Item Data Model¶
Document: Technical Design – Items – Item Data Model
Status: Exploratory
Last updated: 2026-01-12
1. Purpose¶
This document defines the authoritative data model for items in Atherion.
Goals:
- support binding rules and anti-RMT measures
- enable rarity + affix systems
- allow crafting and upgrading
- remain stable across engine and language changes
- be compatible with SpacetimeDB’s table + reducer model
This is a server-authoritative model. Clients never derive item truth.
2. Core Design Principles¶
2.1. Items Are Data, Not Objects¶
Items are:
- immutable definitions + mutable state
- referenced by ID, not duplicated logic
- always validated server-side
The client:
- renders items
- requests actions
- never computes outcomes
2.2. Separate Definition from Instance¶
- ItemDefinition: static, authored data
- ItemInstance: player-owned, mutable data
This allows: - balancing without migration - item upgrades without redefining the base - clean crafting pipelines
3. ItemDefinition Table¶
Defines what an item is.
ItemDefinition
--------------
id: ItemDefId (primary key)
name: string
rarity: enum (Common, Uncommon, Rare, Epic, Legendary)
item_type: enum (Weapon, Armor, Accessory, Consumable, Material)
slot: enum (Head, Chest, Legs, Hands, Feet, Weapon, Offhand, None)
base_stats: json
affix_pool_id: optional AffixPoolId
icon_id: string
model_id: string
Notes:
- base_stats are bounded and never scale infinitely
- Legendary items do not use affix pools
- model_id maps to Unity prefabs
4. ItemInstance Table¶
Defines a specific item owned by someone.
ItemInstance
------------
id: ItemInstanceId (primary key)
item_def_id: ItemDefId
owner_type: enum (Character, Account, Company)
owner_id: EntityId
binding_type: enum (Unbound, Account, Soul, Company)
binding_state: enum (Unbound, Bound)
affixes: json
upgrade_level: int
durability: optional int
created_at: timestamp
Notes:
- Items never change owners without a reducer
- affixes are resolved at creation or upgrade time
- binding_state allows bind-on-equip logic
5. Affix Data Model¶
5.1. AffixDefinition¶
AffixDefinition
---------------
id: AffixId
name: string
category: enum (CombatFlow, RoleInteraction, Survival, Utility)
trigger: enum
effect: json
stacking_rule: enum (None, Diminishing, Unique)
Affixes are:
- conditional
- readable
- bounded
5.2. AffixPool¶
AffixPool
---------
id: AffixPoolId
allowed_affixes: list<AffixId>
rarity_weights: json
max_affixes: int
Affix pools:
- are item-type specific
- prevent invalid combinations
- enforce balance constraints
6. Binding Model¶
Binding is enforced only on the server.
6.1. Binding Logic¶
- Binding type is set at item creation
- Binding state may change via reducer
- Binding rules are never client-controlled
Examples:
- Equip item → bind on equip
- Upgrade beyond threshold → bind on upgrade
- Company-crafted item → bind to company
⸻
6.2. Ownership Model¶
Ownership is abstracted via:
- owner_type
- owner_id
This allows:
- account-wide storage
- company vaults
- character inventory
- future expansion (e.g. NPC storage)
⸻
7. Inventory and Storage Tables¶
7.1. CharacterInventory¶
CharacterInventory
------------------
character_id: CharacterId
item_instance_id: ItemInstanceId
slot_index: int
7.2. CompanyVault¶
CompanyVault
------------
company_id: CompanyId
item_instance_id: ItemInstanceId
permission_mask: int
No item exists without being referenced by exactly one inventory/vault.
⸻
8. Crafting Interaction¶
Crafting reducers:
- consume ItemInstances (materials)
- create new ItemInstances
- optionally bind output
Crafting never mutates:
- ItemDefinition
- existing ItemInstances directly
⸻
9. Reducers (High-Level)¶
Examples:
- CreateItemInstance
- EquipItem
- UpgradeItem
- TransferToVault
- BindItem
All reducers:
- validate ownership
- validate binding rules
- run atomically
⸻
10. Versioning and Migration¶
- ItemDefinitions are versioned implicitly
- Old ItemInstances reference their original definition
- Balance changes affect new items only
Avoids forced migrations.
⸻
11. Anti-RMT Guarantees¶
This model ensures:
- no hidden ownership
- no shadow trades
- all transfers logged
- binding enforced at data level
RMT becomes inefficient and risky.
⸻
12. Performance Considerations¶
- ItemInstances are lightweight records
- Affixes resolved once, not per tick
- Combat systems read cached values
Hot paths avoid JSON parsing during combat.
⸻
13. Why This Model Works¶
- Clean separation of concerns
- Deterministic and auditable
- Scales with content
- Survives language rewrites (C# → Rust)
- Friendly to Unity clients
- Hard to exploit
⸻
14. Open Questions¶
- Should durability exist at all?
- Should some items be “virtual” (no instance)?
- How granular should audit logs be?
- Should items ever decay or retire?
These are deferred decisions.
End of document.