Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6212142
feat(world): add zone system with WanderBot and client-side tile inte…
ComBba Feb 11, 2026
02a57bf
feat(shared): update ZoneId type for grid-town layout
ComBba Feb 11, 2026
1f45653
feat: rebuild world map to Grid-Town 64x64 layout with Scalar API docs
ComBba Feb 11, 2026
065c8ea
ci: enhance CI workflows with parallel jobs, E2E, Docker, and security
ComBba Feb 11, 2026
69fc6eb
ci: use self-hosted Mac runner (ARM64) as primary, Linux for Docker
ComBba Feb 11, 2026
7f58046
fix(client): remove unused AssetGalleryScene import
ComBba Feb 11, 2026
4248df1
fix(server): move @scalar/express-api-reference to dependencies
ComBba Feb 11, 2026
90049a1
fix(server): prevent WanderBot random() from returning 1.0
ComBba Feb 11, 2026
8ae5a79
fix: update zone bounds and map dimensions for 64x64 Grid-Town
ComBba Feb 11, 2026
8f49541
test: update test coordinates and assertions for 64x64 layout
ComBba Feb 11, 2026
cce1bc3
ci: remove explicit pnpm version from workflows
ComBba Feb 11, 2026
d228445
ci(codeql): add Node.js setup for TypeScript extraction
ComBba Feb 11, 2026
10fad5a
ci(labeler): run PR size labeler on ubuntu-latest
ComBba Feb 11, 2026
2b9cdd3
chore: update pnpm-lock.yaml for @scalar dependency move
ComBba Feb 11, 2026
71cbb93
ci: exclude Docker and E2E workflows from pull_request trigger
ComBba Feb 11, 2026
13fe167
test: remove obsolete unified map tests
ComBba Feb 11, 2026
164522b
ci: remove Docker and E2E workflows
ComBba Feb 11, 2026
c4aadfa
chore: update .gitignore for work artifacts and generated files
ComBba Feb 11, 2026
9f8fb83
feat(tools): add Python scripts for map generation and asset extraction
ComBba Feb 11, 2026
1601970
feat(assets): add legacy zone map files
ComBba Feb 11, 2026
3db0664
chore: remove test screenshot files
ComBba Feb 11, 2026
91a158f
style: fix formatting in village.json
ComBba Feb 11, 2026
f7bf0d4
fix(ci): ensure build artifacts available for typecheck and test
ComBba Feb 11, 2026
11e0a97
fix(ci): use self-build instead of artifact download for test job
ComBba Feb 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 65 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@

## Features

- **Multiplayer Virtual World** - Real-time 2D top-down game environment
- **Multiplayer Virtual World** - Real-time 2D top-down game environment (Grid-Town 64x64 map)
- **Human & AI Coexistence** - Both human players and AI agents can interact in the same world
- **Zone System** - 6 distinct zones: Plaza, North Block, West Block, East Block, South Block, Lake
- **WebSocket Communication** - Low-latency multiplayer via Colyseus
- **AIC HTTP API** - RESTful API for AI agent integration
- **AIC HTTP API** - RESTful API for AI agent integration with interactive docs
- **Proximity Chat** - Chat bubbles appear above entities
- **Collision System** - Tile-based collision with debug visualization
- **Docker Support** - Production-ready containerization
Expand All @@ -30,10 +31,24 @@
| **Server** | [Colyseus 0.17](https://colyseus.io/) + [Express 5](https://expressjs.com/) |
| **Language** | [TypeScript 5.9](https://www.typescriptlang.org/) |
| **Validation** | [Zod 4](https://zod.dev/) |
| **API Docs** | [Scalar](https://scalar.com/) |
| **Package Manager** | [pnpm](https://pnpm.io/) |
| **Testing** | [Vitest](https://vitest.dev/) |
| **Container** | [Docker](https://www.docker.com/) |

## World Map

The game world uses the **Grid-Town** layout - a 64x64 tile map (2048x2048 pixels):

| Zone | Description | Location |
| --------------- | -------------------------------- | ------------ |
| **Plaza** | Central social hub (16x16 tiles) | Center |
| **North Block** | Office area with work facilities | Top |
| **West Block** | Cafe and lounge area | Left |
| **East Block** | Meeting rooms | Right |
| **South Block** | Arcade and recreation | Bottom |
| **Lake** | Water feature (blocked) | Bottom-right |

## Project Structure

```
Expand All @@ -42,15 +57,16 @@ openClawWorld/
│ ├── client/ # Phaser game client
│ ├── server/ # Colyseus game server
│ │ └── src/
│ │ ├── app.config.ts # Server configuration (defineServer)
│ │ ├── index.ts # Entry point
│ │ ├── app.config.ts # Server configuration
│ │ ├── openapi.ts # OpenAPI 3.1 spec
│ │ ├── aic/ # AIC API handlers
│ │ ├── rooms/ # Game rooms
│ │ └── schemas/ # Colyseus schemas
│ │ └── zone/ # Zone system
│ ├── shared/ # Shared types and schemas
│ └── plugin/ # Optional plugins
│ └── plugin/ # OpenClaw plugin
├── world/ # World data (maps, NPCs, facilities)
├── tests/ # Integration tests
├── Dockerfile # Production Docker image
├── docker-compose.yml # Docker Compose configuration
├── docs/ # Documentation
└── .github/workflows/ # CI configuration
```

Expand Down Expand Up @@ -98,31 +114,48 @@ pnpm lint # Linting

## Server Endpoints

| Endpoint | Description |
| -------------- | -------------------------- |
| `GET /health` | Health check |
| `GET /metrics` | Server metrics (JSON) |
| `GET /monitor` | Colyseus Monitor dashboard |
| `GET /` | Playground (dev only) |
| Endpoint | Description |
| ------------------- | --------------------------------- |
| `GET /health` | Health check |
| `GET /metrics` | Server metrics (JSON) |
| `GET /docs` | **Interactive API Documentation** |
| `GET /openapi.json` | OpenAPI 3.1 specification |
| `GET /monitor` | Colyseus Monitor (dev only) |
| `GET /` | Playground (dev only) |

## AIC API (AI Agent Interface)

AI agents interact with the world via HTTP API at `/aic/v0.1`:
AI agents interact with the world via HTTP API at `/aic/v0.1`.

**Full interactive documentation available at:** `http://localhost:2567/docs`

### Quick Start

```bash
# Register an agent
curl -X POST http://localhost:2567/aic/v0.1/register \
-H "Content-Type: application/json" \
-d '{"name": "MyAgent", "roomId": "default"}'
-d '{"agentId": "my_agent", "roomId": "default", "name": "My Agent"}'

# Use the returned token for subsequent requests
curl -X POST http://localhost:2567/aic/v0.1/observe \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{"agentId": "my_agent", "roomId": "default", "radius": 100, "detail": "full"}'
```

| Endpoint | Description |
| --------------------------- | ---------------------------- |
| `POST /aic/v0.1/register` | Register a new AI agent |
| `POST /aic/v0.1/observe` | Get world state around agent |
| `POST /aic/v0.1/moveTo` | Move agent to destination |
| `POST /aic/v0.1/interact` | Interact with world objects |
| `POST /aic/v0.1/chatSend` | Send chat message |
| `POST /aic/v0.1/pollEvents` | Poll for events |
### Endpoints

| Endpoint | Auth | Description |
| ------------------------------- | ---- | ---------------------------- |
| `POST /aic/v0.1/register` | No | Register a new AI agent |
| `POST /aic/v0.1/observe` | Yes | Get world state around agent |
| `POST /aic/v0.1/moveTo` | Yes | Move agent to destination |
| `POST /aic/v0.1/interact` | Yes | Interact with world objects |
| `POST /aic/v0.1/chatSend` | Yes | Send chat message |
| `POST /aic/v0.1/chatObserve` | Yes | Get recent chat messages |
| `POST /aic/v0.1/pollEvents` | Yes | Poll for world events |
| `POST /aic/v0.1/profile/update` | Yes | Update agent profile |

## Controls

Expand All @@ -133,6 +166,13 @@ curl -X POST http://localhost:2567/aic/v0.1/register \
| **Enter** | Send chat message |
| **F3** | Toggle collision debug |

## Documentation

- [PRD Index](docs/PRD-INDEX.md) - Product Requirements Document
- [Demo Runbook](docs/demo-runbook.md) - Load testing and demo instructions
- [Grid-Town Map Spec](docs/reference/map_spec_grid_town.md) - Current map specification
- [AIC Schema](docs/aic/v0.1/aic-schema.json) - JSON Schema for AIC API

## Contributing

1. Fork the repository
Expand All @@ -149,4 +189,5 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file

- [Phaser](https://phaser.io/) - HTML5 game framework
- [Colyseus](https://colyseus.io/) - Multiplayer game server
- [Scalar](https://scalar.com/) - Beautiful API documentation
- [Zod](https://zod.dev/) - TypeScript-first schema validation
110 changes: 110 additions & 0 deletions docs/reference/map_spec_grid_town.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Grid-Town Map Specification

Based on reference image: `grid_town_layout.png`

## Map Dimensions

| Property | Value |
|----------|-------|
| Reference Image Size | 2048 x 2048 px |
| Tile Size | 32 x 32 px |
| Map Size (tiles) | 64 x 64 |
| Actual Map Size (px) | 2048 x 2048 |

## Zone Boundaries (Tile Coordinates)

| Zone | Tile X Start | Tile Y Start | Width (tiles) | Height (tiles) | Pixel Bounds |
|------|--------------|--------------|---------------|----------------|--------------|
| Z_PLAZA | 24 | 24 | 16 | 16 | (768, 768) to (1280, 1280) |
| Z_NORTH_BLOCK | 18 | 4 | 28 | 16 | (576, 128) to (1472, 640) |
| Z_WEST_BLOCK | 4 | 18 | 16 | 28 | (128, 576) to (640, 1472) |
| Z_EAST_BLOCK | 44 | 18 | 16 | 20 | (1408, 576) to (1920, 1216) |
| Z_SOUTH_BLOCK | 12 | 44 | 28 | 16 | (384, 1408) to (1280, 1920) |
| Z_LAKE | 44 | 44 | 18 | 18 | (1408, 1408) to (1984, 1984) |

## Layout Description

- **Central Plaza**: Large 16x16 tile gray square in center - main social hub
- **Roads**: Vertical road through center (x=32), horizontal road (y=32) creating cross pattern
- **North Block**: 3 buildings at top - office area
- **West Block**: 3 buildings on left - cafe/lounge area
- **East Block**: 2 buildings on right - meeting rooms
- **South Block**: 3 buildings at bottom - arcade/recreation
- **Lake**: Blue water area in bottom-right corner

## Collision Rules

| Tile Type | Collision | Notes |
|-----------|-----------|-------|
| Grass (green) | No | Walkable |
| Roads (light gray) | No | Walkable |
| Plaza (light gray) | No | Walkable |
| Building Walls (dark gray) | Yes | Not walkable |
| Building Interior (brown) | Yes | Not walkable (MVP - no door openings) |
| Water/Lake (blue) | Yes | Not walkable |

## Interactive Objects (Facility Positions)

### Z_PLAZA
| Object | Type | Tile Position | Pixel Position | Interaction Radius |
|--------|------|---------------|----------------|-------------------|
| plaza.notice_board | notice_board | (32, 28) | (1024, 896) | 48 |
| plaza.signpost | onboarding_signpost | (30, 32) | (960, 1024) | 32 |

### Z_NORTH_BLOCK
| Object | Type | Tile Position | Pixel Position | Interaction Radius |
|--------|------|---------------|----------------|-------------------|
| north.office_terminal | kanban_terminal | (32, 8) | (1024, 256) | 32 |
| north.whiteboard | whiteboard | (28, 8) | (896, 256) | 32 |

### Z_EAST_BLOCK
| Object | Type | Tile Position | Pixel Position | Interaction Radius |
|--------|------|---------------|----------------|-------------------|
| east.meeting_kiosk | schedule_kiosk | (48, 24) | (1536, 768) | 32 |
| east.room_door_A | room_door_a | (50, 26) | (1600, 832) | 32 |

### Z_WEST_BLOCK
| Object | Type | Tile Position | Pixel Position | Interaction Radius |
|--------|------|---------------|----------------|-------------------|
| west.cafe_counter | cafe_counter | (8, 32) | (256, 1024) | 48 |
| west.vending_machine | vending_machine | (12, 28) | (384, 896) | 32 |

### Z_SOUTH_BLOCK
| Object | Type | Tile Position | Pixel Position | Interaction Radius |
|--------|------|---------------|----------------|-------------------|
| south.arcade_cabinet | game_table | (20, 48) | (640, 1536) | 48 |

### Z_LAKE
| Object | Type | Tile Position | Pixel Position | Interaction Radius |
|--------|------|---------------|----------------|-------------------|
| lake.viewpoint | pond_edge | (42, 42) | (1344, 1344) | 32 |

## NPC Spawn Positions

| NPC ID | Zone | Spawn Tile | Pixel Position | Default State |
|--------|------|------------|----------------|---------------|
| greeter | plaza | (32, 32) | (1024, 1024) | idle |
| office-pm | north-block | (32, 10) | (1024, 320) | working |
| meeting-host | east-block | (51, 25) | (1632, 800) | working |
| barista | west-block | (10, 32) | (320, 1024) | working |
| arcade-host | south-block | (20, 51) | (640, 1632) | idle |
| ranger | lake | (44, 44) | (1408, 1408) | idle |

## Spawn Points

| Zone | Primary Spawn Tile | Primary Spawn Pixel |
|------|-------------------|---------------------|
| plaza | (32, 32) | (1024, 1024) |
| north-block | (32, 10) | (1024, 320) |
| west-block | (10, 32) | (320, 1024) |
| east-block | (51, 25) | (1632, 800) |
| south-block | (20, 51) | (640, 1632) |
| lake | (44, 44) | (1408, 1408) |

## Layers

Required layers for map JSON:

1. **ground** - Base terrain (grass tiles, ID 1)
2. **collision** - Collision grid (0=passable, 1=blocked)
3. **objects** - Spawn points, facility markers
Binary file modified docs/reference/village_world_reference.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"clean": "pnpm -r clean && rm -rf node_modules",
"dev:server": "pnpm --filter @openclawworld/server dev",
"dev:client": "pnpm --filter @openclawworld/client dev",
"load-test": "tsx scripts/load-test.ts"
"load-test": "tsx scripts/load-test.ts",
"extract:assets": "python tools/extract_assets/extract.py --all"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
Expand Down
Loading
Loading