---
id: world-map-and-portals/007
title: The entity class restructure — ComplexItem, LivingCreature, Player
epic: world-map-and-portals
state: done
priority: 3
blocked_by: []
estimate: M
created: 2026-08-15
updated: 2026-08-18
claimed_by: null
claimed_at: null
delivers: []
review_artifact: land-of-lor/game/world/complex_item.gd
---

## What landed

Kris's structure, adopted with four deviations, all flagged rather than silently taken:

```
ComplexItem            data + serialisation only
  +- LivingCreature    things that move and (later) can be hurt
       +- Player       account, seed, display name
       +- Creature     autonomous, flow-field driven
SimpleItem             a sibling, not a child
```

- **`SimpleItem` is a sibling of `ComplexItem`.** Giving stackable data a tick it never uses
  invites behaviour to leak into it, and "everything is simple or complex" reads as two roots.
- **Inventory belongs to `Player`**, not `LivingCreature`, until a creature carries loot.
- **The base carries no behaviour** — it stays the 68 lines of pure data it always was.
- **Portals did NOT become ComplexItems** (against Handoff 1's suggestion). They are static
  grid metadata sent once at `hello_ack`; making them entities would put them in the 10Hz
  broadcast and every snapshot for no gain. Towers and spawn points are the right first
  non-creature items.

**The wire contract did not change.** `to_dict()` output is byte-identical and `kind` still
says `player` / `creature` — `from_dict` defaults it to `"player"`, so renaming it would
hydrate every persisted creature in production as a player.

`entity_factory.gd` is the one place a wire dictionary becomes a typed object. A spike
confirmed the base-preloads-its-own-subclass cycle *does* work in Godot 4.7.1 headless, so the
separate factory is a design choice — one registration point for a new type — rather than a
workaround.

## Verification

`godot --headless --path game/world --script test_runner.gd` — 116 passing, including
`test_entity_hierarchy()` (round-trips, factory dispatch, a kind-less legacy snapshot, an
unknown future kind falling back to the base, and movement treating players and creatures by
the same rules). The director's 139 tests, which spawn the real Godot world server, are green
throughout.