Def System Refactor Playbook (v1)¶
Relationship To Docs/backend/inventory-selection.md¶
This document is the Def-focused companion to Docs/backend/inventory-selection.md.
backend/inventory-selection.mdis still the source of truth for inventory/selection transport behavior and Nakama RPC contracts.- This file is the source of truth for Def data model dependencies, tooling, and refactor impact.
Use both docs together when changing Def schemas or import/runtime behavior.
Scope¶
Covers all Def pipeline parts currently in project:
- Runtime Def assets:
UTankItemDefUTankCharacterDef- Def import tooling:
Source/Tools/TankInventoryToolsTankItemDefCsvImportTankCharacterDefCsvImport- Authoring inputs:
Source/Tools/TankInventoryTools/TankItemDefs.xlsxSource/Tools/TankInventoryTools/TankCharacterDefs.xlsx- External JSON helper tool:
Tools/NakamaInventoryWorkbench- GameFeature content packaging:
- currently
Plugins/GameFeatures/TankInventory_Base - designed to scale to more
TankInventory*plugins
Def Contracts (Current)¶
UTankItemDef (Source/Metal_terra/Public/Data/TankItemDef.h)¶
Core identity:
ItemId(stable gameplay/backend id)CategoryId(ownership bucket)CatalogIndex(index inside category)RequiredFeatureId(optional feature pack marker)
Presentation:
DisplayNameIconStaticMeshSkeletalMesh
Editor constraint:
CatalogIndexis clamped to>= 0inPostEditChangeProperty.
UTankCharacterDef (Source/Metal_terra/Public/Data/TankCharacterDef.h)¶
Core identity:
CharacterId(stable gameplay/backend id)CategoryIdClassId(import headerclass)CatalogIndexRequiredFeatureId
Gameplay/presentation/progression:
- class refs:
CharacterBP,AnimBP - montage refs:
HitReactionMontage,DeathMontage - gameplay effects:
PrimaryAttributes,SecondaryAttributes,VitalAttributes StartupAbilitiesDisplayName,Description,Icon,SkeletalMeshStartingLevel,UnlockedSkillIds,StatDistribution
Editor constraints:
CatalogIndex >= 0StartingLevel >= 1- movement/lives/stats/ability numeric values clamped non-negative
End-To-End Data Flow¶
- Designers edit XLSX (
Source/Tools/TankInventoryTools/*.xlsx). - Import scripts run commandlets (
Run-TankItemImport.ps1,Run-TankCharacterImport.ps1). - Commandlets create/update/prune Def assets under selected content root:
- Items forced under
<OutputPath>/Item/... - Characters forced under
<OutputPath>/Character/... - Def assets are packaged via GameFeature plugin content (currently
TankInventory_Base). - Runtime systems consume Def fields:
- ownership index (
UTankInventorySubsystem) - selection payload build (
UOnlineSelectionPayloadLibrary) - selection authority/broadcast (
UOnlineManagerSubsystem,FOnlineSelectionTransportService) - character spawn/ability/attribute runtime (
ATankPlayerState,ATankGameMode,ATankCharacterBase,UTankAbilitySystemBPLibrary) - Nakama RPC payloads use Def-derived
category/indexvalues. NakamaInventoryWorkbenchuses workbook catalogs + bitset encoding for offline owned-snapshot generation and inspection.
Dependency Graph (What Breaks If Defs Change)¶
ItemDef dependencies¶
Def identity field usage (CategoryId, CatalogIndex, ItemId):
UTankInventorySubsystemRebuildItemDefIndex()indexesTankItemDefassets by(CategoryId, CatalogIndex).TryResolveItemDefAssetId()resolves from(CategoryId, CatalogIndex).TryExtractAddressFromAssetData()reads asset registry tags forCategoryIdandCatalogIndex.UOnlineSelectionPayloadLibrary- reads
ItemDef.CategoryIdandItemDef.CatalogIndexwhen buildingequipped.selected[]. TankItemDefCsvImportCommandlet- writes all item identity/presentation fields.
CharacterDef dependencies¶
Def identity field usage (CharacterId, CategoryId, CatalogIndex):
UOnlineSelectionPayloadLibrary- reads
CharacterDef.CategoryId+CharacterDef.CatalogIndex. ATankPlayerState- resolves selected character from
equipped.selected[]by catalog index. - loads
TankCharacterDefprimary assets and applies to replicated state. UTankBlueprintFunctionLibrary- resolves by
CharacterIdand readsStartupAbilities. ATankPlayerController- local selection preview/prediction uses resolved
CharacterId. TankCharacterDefCsvImportCommandlet- writes identity/presentation/progression fields.
Character gameplay field usage:
ATankGameMode->CharacterDef->CharacterBPfor pawn class selection.ATankCharacterBaseandUTankAbilitySystemBPLibrary->PrimaryAttributes,SecondaryAttributes,VitalAttributes.ATankPlayerState->StartupAbilities,Lives,MovementSpeed, sync-loads referenced soft assets.UOnlineManagerSubsystemandFOnlineSelectionTransportService-> synchronous loading of CharacterDef bundles + soft references before submit/broadcast.
Import Tooling Contract¶
Item import (TankItemDefCsvImport)¶
Source columns (case-insensitive aliases supported):
- required:
itemId - optional:
assetName,categoryId,catalogIndex,requiredFeatureId,displayName,iconPath,staticMeshPath,skeletalMeshPath
XLSX behavior:
- every worksheet is imported
- worksheet name becomes
CategoryIdfor that sheet - optional row
categoryIddifferent from sheet name is ignored with warning
Output behavior:
- output is forced to
<OutputPath>/Item/<CategoryFolder>/<AssetName> - strict mirror mode: stale assets under output root are deleted
Character import (TankCharacterDefCsvImport)¶
Source columns (case-insensitive aliases supported):
- required:
characterId - optional:
assetName,categoryId,class,catalogIndex,requiredFeatureId,displayName,description,iconPath,skeletalMeshPath,startingLevel,unlockedSkills,strength,agility,intellect,vitality
XLSX behavior:
- currently requires worksheet named
1
Category fallback order:
- row
categoryId - commandlet
-DefaultCategory - source label (worksheet name)
- hard fallback
1
Output behavior:
- output is forced to
<OutputPath>/Character/<AssetName> - strict mirror mode: stale assets under output root are deleted
Shared commandlet flags¶
-StartIndex-DefaultCategory-PerCategory-UseExistingMax-DryRun
XLSX Inputs In Source/Tools¶
Source/Tools/TankInventoryTools/TankItemDefs.xlsxSource/Tools/TankInventoryTools/TankCharacterDefs.xlsx
These files are part of the Def schema contract. If column names or semantics change in Def classes, update:
- commandlet parser aliases
USAGE.md- designer workbook templates
NakamaInventoryWorkbenchworkbook parser if it consumes those columns
NakamaInventoryWorkbench Dependency¶
Primary files:
Tools/NakamaInventoryWorkbench/NakamaInventoryWorkbench/WorkbookReaders.csTools/NakamaInventoryWorkbench/NakamaInventoryWorkbench/CoreModels.csTools/NakamaInventoryWorkbench/NakamaInventoryWorkbench/InventoryCodec.cs
Important coupling:
- category normalization:
trim + lowercase - bitset encoding contract:
bitset_b64_lsb0 - owned snapshot JSON fields:
schema_version,catalog_version,owned_epoch,owned_rev,encoding,owned[] - workbook parser reads item/character id/category/display fields and optional stats
Character indexing note:
- Workbench treats character sheets by
characterIdheader and auto-assignscatalogIndexby row order per category. - This may diverge from explicit character
catalogIndexmanaged by commandlets if workbook/order rules are changed.
If character index semantics change, update both UE import and Workbench parser logic together.
GameFeature Packaging Dependency¶
Current runtime content pack:
Plugins/GameFeatures/TankInventory_Base
Current packaging/cook references:
Metal_terra.uprojectenablesTankInventory_BasepluginConfig/DefaultGame.iniincludes+DirectoriesToAlwaysCook=(Path="/TankInventory_Base")
Import scripts (Run-TankItemImport.ps1, Run-TankCharacterImport.ps1) behavior:
- patch picker scans
Plugins/GameFeaturesfor plugin names matching^TankInventory(?:_|$) - selected plugin
Contentfolder is used as output root - scripts append
/Itemor/Character
Future expansion rule:
- additional GameFeatures should keep
TankInventory*naming if you want automatic picker discovery. - otherwise update script matcher logic.
Refactor Matrix: Change X -> Update Y¶
| Change Type | Must Update |
|---|---|
Rename/add/remove Def property in UTankItemDef |
TankItemDef.h/.cpp, item commandlet parse/write (TankItemDefCsvImportCommandlet.cpp), XLSX headers/templates, USAGE.md, any runtime consumer reading the field |
Rename/add/remove Def property in UTankCharacterDef |
TankCharacterDef.h/.cpp, character commandlet parse/write (TankCharacterDefCsvImportCommandlet.cpp), XLSX headers/templates, USAGE.md, runtime consumers (TankPlayerState, TankGameMode, selection payload/transport, ability init) |
Change CategoryId or CatalogIndex semantics |
UTankInventorySubsystem, UOnlineSelectionPayloadLibrary, ATankPlayerState selection resolve, both commandlets, workbook conventions, backend validation expectations |
| Change equipped JSON shape generated from defs | UOnlineSelectionPayloadLibrary, ATankPlayerState::TryExtractCharacterCatalogIndexFromEquippedJson, backend parser assumptions in backend/inventory-selection.md |
| Change character asset loading policy | UOnlineManagerSubsystem::EnsureCharacterDefFullyLoadedForSelectionSubmit, FOnlineSelectionTransportService::EnsureCharacterDefFullyLoadedForBroadcast, ATankPlayerState::SyncLoadCharacterDefSource |
| Change import sheet rules | both commandlets, USAGE.md, source .xlsx authoring guidance, Workbench reader behavior |
Change feature-pack routing (RequiredFeatureId semantics) |
Def class comments/contract, both commandlets, any feature-gating runtime code (currently minimal usage), docs |
| Add new GameFeature def pack | plugin enablement (.uproject), cook rules (DefaultGame.ini), import script picker compatibility, content path conventions |
Add New Def Type (Future) Checklist¶
- Create new
UPrimaryDataAssetDef class inSource/Metal_terra/Public/Data. - Define stable identity fields up front (id/category/index + optional feature marker if needed).
- Mark identity fields
AssetRegistrySearchableif runtime indexing/resolution needs tags. - Add editor validation clamps in
PostEditChangeProperty. - Add import commandlet in
Source/Tools/TankInventoryTools. - Add run scripts and update
USAGE.md. - Add/maintain source workbook template in
Source/Tools/TankInventoryTools. - Add runtime subsystem indexing/resolution if this Def participates in ownership or selection.
- Update selection payload builder if this Def appears in
equipped.selected[]. - Update Nakama contracts/docs (
backend/inventory-selection.md) for any new payload fields. - Update
NakamaInventoryWorkbenchif offline JSON generation/inspection should include this Def. - Add cook/plugin/content routing for GameFeature distribution.
Known Current Gaps To Keep In Mind¶
- Character import is still single-sheet (
1) oriented, while tooling around catalogs is becoming more generalized. RequiredFeatureIdandClassIdare imported but currently have limited runtime consumers; they are mostly metadata right now.- Character def load-hardening exists in multiple paths (submit, broadcast, player-state sync-load). Refactors should avoid diverging behavior between these loaders.
- Legacy
UCharacterClassInfostill exists in source as historical data shape; active selection authority path is Def-driven.
Validation Checklist After Any Def Refactor¶
- Build C++ project and ensure
Metal_terra+TankInventoryToolscompile. - Run item import with
-DryRun, then real run; verify created/updated/deleted counts look expected. - Run character import with
-DryRun, then real run; verify sheet/category/index expectations. - Verify runtime logs:
RebuildItemDefIndex: indexed N item defs- no duplicate
(CategoryId, CatalogIndex)errors - Verify selection submit path builds payload from defs without
BuildEquippedJsonFromDefserrors. - Verify server broadcast tick resolves character defs successfully.
- Verify Nakama selection confirm/lock RPCs still accept payloads.
- Verify
NakamaInventoryWorkbenchcan load workbook and generate/parse owned snapshot JSON for changed schema.
Fast File Index¶
Core Def classes¶
Source/Metal_terra/Public/Data/TankItemDef.hSource/Metal_terra/Private/Data/TankItemDef.cppSource/Metal_terra/Public/Data/TankCharacterDef.hSource/Metal_terra/Private/Data/TankCharacterDef.cpp
Runtime consumers¶
Source/Metal_terra/Private/Core/Subsystems/TankInventorySubsystem.cppSource/Metal_terra/Private/Core/Subsystems/Online/OnlineSelectionPayloadLibrary.cppSource/Metal_terra/Private/Core/Subsystems/OnlineManagerSubsystem.cppSource/Metal_terra/Private/Core/Subsystems/Online/OnlineSelectionTransportService.cppSource/Metal_terra/Private/Core/TankPlayerState.cppSource/Metal_terra/Private/Core/TankPlayerController.cppSource/Metal_terra/Private/Core/TankGameMode.cppSource/Metal_terra/Private/AbilitySystem/TankAbilitySystemBPLibrary.cppSource/Metal_terra/Private/Character/TankCharacterBase.cpp
Import tooling¶
Source/Tools/TankInventoryTools/Private/Commandlets/TankItemDefCsvImportCommandlet.cppSource/Tools/TankInventoryTools/Private/Commandlets/TankCharacterDefCsvImportCommandlet.cppSource/Tools/TankInventoryTools/Run-TankItemImport.ps1Source/Tools/TankInventoryTools/Run-TankCharacterImport.ps1Source/Tools/TankInventoryTools/USAGE.md
External helper tool¶
Tools/NakamaInventoryWorkbench/README.mdTools/NakamaInventoryWorkbench/NakamaInventoryWorkbench/WorkbookReaders.csTools/NakamaInventoryWorkbench/NakamaInventoryWorkbench/CoreModels.csTools/NakamaInventoryWorkbench/NakamaInventoryWorkbench/InventoryCodec.cs
Packaging/config¶
Plugins/GameFeatures/TankInventory_Base/TankInventory_Base.upluginConfig/DefaultGame.iniMetal_terra.uproject