# Game World Widget

The **Game World** widget renders an interactive, navigable 2D tile-based game world directly inside a Business Platform page. It is suited for onboarding experiences, interactive floor plans, warehouse overviews, and similar spatial use cases.

The widget uses [Phaser](https://phaser.io/) for rendering and physics, loaded dynamically in the browser. Map data is authored in the backoffice and stored as `GameMap` documents, which the widget loads at runtime.

---

## Prerequisites

- A `GameMap` document must exist before placing the widget. Create one via the backoffice admin area (see [Creating a Game Map](#creating-a-game-map)).
- Phaser is loaded lazily; no additional installation steps are required for widget consumers.

---

## Creating a Game Map

Game maps are created and edited in the backoffice admin area.

### Opening the Map Manager

1. Navigate to **Admin → Game Maps** in the backoffice sidebar.
2. The page lists all existing maps with their names and dimensions.

### Creating a New Map

1. Click **Create Map**.
2. Fill in the dialog fields:

   | Field | Description | Default |
   |---|---|---|
   | **Name** | Display name for the map | *(required)* |
   | **Width** | Map width in tiles | `30` |
   | **Height** | Map height in tiles | `20` |
   | **Tile Size** | Width and height of each tile in pixels | `32` |

3. Click **Create**. The editor opens automatically for the new map.

### Map Editor

The editor provides a full-screen canvas-based interface with the following panels and tools.

#### Toolbar Tools

| Tool | Description |
|---|---|
| **Brush** | Paint the selected tile onto the active layer |
| **Fill** | Flood-fill a contiguous area with the selected tile |
| **Eraser** | Remove tiles from the active layer |
| **Object** | Place an interactive object (NPC, item, decoration, sign) |
| **Trigger** | Draw a trigger zone (teleport, dialogue, info, action) |
| **Spawn** | Set the player spawn point |
| **Select** | Select and inspect objects or triggers |

#### Layers Panel

Layers are rendered in depth order. Each layer has:

- **Visibility** toggle — show or hide the layer on the canvas.
- **Collision** toggle — when enabled, the layer acts as a collision surface for the player.
- **Move up / Move down** buttons — reorder layers.
- **Remove** button — delete the layer (at least one layer must remain).

To add a new layer, type a name into the input at the bottom of the panel and press **Enter** or click **+**.

#### Tileset Manager

Tilesets provide the tile graphics painted onto layers. Three built-in tilesets are available:

| Tileset | Tile Size | Tiles |
|---|---|---|
| `basic-office` | 32 × 32 | 64 |
| `basic-outdoor` | 32 × 32 | 64 |
| `basic-warehouse` | 32 × 32 | 64 |

Click **Add Tileset** in the panel to expand the built-in tileset list and add one to the current map. Each tileset can only be added once per map. Remove a tileset by clicking the **×** next to its name.

#### Tile Palette

After adding a tileset, the **Tile Palette** panel shows the tileset image with a grid overlay. Click any tile to select it as the active brush. The selected tile is highlighted in green.

If the map contains multiple tilesets, use the dropdown at the top of the palette to switch between them.

#### Objects Panel

Objects are interactive entities placed on the map. Supported types:

| Type | Icon | Description |
|---|---|---|
| `npc` | person | Non-player character |
| `item` | box | Collectible or usable item |
| `decoration` | tree | Non-interactive decoration |
| `sign` | sign | Readable sign |

Select the desired type in the Objects panel, then choose the **Object** tool from the toolbar and click on the canvas to place it. Select an existing object in the list or via the **Select** tool to view and edit its properties in the Properties panel.

#### Triggers Panel

Triggers are rectangular zones that fire events when the player enters them. Supported types:

| Type | Description |
|---|---|
| `teleport` | Move the player to another location or map |
| `dialogue` | Start a dialogue sequence |
| `info` | Display an informational message |
| `action` | Fire a custom action |

Click **Draw Trigger** to activate the trigger tool, then drag a rectangle on the canvas to define the zone. Select a trigger from the list to edit its properties.

#### Properties Panel

The Properties panel shows editable fields for the currently selected object or trigger, including name, type, position, and interaction text (with English locale support).

#### Saving

Click **Save** in the top toolbar. The map is saved via a `PATCH` request to `/api/game-maps/:mapId`. Unsaved changes are indicated by a dirty state marker in the toolbar.

### Deleting a Map

From the **Game Maps** list page, click the delete button next to a map. A confirmation dialog shows the map name before deletion.

---

## Widget Configuration

Once a map exists, add the **Game World** widget to any page and configure it with the following properties.

| Property | Type | Required | Default | Description |
|---|---|---|---|---|
| `mapId` | `string` | ✅ | — | The `_id` of the `GameMap` document to load |
| `width` | `number` | | `800` | Canvas width in pixels |
| `height` | `number` | | `600` | Canvas height in pixels |
| `enableSound` | `boolean` | | `true` | Enable ambient audio and sound effects |
| `showMinimap` | `boolean` | | `false` | Show a minimap overlay |
| `playerSprite` | `string` | | — | URL of a custom player sprite sheet, overriding the default |
| `movementType` | `"free"` \| `"grid"` | | `"free"` | Player movement style — smooth free movement or tile-snapped grid movement |

### Minimal Example

```json
{
  "mapId": "6627f4e2a1b2c3d4e5f60001"
}
```

### Full Example

```json
{
  "mapId": "6627f4e2a1b2c3d4e5f60001",
  "width": 1024,
  "height": 768,
  "enableSound": false,
  "showMinimap": true,
  "playerSprite": "https://cdn.example.com/sprites/custom-player.png",
  "movementType": "grid"
}
```

---

## Runtime Behaviour

- The widget loads Phaser lazily; it is not included in the server-side render bundle.
- While map data is loading, a spinner is shown in place of the canvas.
- The game canvas is focusable. When not focused, an overlay prompts the user to **Click to play**. Keyboard input is disabled while the widget is out of focus, preventing conflicts with page-level shortcuts.
- If Phaser fails to load or the map cannot be found, an error message is shown inside the widget boundary.

---

## Interactive Objects at Runtime

Objects placed on a map respond to player proximity:

- When the player moves within **48 pixels** of an object, a prompt key indicator appears above it.
- Interacting with the object (pressing the interaction key) triggers the configured behaviour (dialogue, item pickup, etc.).
- Collection-bound objects can display live data labels sourced from a linked collection document.

---

## API Endpoints

The backoffice editor and the widget communicate with the following endpoints:

| Method | Path | Description |
|---|---|---|
| `GET` | `/api/game-maps` | List all maps |
| `POST` | `/api/game-maps` | Create a new map |
| `GET` | `/api/game-maps/:id` | Load a single map |
| `PATCH` | `/api/game-maps/:id` | Save map changes |
| `DELETE` | `/api/game-maps/:id` | Delete a map |
