From 90e35a5750c17dad69213c7a95b674f5f1a4de9f Mon Sep 17 00:00:00 2001 From: ud18010 Date: Mon, 27 Jul 2026 11:35:19 +0800 Subject: [PATCH] docs: define unified character catalog --- ...-07-27-unified-character-catalog-design.md | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-27-unified-character-catalog-design.md diff --git a/docs/superpowers/specs/2026-07-27-unified-character-catalog-design.md b/docs/superpowers/specs/2026-07-27-unified-character-catalog-design.md new file mode 100644 index 00000000..7755be19 --- /dev/null +++ b/docs/superpowers/specs/2026-07-27-unified-character-catalog-design.md @@ -0,0 +1,59 @@ +# Unified Character Catalog Design + +## Goal + +Make `Assets/Resources/Config/CharacterConfig.json` the only source of truth for +the selectable lobby characters. Refreshing the configuration from the Unity +editor must make the corresponding character selectable and loadable in the +lobby without a matching code edit. + +## Current issue + +`CharacterSwitchController` builds its selection UI from `CharacterConfig.json` +and stores the selected character ID in `PlayerPrefs`. `LobbyWorldController` +instead maps that ID through its own hard-coded `ActorPaths` array. A generated +entry such as `cityboy_sk` is not in that array, so the mapping falls back to +figure `1` and displays `Assasin`. + +## Design + +`LobbyWorldController` will load the same resource configuration used by the +selection UI. It will use the ordered `characters` list for both directions of +the existing network mapping: + +- selected character ID -> one-based `Figure` index sent to the server; +- received one-based `Figure` index -> the configured prefab path to load. + +The order generated by `CharacterConfigGenerator` remains alphabetical and is +therefore deterministic across clients built with the same content. The +network protocol remains unchanged: it still carries a one-based integer. + +The hard-coded actor-path array will be removed. Config loading validates that +the list exists and contains usable entries. If configuration cannot be read, +or a selected ID is absent, the lobby will log a specific error and use the +configured default character (or the first valid entry) rather than silently +mapping the unknown ID to `Assasin`. + +## Components + +- `CharacterConfigData` retains lookup of character items by ID and default + selection. +- `LobbyWorldController` owns a loaded `CharacterConfigData` instance and uses + it to resolve figure indices and prefab paths. +- `CharacterSwitchController` continues to populate the UI from the same JSON + asset and to persist the selected ID. + +No prefab or network-server change is required. + +## Error handling + +On missing, invalid, or empty configuration, the lobby does not index into a +path array. It logs an actionable configuration error and avoids attempting to +load an arbitrary model. Invalid remote figure indices are handled as invalid +configuration data and fall back to the catalog's default item. + +## Tests + +Add focused tests for catalog-to-figure and figure-to-prefab resolution, +including the generated `cityboy_sk` entry, unknown IDs, and invalid indices. +Keep existing valid figure ordering compatible with the network protocol.