From 4f04e735daa6609dbd9de00ece03a89ab1aded0b Mon Sep 17 00:00:00 2001 From: Jage9 Date: Sat, 21 Feb 2026 18:57:02 -0500 Subject: [PATCH] Add plain-language item type template documentation --- docs/item-schema.md | 1 + docs/item-type-template.md | 118 +++++++++++++++++++++++++++++++++++++ docs/item-types.md | 2 + 3 files changed, 121 insertions(+) create mode 100644 docs/item-type-template.md diff --git a/docs/item-schema.md b/docs/item-schema.md index 61e6c13..ad7aeb2 100644 --- a/docs/item-schema.md +++ b/docs/item-schema.md @@ -48,6 +48,7 @@ - Global/type-level properties are loaded from server registry in `server/app/item_catalog.py`. - Per-type use/update validation and message behavior are handled in `server/app/item_type_handlers.py`. - Client-side add/edit metadata is handled in `client/src/items/itemRegistry.ts`. +- End-to-end add-item template: `docs/item-type-template.md`. ## Type Params diff --git a/docs/item-type-template.md b/docs/item-type-template.md new file mode 100644 index 0000000..cc68f85 --- /dev/null +++ b/docs/item-type-template.md @@ -0,0 +1,118 @@ +# Item Type Template + +This page is a practical, copy/paste template for adding a new item type with the current registry-based system. + +Use this when you want a new item type without editing one huge `if/elif` chain. + +## Plain-English Flow + +When a new item type is added, you wire it in four places: + +1. Server catalog (`item_catalog.py`) +- Defines global defaults shared by all instances of that type: + - default title + - default params + - use sound / emit sound + - cooldown + +2. Server behavior (`item_type_handlers.py`) +- Defines what happens when users edit params (`validate_update`). +- Defines what happens when users press `use` (`use`). + +3. Shared type unions (`models.py`, protocol/state types) +- Adds the new type name to type literals/unions so packets validate. + +4. Client item registry (`itemRegistry.ts`) +- Defines add-menu order, editable properties, and optional property dropdown choices. + +That is enough for a first working item type. + +## Example: `counter` + +This sample item increments a number each time it is used. + +### 1. Server Catalog (`server/app/item_catalog.py`) + +```py +ItemType = Literal["radio_station", "dice", "wheel", "clock", "counter"] + +ITEM_DEFINITIONS: dict[ItemType, ItemDefinition] = { + # ...existing... + "counter": ItemDefinition( + default_title="counter", + capabilities=("editable", "carryable", "deletable", "usable"), + use_sound=None, + emit_sound=None, + default_params={"value": 0}, + use_cooldown_ms=1000, + ), +} +``` + +### 2. Server Handler (`server/app/item_type_handlers.py`) + +```py +def _validate_counter_update(_item: WorldItem, next_params: dict) -> dict: + try: + value = int(next_params.get("value", 0)) + except (TypeError, ValueError) as exc: + raise ValueError("value must be a number.") from exc + if value < 0: + raise ValueError("value must be 0 or greater.") + next_params["value"] = value + return next_params + + +def _use_counter(item: WorldItem, nickname: str, _clock_formatter: Callable[[dict], str]) -> ItemUseResult: + current = int(item.params.get("value", 0)) + next_value = current + 1 + return ItemUseResult( + self_message=f"{item.title}: {next_value}", + others_message=f"{nickname} uses {item.title}: {next_value}", + updated_params={**item.params, "value": next_value}, + ) + + +ITEM_TYPE_HANDLERS: dict[ItemType, ItemTypeHandler] = { + # ...existing... + "counter": ItemTypeHandler( + validate_update=_validate_counter_update, + use=_use_counter, + ), +} +``` + +### 3. Type Unions + +Update item-type unions/literals in: + +- `server/app/models.py` +- `client/src/network/protocol.ts` +- `client/src/state/gameState.ts` + +Add `"counter"` anywhere item types are enumerated. + +### 4. Client Registry (`client/src/items/itemRegistry.ts`) + +```ts +export const ITEM_TYPE_SEQUENCE: ItemType[] = ['clock', 'counter', 'dice', 'radio_station', 'wheel']; + +const ITEM_TYPE_EDITABLE_PROPERTIES: Record = { + // ...existing... + counter: ['title', 'value'], +}; + +export const ITEM_TYPE_GLOBAL_PROPERTIES: Record> = { + // ...existing... + counter: { useSound: 'none', emitSound: 'none', useCooldownMs: 1000 }, +}; +``` + +No dropdown options are needed here because `value` is a numeric text field. + +## Checklist Before Commit + +1. Add/adjust server tests for `use` and `update` validation. +2. Run `cd server && uv run --extra dev pytest`. +3. Run `cd client && npm run lint && npm run build`. +4. Update `docs/item-types.md` and `docs/item-schema.md` if behavior/defaults changed. diff --git a/docs/item-types.md b/docs/item-types.md index cfa5956..015d207 100644 --- a/docs/item-types.md +++ b/docs/item-types.md @@ -100,6 +100,8 @@ This is behavior-focused documentation for item types and their defaults. Item types are currently code-registered on both server and client so new types are additive instead of editing one large branch. +For a full copy/paste example with plain-English explanation, see `docs/item-type-template.md`. + 1. Server catalog: add global defaults in `server/app/item_catalog.py` (`ITEM_DEFINITIONS`). 2. Server handlers: add `validate_update` + `use` logic in `server/app/item_type_handlers.py` and register it in `ITEM_TYPE_HANDLERS`. 3. Server models: extend `ItemType` literals in `server/app/models.py` and any packet enums that list item types.