Entities¶
Status: Current
Last reviewed: 2026-07-07
Source: server/src/game/entities.ts, shared/src/types.ts
Entity Ids¶
Ids are prefix_base36, minted by makeId(prefix): pl_ players, gob_ goblins, prj_ projectiles, loot_ loot bags, npc_ NPCs. Ids are unique for the life of the process.
Entity Types¶
The wire-level EntityType values are player, goblin, projectile, loot_bag, village_npc, plus reserved item and spell_effect. Every server entity implements two methods:
spawnData()returns the fullEntitySpawnDatasent once when the entity enters a client's view.snap()returns the smallEntitySnapincluded in each tick's snapshot, ornullfor static entities (NPCs and loot bags do not move, so they only send spawn data).
Player¶
PlayerEntity holds the movement state (pos, vel, onGround), aim (yaw, pitch), vitals (hp, stamina, mana), the equipped weapon, and the weapon state machine (wstate, wstateT, drawStartedAt, blockRaisedAt, blocking). It also carries the input queue, the last acknowledged input sequence, inventory, skills, skill-use accumulators, and the quest log. godMode and isAdmin gate editor and playtest behaviour. See Combat for the state machine.
NPC¶
NpcEntity comes from an npc_spawn zone object. It stores defId (the stable npcId), display name, role, position, yaw, dialogue lines, and the questIds it offers or completes. NPCs are static; they only send spawn data. In the client they face a fixed yaw and idle. See Adding NPCs.
Mob¶
GoblinEntity is the one mob family. Its variant selects a tuning row from GOBLIN_TUNING:
| Variant | HP | Speed | Sight | Attack range | Cooldown | Windup | Damage | Weight |
|---|---|---|---|---|---|---|---|---|
| scrapper | 42 | 5.4 | 17 | 2.2 | 1.7 | 0.55 | 7 | 1.0 |
| slinger | 30 | 4.6 | 20 | 17 | 2.3 | 0.5 | 6 | 0.9 |
| hexer | 24 | 4.3 | 19 | 15 | 3.0 | 0.7 | 11 | 0.85 |
| champion | 240 | 5.0 | 24 | 3.0 | 2.4 | 0.75 | 18 | 2.4 |
Runtime AI fields cover state (idle/aggro/return), current target, timers, a pending telegraphed attack, stagger, and animation. weight scales knockback resistance, hit-capsule size, and model scale. See Adding Mobs and the AI section of Combat.
Projectile¶
ProjectileEntity covers arrow, fireball, rift_burst, goblin_rock, and hex_bolt. Each pulls a ProjectileDef (speed, gravity, radius, damage, splash radius, ttl, knockback). Arrows carry a per-instance damage and draw set by the bow draw model. Projectiles integrate with gravity and use swept sub-step collision (advancing in short steps sized to the projectile radius) so fast arrows do not tunnel through goblin-sized targets.
Loot Bag¶
LootBagEntity drops on goblin death with rolled loot (rollGoblinLoot) and lives for LOOT_BAG_TTL (120 s). Interacting within INTERACT_RANGE grants the items and fires quest loot_item events. Full-loot player corpses reuse the same class and are a marked TODO.
Quest Trigger¶
Not an entity but a derived volume. buildZoneRuntime turns each quest_trigger object into a QuestTriggerDef (triggerId, position, radius). Twice a second the server checks players against triggers and fires reach_area quest events. See Quest System.
Resource Node¶
The resource_node prefab exists as a placeable, colliding prop with a nodeType property. Gathering is not implemented yet; the prefab and its ember hooks are in place so the gathering milestone can build on them.
Ember Relay¶
The ember_relay prefab (the cracked shrine) is the anchor of the Emberwake system. buildZoneRuntime collects relays into emberRelays, and EmberSystem.bind picks the first one as the pressure source. See The Emberwake System.
Admin-Placed Object¶
Everything in a zone is a ZoneObjectInstance: id, prefab, x, z, optional y height offset, yaw, scale, and an optional props blob. Colliders, spawns, NPCs, triggers, safe zones, and relays are all derived from these instances by buildZoneRuntime, so the editor only ever manipulates this one shape. See Level Editor.