2026-02-20 08:16:43 -05:00
|
|
|
# Item Schema
|
|
|
|
|
|
|
|
|
|
## World Item (server-authoritative)
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"id": "string",
|
2026-02-21 16:01:40 -05:00
|
|
|
"type": "radio_station | dice | wheel | clock",
|
2026-02-20 08:16:43 -05:00
|
|
|
"title": "string",
|
|
|
|
|
"x": 0,
|
|
|
|
|
"y": 0,
|
|
|
|
|
"createdBy": "user-id",
|
|
|
|
|
"createdAt": 1735689600000,
|
|
|
|
|
"updatedAt": 1735689600000,
|
|
|
|
|
"version": 1,
|
|
|
|
|
"capabilities": ["editable", "carryable", "deletable", "usable"],
|
2026-02-21 16:13:48 -05:00
|
|
|
"useSound": "sounds/roll.ogg",
|
|
|
|
|
"emitSound": "sounds/clock.ogg",
|
2026-02-20 08:16:43 -05:00
|
|
|
"params": {},
|
|
|
|
|
"carrierId": null
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2026-02-21 16:13:48 -05:00
|
|
|
- `useSound`: optional client-played one-shot sound when item `use` succeeds; global item field and not user-editable in V1.
|
|
|
|
|
- `emitSound`: optional continuously-looping spatial sound emitted from the item on the grid; global item field and not user-editable in V1.
|
|
|
|
|
- `capabilities`, `useSound`, and `emitSound` are derived from global item-type definitions at runtime (not stored per-instance in persisted state).
|
2026-02-21 16:01:40 -05:00
|
|
|
- `useCooldownMs`: global per item type (`radio_station=1000`, `dice=1000`, `wheel=4000`, `clock=1000`), not per-instance editable.
|
2026-02-20 08:16:43 -05:00
|
|
|
|
|
|
|
|
## Persisted Item State (`server/runtime/items.json`)
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"id": "string",
|
2026-02-21 16:01:40 -05:00
|
|
|
"type": "radio_station | dice | wheel | clock",
|
2026-02-20 08:16:43 -05:00
|
|
|
"title": "string",
|
|
|
|
|
"x": 0,
|
|
|
|
|
"y": 0,
|
|
|
|
|
"createdBy": "user-id",
|
|
|
|
|
"createdAt": 1735689600000,
|
|
|
|
|
"updatedAt": 1735689600000,
|
|
|
|
|
"version": 1,
|
|
|
|
|
"params": {},
|
|
|
|
|
"carrierId": null
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- Persisted state stores only instance data.
|
|
|
|
|
- Global/type-level properties are loaded from server registry in `server/app/item_catalog.py`.
|
|
|
|
|
|
|
|
|
|
## Type Params
|
|
|
|
|
|
|
|
|
|
### `radio_station`
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"streamUrl": "",
|
|
|
|
|
"enabled": true,
|
2026-02-21 03:43:27 -05:00
|
|
|
"channel": "stereo",
|
|
|
|
|
"volume": 50,
|
|
|
|
|
"effect": "off",
|
|
|
|
|
"effectValue": 50
|
2026-02-20 08:16:43 -05:00
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- `streamUrl`: string, empty allowed until configured.
|
|
|
|
|
- `enabled`: boolean on/off flag.
|
|
|
|
|
- UI behavior: in property menu, `Enter` toggles on/off directly.
|
|
|
|
|
- `volume`: integer, range `0-100`, default `50`.
|
2026-02-21 03:43:27 -05:00
|
|
|
- `channel`: one of `stereo | mono | left | right`, default `stereo`.
|
|
|
|
|
- `effect`: one of `reverb | echo | flanger | high_pass | low_pass | off`, default `off`.
|
|
|
|
|
- `effectValue`: number, range `0-100`, precision `0.1`.
|
2026-02-20 08:16:43 -05:00
|
|
|
|
|
|
|
|
### `dice`
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"sides": 6,
|
|
|
|
|
"number": 2
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- `sides`: integer, range `1-100`.
|
|
|
|
|
- `number`: integer, range `1-100`.
|
|
|
|
|
|
2026-02-21 03:43:27 -05:00
|
|
|
### `wheel`
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"spaces": "yes, no"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- `spaces`: comma-delimited string of values.
|
|
|
|
|
- Server validation:
|
|
|
|
|
- must include at least 1 value
|
|
|
|
|
- max 100 values
|
|
|
|
|
- each value max 80 chars
|
|
|
|
|
|
2026-02-21 16:01:40 -05:00
|
|
|
### `clock`
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"timeZone": "America/Detroit",
|
|
|
|
|
"use24Hour": false
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2026-02-21 16:04:55 -05:00
|
|
|
- `timeZone`: one representative IANA zone per world UTC offset. Includes:
|
|
|
|
|
`America/Anchorage`, `America/Argentina/Buenos_Aires`, `America/Chicago`, `America/Detroit`,
|
|
|
|
|
`America/Halifax`, `America/Indiana/Indianapolis`, `America/Kentucky/Louisville`,
|
|
|
|
|
`America/Los_Angeles`, `America/St_Johns`, `Asia/Bangkok`, `Asia/Dhaka`, `Asia/Dubai`,
|
|
|
|
|
`Asia/Hong_Kong`, `Asia/Kabul`, `Asia/Karachi`, `Asia/Kathmandu`, `Asia/Kolkata`,
|
|
|
|
|
`Asia/Seoul`, `Asia/Singapore`, `Asia/Tehran`, `Asia/Tokyo`, `Asia/Yangon`,
|
|
|
|
|
`Atlantic/Azores`, `Atlantic/South_Georgia`, `Australia/Brisbane`, `Australia/Darwin`,
|
|
|
|
|
`Australia/Eucla`, `Australia/Lord_Howe`, `Europe/Berlin`, `Europe/Helsinki`,
|
|
|
|
|
`Europe/London`, `Europe/Moscow`, `Pacific/Apia`, `Pacific/Auckland`, `Pacific/Chatham`,
|
|
|
|
|
`Pacific/Honolulu`, `Pacific/Kiritimati`, `Pacific/Noumea`, `Pacific/Pago_Pago`, `UTC`.
|
2026-02-21 16:01:40 -05:00
|
|
|
- `use24Hour`: boolean (or `on/off` in updates), default `false`.
|
2026-02-21 16:13:48 -05:00
|
|
|
- Global defaults: `useSound=none`, `emitSound=sounds/clock.ogg`.
|
2026-02-21 16:01:40 -05:00
|
|
|
|
2026-02-20 08:16:43 -05:00
|
|
|
## Packet Shapes
|
|
|
|
|
|
|
|
|
|
- `item_upsert`:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"type": "item_upsert",
|
|
|
|
|
"item": { "..." : "World Item" }
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- `item_remove`:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"type": "item_remove",
|
|
|
|
|
"itemId": "item-id"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- `item_action_result`:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"type": "item_action_result",
|
|
|
|
|
"ok": true,
|
|
|
|
|
"action": "add | pickup | drop | delete | use | update",
|
|
|
|
|
"message": "human-readable status",
|
|
|
|
|
"itemId": "optional-item-id"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- `item_use_sound`:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"type": "item_use_sound",
|
|
|
|
|
"itemId": "item-id",
|
|
|
|
|
"sound": "sounds/roll.ogg",
|
|
|
|
|
"x": 12,
|
|
|
|
|
"y": 8
|
|
|
|
|
}
|
|
|
|
|
```
|