name: character-data description: "Use this skill when working with character data models, the two-enum system, JSON game data files, equipment management, or world/economy systems. Covers Character.gd, BaseCharacterResource, GlobalEnums, GameEnums, EquipmentManager, DataManager, GameDataManager, PlanetDataManager, WorldEconomyManager, and all 132 JSON files in data/."
๐ RULE 0 (CLAUDE.md "Agent Verification Protocol" โ MANDATORY, NON-NEGOTIABLE): READ THE ACTUAL CODE AND SCENES BEFORE ANY PLAN. You may NOT propose a plan, design, edit, routing decision, or structural claim until you have opened and read the ACTUAL files involved โ the
.gdscripts AND the related.tscn/.tresscene/resource files. Memory, CLAUDE.md docblocks, SOPs, this file's own notes, and relayed sub-agent summaries are LEADS TO VERIFY, never facts โ they go stale; open the file and confirm, citingfile:line. The.tscnwiring (node tree, node types,[ext_resource]scripts, embedded/instanced sub-scenes,unique_name_in_owner, anchors/containers) is the authority on what is actually instantiated and live โ a.gdcan look dead but be wired into a scene, or look live but be orphaned. UI / layout / responsive work: reading the.gdis NOT enough, OPEN the.tscn. If you name a node/signal/property you have not seen in the real source, you have not done the work. No first-hand read of the code + scene wiring = no plan. Full code-and-scene due diligence is the floor, not extra effort.
Character & Data Systems
Reference Files
| Reference | Contents |
|---|---|
references/character-model.md |
Character.gd full API (~1,900 lines), BaseCharacterResource, flat stats, dual-key aliases, implant system, serialization format |
references/enum-systems.md |
Two-enum alignment table (GlobalEnums vs GameEnums), sync protocol, diff-check |
references/json-data-catalog.md |
All 132 JSON files: path, schema summary, consumer system, validation rules |
references/equipment-world.md |
EquipmentManager API, equipment_data key, sell value logic, PlanetDataManager, PlanetCache, WorldEconomyManager |
Quick Decision Tree
- Modifying character stats/properties โ Read
character-model.md - Adding/changing enum values โ Read
enum-systems.md(MUST sync both files: GlobalEnums + GameEnums) - Working with JSON data files โ Read
json-data-catalog.md - Equipment/world/economy changes โ Read
equipment-world.md - Character serialization bugs โ Read
character-model.md(to_dictionary/from_dictionary section) - Adding new data tables โ Read
json-data-catalog.md+equipment-world.mdfor loading pattern - PlanetDataManager cross-mode contamination โ Every campaign core's
apply_pending_qol_data()MUST callpdm.deserialize_all({})unconditionally so 5PFH state can't bleed into Bug Hunt / Planetfall / Tactics. The autoload'svisited_planets.clear()only executes insidedeserialize_all(). Empty dict cleanly clears via theclear()at top of the function. See CLAUDE.md gotchas (Jun 2026 Galaxy Log audit B3/B4) - Starting world seeding โ
CampaignFinalizationService.finalize_campaign()registers the starting world with PlanetDataManager viapdm.get_or_generate_planet()so it joinsvisited_planetswithdiscovered_on_turn=0. Without this,travel_historyis empty on Turn 0 and downstream consumers (Galaxy Log anchor logic, future world-history features) would crash or miss the home world (Jun 2026 Galaxy Log audit B2) - Journal
locationwrite contract โ All journal writers (TravelPhase, PostBattleCompletion, CampaignJournal.auto_create_milestone_entry) MUST setlocation = current_planet.namesoget_entries_by_location()can join entries to a planet. Resolve viapdm.get_current_planet().nameโ do NOT read frombattle_result.location(it's never populated). See CLAUDE.md gotchas (Jun 2026 Galaxy Log audit B1)
Key Source Files
| File | Class/Role | Purpose |
|---|---|---|
src/core/character/Character.gd |
Character |
Canonical character model (~1,900 lines) |
src/core/character/SpeciesDataService.gd |
SpeciesDataService |
Static species lookup from character_species.json (16 Strange Characters + primary + compendium) |
src/core/character/CharacterTransferService.gd |
CharacterTransferService |
Cross-mode character transfer โ canonical hub (5PFH-standard Character dict is the interchange form). export_to_canonical / import_from_canonical / transfer_character compose any-to-any routes through 5PFH. Lossless snapshot embed; reward-suppression unless target_mode == "five_parsecs". File-drop via user://transfers/<id>.json. See gamemode skills' cross-mode-safety.md for full route matrix |
src/core/character/Base/Character.gd |
BaseCharacterResource |
Base Resource with flat stats |
src/core/systems/GlobalEnums.gd |
Autoload GlobalEnums |
Primary enum definitions (70+) |
src/core/enums/GameEnums.gd |
GameEnums |
Secondary enum definitions (80+); CharacterClass/CharacterStatus/ShipType/CampaignType (FiveParsecsGameEnums.gd deleted Sprint A Bug 3, 2026-05-24) |
src/core/equipment/EquipmentManager.gd |
Autoload | Equipment operations, pricing |
src/core/data/DataManager.gd |
Autoload | Data persistence, JSON loading |
src/core/managers/GameDataManager.gd |
Autoload | Game data loading (injuries, enemies, gear, etc.) |
src/core/world/PlanetDataManager.gd |
Autoload | Planet persistence, world events |
src/core/world/WorldEconomyManager.gd |
Autoload | Credits, transactions, price adjustments |
Rules Data Authority
All game data values MUST be verified against data/RulesReference/ files (extracted from Core Rules and Compendium PDFs). Key RulesReference files for this skill: SpeciesList.json, EquipmentItems.json, Bestiary.json, Campaign.json, DifficultyOptions.json.
NEVER invent stats, costs, ranges, or probabilities. If data isn't in RulesReference, ask the user to provide it from the book. See docs/QA_RULES_ACCURACY_AUDIT.md for the full verification checklist.
Critical Gotchas
- Stats are FLAT โ
combat,reactions,toughness,speed,savvy,luck,techare direct properties. NOstatssub-object - Both enum files must stay in sync โ GlobalEnums, GameEnums (FiveParsecsGameEnums.gd deleted Sprint A Bug 3, 2026-05-24)
- Dual-key aliases โ
to_dictionary()returns both"id"/"character_id"and"name"/"character_name" - Equipment key is
"equipment"โ NOT"pool"(Phase 22 fix) class_name+ autoload conflict โ Godot 4.6 errors if a script has both- Use
load()notpreload()in autoloaded scripts (autoloads parse before import system) - FiveParsecsCampaignCore is Resource โ
campaign["key"] = valsilently fails; useprogress_data["key"]