Skip to content

Technical Changelog

Full history of commits (technical). Generated from git log.


48cb081 – fix(ts): remove redundant dismantle check in JobAssigner (TS2367) (2026-03-02 22:55:43 +0100, Kamil Kawka-Tomczak)

Made-with: Cursor

e40a934 – chore: add English-only rule, translate UI and docs (2026-03-02 22:53:20 +0100, Kamil Kawka-Tomczak)

  • .cursorrules: all text, docs, commits must be in English
  • ObjectPanel: Rozbierz -> Dismantle
  • IsometricMap: Idź do/Biegnij do -> Move here/Run here
  • todo.md, changelog.md, ui-structure.md: translate PL to EN

Made-with: Cursor

a88fe13 – feat(build): rozbiórka budowli (dismantle) + budowanie, Construction, tekstury (2026-03-02 22:51:00 +0100, Kamil Kawka-Tomczak)

Rozbiórka: - DismantleJob: 10% czasu budowy, 50% surowców (zaokrąglone w dół) - Przycisk Rozbierz w ObjectPanel dla finished buildings - JobAssigner, JobWorkExecution obsługa dismantle - IsometricMap.dismantleObject, handleDismantleComplete - SelectionEvent type: cleared - zamknięcie panelu po rozbiórce

Budowanie: - Cancel build: anulowanie blueprint/delivery, drop zasobów - Umiejętność Construction (canDoJob build) - Tekstury budowli w ObjectLayer (furniture.ts) - HaulJobCreator: skip buildings w createHaulJobs - GameFooter Jobs tab, ColonistPanel allowed jobs

Made-with: Cursor

69c1450 – fix(build): TS errors + cursorrules npm/docker (2026-03-02 21:37:42 +0100, Kamil Kawka-Tomczak)

  • main.ts: cast needKey for setColonistNeed
  • SettingsScreen: use SettingsTab enum, fix Tab types
  • GameScreen: assert workshopData/objectData for SelectionEvent
  • Minimap: add target to pointerdown event type
  • .cursorrules: npm via docker compose exec dev

Made-with: Cursor

f9d458a – feat(ui): React layout – sidebar usunięty, overlaye, GameBridge (2026-03-02 21:08:00 +0100, Kamil Kawka-Tomczak)

Entry point i layout: - index.html → react/main.tsx (React entry); App.tsx – ekrany + game layout - init(container, { useReactLayout, onGameReady, onLoadingProgress }) - Canvas reparenting na Singleplayer

Sidebar usunięty: - GameArea sidebarWidth: 0, mapa full width - GameFooter (React) – Order manager, Colonists, Jobs

Overlaye (DraggableOverlayPanel): - Menu, Minimap, FPS, Zoom, Speed, Dev, SelectionPanel - Pozycja/rozmiar w StorageDriver (sessionStorage)

GameBridge (GameUIApi), StorageDriver React + MUI + Vite

Docs: ui-structure, changelog, minimap (sessionStorage) Made-with: Cursor

ddfbed7 – fix(ui): right-click Idź do/Biegnij do – selectedColonistId w React layout (2026-03-02 21:06:11 +0100, Kamil Kawka-Tomczak)

  • GameOverlays: setSelectedColonistId przy zmianie zaznaczenia (citizen) i przy zamknięciu panelu
  • IsometricMap: polskie etykiety menu kontekstowego (Idź do, Biegnij do)
  • Docs: changelog, ui-structure (selectedColonistId flow)

Made-with: Cursor

455d564 – feat(minimap): header, collapse, drag, persistence; sidebar speed controls up (2026-03-01 23:18:48 +0100, Kamil Kawka-Tomczak)

  • Minimap overlay: header with collapse/expand button, drag to reposition
  • Persistence: position and collapsed state in localStorage (simu-game-minimap-overlay)
  • Sidebar: removed minimap spacer, speed controls moved up
  • Docs: minimap.md, changelog, ui-structure

Made-with: Cursor

8532e9c – feat: zones, recreation need, place colonist, layer offset (2026-03-01 20:00:23 +0100, Kamil Kawka-Tomczak)

Zones: - Zone types have defaultColor (storage, sleeping, growing, recreation) - ZoneOverlayLayer renders all four types; getTileKeysFromBounds helper - ZoneManager uses def.defaultColor when creating zone; findNearestRecreationZoneTile

Recreation need: - RecreationJob, NeedType + recreation; colonist BASE_ALLOWED_JOB_TYPES + recreation - NeedJobScheduler createRecreationJobForColonist (in zone 15s, outside 30s) - ColonistObject: recreationCrossed, fulfillRecreation, recreationWasAboveThreshold - RecreationNeedHandler, ColonistBehaviors + context requestNeedJob('recreation') - JobWorkExecution + JobAssigner + JobSystem + IsometricMap onRecreationComplete

Other: - Place colonist: single use then deselect; setOnPlaceColonistModeChange for DevPanel - CameraController: layer offset restored (LAYER_OFFSET_EXTRA_PX = 4) for terrain alignment - JobWorkExecution: single actionId declaration in startWorkOnJob

Made-with: Cursor

f13ce12 – feat(ui): selection border follows colonist smoothly during movement (2026-02-13 10:50:41 +0100, Kamil Kawka-Tomczak)

  • ObjectLayer: getInterpolatedTilePosition(colonistId) for current move interpolation
  • MapView: expose getInterpolatedTilePosition
  • SelectionManager: updateSelectionBorderPosition(tileX, tileY), refactor to drawSelectionBorderAt()
  • IsometricMap: after each map render, update selection border from interpolated position when selected object is colonist

Co-authored-by: Cursor cursoragent@cursor.com

318f746 – fix: zone panel first click + Delete zone button in top-right (2026-02-13 08:59:09 +0100, Kamil Kawka-Tomczak)

  • Zone panel: clearSelection(true) on zone tile click so sidebar does not clear panel before show
  • ZonePanel: move Delete zone button to top-right of content (below header), wordWrap for Stored list
  • todo.md: document zone panel fix and UI change, mark section Fixed

Co-authored-by: Cursor cursoragent@cursor.com

b06630a – Align map layers: terrain offset so grid matches zones/objects (2026-02-12 22:46:21 +0100, Kamil Kawka-Tomczak)

Layer alignment: - Apply layer offset only to terrain tiles (TerrainLayer): positions use (px - layerOffset, py - layerOffset) so CompositeTilemap aligns with zones, objects, and selection borders (which use tile grid as-is). - Single tuning point: CameraController.getLayerOffset(), driven by LAYER_OFFSET_TILE_FRACTION and LAYER_OFFSET_EXTRA_PX. - Removed offset from ZoneOverlayLayer, ObjectLayer, SelectionManager. - Documented in CameraController and TerrainLayer.

Other: Run-to destination, colonist needs decay, job system updates. Co-authored-by: Cursor cursoragent@cursor.com

098281a – feat(perf): telemetry, UUID/map perf, pointer throttle, FPS on hover (2026-02-12 22:04:12 +0100, Kamil Kawka-Tomczak)

Telemetry: - Client: batch 500 events, flush 1min + pagehide sendBeacon, POST /api/telemetry - Server: append JSONL to data/telemetry.jsonl; data/ in .gitignore - Events: app_init, session_created/loaded, screen_view, job_queued/assigned/work_started/completed/cancelled, behavior_wander/need_requested, zone_created/removed

Performance: - UUID: fast isValidUUID (no regex in hot path); drop validation in ObjectManager getObjectByUUID/hasObject/remove/move - Fewer lookups: BehaviorRunner getAllObjects+filter; ObjectLayer objectRef in userData for overlays; syncColonistJobActionFromJobQueue Map by UUID - Pointer throttle (32ms): MapTooltipHandler, cursor label, MapInputHandler; throttle.ts util - FPS on hover: renderMapView every 2nd frame when camera static; updateOverlays every 2nd frame - BehaviorRunner: prune accumulators for removed entities

Docs: docs/performance.md, map-rendering performance section, changelog Co-authored-by: Cursor cursoragent@cursor.com

dfada73 – fix(ts): SessionData data optional; LoadedRaw for parse so mapData assignable (2026-02-12 19:51:29 +0100, Kamil Kawka-Tomczak)

Co-authored-by: Cursor cursoragent@cursor.com

e009b27 – Behaviors in sim/core: BehaviorRunner, colonist behaviors, docs (2026-02-12 19:41:31 +0100, Kamil Kawka-Tomczak)

  • sim/core/behaviors: generic BehaviorRunner with interval-based tick
  • sim/core/objects/colonist/ColonistBehaviors: needCheck (tick needs, request drink/sleep), wander (request MoveToJob when free)
  • Client: ColonistBehaviorContextImpl only (addWanderJob, requestNeedJob); IsometricMap uses BehaviorRunner from sim
  • DEBUG_HAUL_ONLY=false: re-enable wandering, sleep, drink
  • Wandering uses MoveToJob (same pathing rules as other jobs)
  • Docs: systems/behaviors.md, overview + movement-needs updated, zensical nav

Co-authored-by: Cursor cursoragent@cursor.com

6143c3f – Session format: compact map, no duplicate fields, objects vs colonists, docs (2026-02-12 19:21:39 +0100, Kamil Kawka-Tomczak)

  • SessionManager: store map as mapCompact (types + t/e arrays); expand on load
  • Objects: store only extra fields in data (no duplicate type/x/y/uuid)
  • objects[] = non-colonist only; colonists[] = colonists only (save & load)
  • Load: backward compat for old mapData and old single objects[] format
  • persistence.md: document full session storage format (mapCompact, objects/colonists, data shape)

Co-authored-by: Cursor cursoragent@cursor.com

3bb55d1 – docs: technical changelog from git log in CI (2026-02-12 19:04:22 +0100, Kamil Kawka-Tomczak)

  • scripts/generate-changelog.sh: generates docs/changelog.md from git log
  • build:docs: run script before zensical build, add docs/ to artifacts
  • zensical nav: changelog.md under Technical
  • npm run docs:changelog for local refresh

Co-authored-by: Cursor cursoragent@cursor.com

f96aa16 – PPM context menu, panel title bar + close, docs (2026-02-12 18:58:45 +0100, Kamil Kawka-Tomczak)

  • MapContextMenu: right-click on object (Chop/Mine) or empty tile (Move here)
  • PPM orders assigned to selected colonist when colonist panel open (reservedForColonistId)
  • MoveToJob in sim/core/jobs/move, wired in JobSystem/JobAssigner
  • Panel title bar with name + X; close clears map selection (clearSelection skipCallback)
  • MapInputHandler: ignore pointerup when button !== 0 to keep selection on PPM
  • JobSystem.getPlannedTargetObjectIds: skip move jobs (no UUID)
  • Docs: panel-internals (title bar, close, PPM menu), ui-structure (GameArea PPM)

Co-authored-by: Cursor cursoragent@cursor.com

0cae18b – refactor(ui): ColonistPanelGearTab, ZonePanel registries, docs (2026-02-12 18:32:35 +0100, Kamil Kawka-Tomczak)

  • Move GearTab to sidebar/panels as ColonistPanelGearTab (ColonistPanel-only)
  • Fix ResourceWeights import path; use ColonistPanelGearTab naming
  • ZonePanel: zone name from instance + ZoneTypeRegistry (sim/core), storage labels from getObjectTypeDisplayLabel (gameData/objectTypes)
  • Docs: panel-internals (Gear→ColonistPanelGearTab, ZonePanel sources), game-data (display labels section)

Co-authored-by: Cursor cursoragent@cursor.com

6076dd6 – feat(ui): zone overlay labels from zone type definition (displayName) (2026-02-12 18:09:17 +0100, Kamil Kawka-Tomczak)

Co-authored-by: Cursor cursoragent@cursor.com

417f7a5 – refactor(ui): WorkAssignmentPanel from registry; unify overlays; docs (2026-02-12 18:05:18 +0100, Kamil Kawka-Tomczak)

  • Footer: JobsPanel -> WorkAssignmentPanel; job ids/labels from workAssignmentJobs registry
  • Object overlays: single bubble style for Zzz and need messages; one container (objectOverlaysContainer)
  • Cooldown for need bubbles on ColonistObject (getOverlayDescriptor returns null when in cooldown; setOverlayCooldownUntil from view)
  • AbstractObject: optional setOverlayCooldownUntil(); timing constants OVERLAY_VISIBLE_MS/OVERLAY_COOLDOWN_MS in ObjectLayer
  • Docs: map-rendering (ObjectLayer overlays), game-data (Footer/overlays), sim-objects (getOverlayDescriptor/setOverlayCooldownUntil)

Co-authored-by: Cursor cursoragent@cursor.com