Skip to content

Sim objects

Overview

Objects on the map live in the sim layer (src/sim/core/objects/). They are pure logic – no PixiJS. The client uses ObjectFactory and TextureProvider to create and render them.

Folder structure

Path Contents
objects/base/ AbstractObject, LandscapeElementObject, ResourceObject, types.ts
objects/landscape/ PineTreeObject, StoneChunkObject
objects/resources/ WoodLogObject, StoneBrickObject
objects/colonist/ ColonistObject
objects/interfaces/ GatherableInterface, StackableInterface, TextureProvider, ActionExecutor
ObjectManager.ts, index.ts Manager and re-exports

Hierarchy

AbstractObject (base/)
├── ColonistObject (colonist/)
├── LandscapeElementObject (base/)
│   ├── PineTreeObject (landscape/) – GatherableInterface
│   └── StoneChunkObject (landscape/) – GatherableInterface
└── ResourceObject (base/)
    ├── WoodLogObject (resources/)
    └── StoneBrickObject (resources/)

AbstractObject

Base for all map objects. Defines:

Method Purpose
getPosition(), setPosition() Tile (x, y)
getUUID(), getId() Unique id for persistence
getTexture() Textures + relative positions (client-provided)
getDisplaySize(), getClickableSize(), getClickableOffset() Size and click area
getName(), getType() Display name and type id
getPanelType() 'object', 'workshop', 'citizen', or null
getActions() Action definitions (id, name, duration, etc.)
isClickableAt(), isDisplayedAt() Hit testing
serialize(), deserialize() Save/load

Interfaces

GatherableInterface

Objects that can be gathered (chop, mine):

  • getDrop(): { type: string; quantity: number }[] – drops when gathered
  • dispatchGatherAction(onComplete) – start gather work (rendering layer handles completion)

Implemented by: PineTreeObject, StoneChunkObject

StackableInterface

Objects with quantity:

  • getQuantity(): number
  • getMaxStack(): number

Implemented by: WoodLogObject, StoneBrickObject (via ResourceObject)

TextureProvider

Injected by the client. Used for getTexture():

  • getTextureByPosition(row, col) – sprite sheet
  • getTextureByAsset(path) – asset path
  • getTextureFromSpriteSheet(path, frameCol, frameRow, cols, rows) – sprite sheet frames

ActionExecutor

Injected by the client. Used by jobs to run actions (chop, mine):

  • executeAction(objectId, actionId, onProgress?, onComplete?, options?)
  • canExecuteAction(objectId, actionId)

ColonistObject

  • Skills – level and XP per skill (e.g. Woodworking, Mining)
  • Needs – sleeping, drinking, eating, recreation (0–100, decay over time)
  • JobcurrentJobId, allowedJobTypes, canDoJob(), setJobAllowed()
  • HaulcarriedObject, setCarriedObject()
  • Needs logictickNeeds(), fulfillDrinking(), fulfillSleep(), getLowNeedMessages()
  • OverlaygetOverlayDescriptor() (Zzz when sleeping, need messages with cooldown); setOverlayCooldownUntil(ts) called by view after bubble display time
  • XPaddSkillXp(skillName, xp) – 1 XP per 0.1s of work

See Needs & movement for need decay and job creation.

Object types

Type Class Gatherable Stackable Drops
colonist ColonistObject
pine_tree PineTreeObject 25 wood_log
stone_chunk StoneChunkObject 10 stone_brick
wood_log WoodLogObject ✓ (max 100)
stone_brick StoneBrickObject

ObjectManager

  • Storage: Map<uuid, AbstractObject> and spatial index Map<tileKey, Set<uuid>>
  • Add/remove: addObject(), removeObject(uuid), removeObjectAt(x, y)
  • Move: moveObject(uuid, newX, newY) – updates spatial index
  • Lookup: getObjectByUUID(), getObjectAt(x, y) (clickable), getObjectsAt(x, y) (spatial)
  • Serialization: serialize(), deserialize(data, objectFactory)

ObjectFactory

Client (src/client/ui/utils/ObjectFactory.ts) creates objects from serialized data:

  • Uses TextureProviderImpl for textures
  • Maps type → constructor: pine_tree, stone_chunk, wood_log, stone_brick, colonist
  • Passes colonist data (name, age, skills, needs, etc.) for ColonistObject

Adding a new object type

  1. Create class in the appropriate subdir (objects/landscape/, objects/resources/, or objects/colonist/) extending AbstractObject, ResourceObject, or LandscapeElementObject from ../base/
  2. Implement getType(), getName(), getTexture(), getDisplaySize(), getClickableSize(), getActions()
  3. Export from the subdir index.ts and from objects/index.ts
  4. Add case in ObjectFactory.createObject() (client) for the new type
  5. If gatherable: implement GatherableInterface and register action (e.g. chop) in game data
  6. If stackable: extend ResourceObject and implement getMaxStack()