Architecture
World Forge is a monorepo with npm workspaces and TypeScript project references. Six packages form a clean dependency graph — five shipping today plus one reserved stub for the planned Godot 4 lane.
Package Map
Section titled “Package Map”packages/ schema/ @world-forge/schema — spatial types, validation, 2.5D fields export-ai-rpg/ @world-forge/export-ai-rpg — AI RPG Engine export pipeline + CLI export-unreal/ @world-forge/export-unreal — Unreal Engine 5 export pipeline + CLI (2.5D aware) export-godot/ @world-forge/export-godot — (planned) Godot 4 export lane, stub only renderer-2d/ @world-forge/renderer-2d — PixiJS 2D canvas renderer editor/ @world-forge/editor — React web authoring appThe 2.5D fields on Zone — elevation, elevationRange, parallaxLayers, skylineRef — are what the Unreal lane consumes to place actors on a Z-up axis with depth-ordered parallax backdrops. The AI RPG Engine lane ignores them; the Godot lane (planned) will reuse them.
Dependency Graph
Section titled “Dependency Graph”schema ← renderer-2dschema ← export-ai-rpgschema ← export-unrealschema ← export-godot (stub)schema + renderer-2d + export-ai-rpg + export-unreal ← editorSchema is the foundation. Each export lane depends only on schema — they are peers, not layered. The renderer depends only on schema. The editor depends on schema, the renderer, and every shipping export lane.
@world-forge/schema
Section titled “@world-forge/schema”The type authority. Defines every structure in a WorldProject:
- Authoring modes —
AuthoringModetype (7 modes),isValidMode(),DEFAULT_MODE - Spatial types —
WorldMap,Zone,ZoneConnection,ConnectionKind(12 kinds),Landmark - District types —
District,FactionPresence,PressureHotspot - Entity types —
EntityPlacement,ItemPlacement,SpawnPoint,EncounterAnchor - Dialogue types —
DialogueDefinition,DialogueNode,DialogueChoice,DialogueCondition,DialogueEffect - Asset types —
AssetEntry,AssetKind,AssetProvenance - Visual types —
Tileset,TileLayer,PropDefinition,AmbientLayer - Container —
WorldProjectinterface that holds everything - Validation —
validateProject()with 54 structural checks (Map-based O(n) lookups,warningCount);advisoryValidation()for mode-specific suggestions plus metadata completeness and asset naming checks
@world-forge/export-unreal
Section titled “@world-forge/export-unreal”Peer export lane that converts a WorldProject into an Unreal Engine 5 content pack tuned for 2.5D games. Emits pack.json, per-zone and per-district Primary Data Asset JSON, a grouped actor spawn manifest, level-streaming hints per connection, World Partition cell hints, and a structured fidelity report. The world-forge-export-unreal CLI wraps the pipeline with --out, --tile-size-cm, --validate-only, and --verbose flags.
2.5D fields — Zone.elevation, elevationRange, parallaxLayers, and skylineRef are preserved and converted into UE cm / Z-up coordinates.
Coordinate transform — pure functions pixelsToUnrealCm, elevationToZ, worldForgeToUnrealAxis, gridToUnrealAxis. Default world scale is 1 tile = 100 cm. Y-down (World Forge) becomes Z-up (Unreal) with Y flipped.
Round-trip import — importFromUnreal reconstructs a WorldProject from an Unreal pack; gameplay-only data (dialogues, progression, builds) is flagged as dropped in the fidelity report.
@world-forge/export-godot
Section titled “@world-forge/export-godot”Reserved workspace slot for the planned Godot 4 export lane (Fractured Road). Not yet implemented — the package ships today only as a stub so tooling and the editor can reference it without workspace churn when the lane lands.
@world-forge/export-ai-rpg
Section titled “@world-forge/export-ai-rpg”Bidirectional conversion between WorldProject and ai-rpg-engine’s ContentPack format.
Export — 9 converters transform WorldProject domains into engine types. exportToEngine() orchestrates validation, conversion, manifest generation, and warning collection. A CLI tool (world-forge-export) wraps the pipeline.
Import — 8 reverse converters reconstruct a WorldProject from exported JSON. importProject() auto-detects the format (WorldProject, ExportResult, or ContentPack) and orchestrates all converters. inferMode() recovers the authoring mode from connection kinds and grid area when importing pre-mode projects.
Fidelity — every import produces a structured FidelityReport tracking what was lossless, approximated, or dropped. Each entry has a domain, severity, and machine-stable reason key.
Diff — the editor includes a semantic diff engine (diff-model.ts) that compares two WorldProject snapshots with domain-specific comparators.
@world-forge/renderer-2d
Section titled “@world-forge/renderer-2d”PixiJS-based 2D renderer with six sub-renderers:
- WorldViewport — Application wrapper with pan, zoom, grid overlay
- ZoneOverlayRenderer — zone boundaries with district coloring, selection/hover
- ConnectionRenderer — lines between zones, arrows for one-way connections
- EntityRenderer — role-based icons (NPC, enemy, merchant, boss)
- TileLayerRenderer — z-ordered tile layers with tag-based coloring
- MinimapRenderer — scaled overview with viewport indicator
@world-forge/editor
Section titled “@world-forge/editor”React 19 + Vite web app. State management with Zustand, supporting undo/redo (10-deep stack with action labels), auto-save (30s throttle, 3-version recovery), clipboard (copy/paste with ID remapping), and per-object visibility (localStorage-persisted). Authoring modes (dungeon/district/world/ocean/space/interior/wilderness) adapt grid defaults, connection vocabulary, object creation defaults (connection kind, entity role, encounter type, zone naming), preset filtering, guide text, and advisory validation to the world’s scale. Canvas features include minimap overlay, viewport culling, connection preview lines, right-click context menu, performance stats, and dark/light theme toggle. Tools: select, zone-paint, connection, entity-place, encounter-place, landmark, spawn. Workspace tabs: Map, Objects, Player, Builds, Trees, Dialogue, Presets, Assets, Issues, Deps, Review, Guide, plus conditional Import (fidelity report) and Diff (semantic change tracking) tabs after importing a project.
Key editor modules:
- SearchOverlay — Ctrl+K fuzzy search across all object types (zones, entities, landmarks, spawns, encounters, districts, connections, dialogues, progression trees) and presets, with recent search history (localStorage)
- ObjectListPanel — hierarchical tree view (districts → zones → entities/landmarks/spawns/encounters) with bidirectional selection, inline filter, faction and hotspot counts
- EncounterProperties — single-encounter selection panel with type, enemy IDs, probability, cooldown, tags
- DistrictPanel — expanded district editor with metrics sliders, tags, controlling faction, economy profile, faction presence management, pressure hotspot editing
- duplicate.ts — pure function for duplicating selections with ID remapping, connection rewiring, and district preservation
- frame-helpers.ts — shared viewport framing utility (
computeFrameViewport) used by search, object list, and district panels - hit-testing.ts — pure math hit-testing (
findHitAt,findAllHitsAt) with click-cycle disambiguation for overlapping objects; priority: spawns > encounters > landmarks > entities > connections > zones - layout.ts — pure functions for 6-way alignment and horizontal/vertical distribution across any combination of object types
- snap.ts — pure snap computation for object-to-object snapping during drag and resize (edge/center matching, guide line generation)
- resize-handles.ts — pure math for zone resize handles (8 handles per zone, axis-aware resizing, min-size clamping, screen-space hit detection)
- connection-lines.ts — pure math for connection routing, edge anchoring (ray-rect intersection), line-segment hit-testing, kind-based visual styles (all 12 connection kinds with distinct colors and dash patterns), and display labels
- hotkeys.ts — centralized keyboard shortcut registry with 13 bindings,
matchHotkey()anddispatchHotkey()with input-field safety guard - PresetBrowser — preset library UI with Region/Encounter sub-tabs, merge/overwrite mode, save-from-current, built-in protection
- mode-profiles.ts —
ModeProfileinterface andMODE_PROFILESrecord with grid defaults, connection kinds, zone tag suggestions, guide overrides (district, zone, spawn, player, npc), encounter types, default entity role, zone name pattern, and mode tip per authoring mode;getModeProfile(mode)with dungeon fallback;getDefaultConnectionKind(mode)returns the mode’s primary connection kind - presets/ — preset type definitions (
RegionPreset,EncounterPresetwithmodes?: AuthoringMode[]), built-in presets (9 region, 10 encounter: 3 universal + 7 mode-specific),filterPresetsByMode(), Zustand + localStorage preset store - kits/ —
StarterKittype with multi-mode support, preset refs, guide hints, tags; 7 built-in kits wrapping mode starters;useKitStore(Zustand + localStorage CRUD with built-in protection);filterKitsByMode();validateKit()with errors + warnings; barrel export viaindex.ts - templates/ — genre starters, mode starter templates (7 hand-built projects, one per mode, derived from
BUILTIN_KITS), sample worlds (6 intermediate),ModeStarterinterface,MODE_STARTERSarray,createProjectFromModeStarter()factory - SpeedPanel — double-right-click floating command palette with context-aware actions, pinnable favorites (reorder), recent actions, custom groups, lightweight macros, edit mode for CRUD, search filtering
- speed-panel-actions.ts — action registry with
SpeedPanelActioninterface (includingmacroSafeandmodeSuggested), group/macro types, andfilterActions()returning 6-sectionFilteredActions(pinned, groups, recents, macros, modeSuggested, contextual) - speed-panel-execute.ts — extracted
executeAction()andexecuteMacro()pure functions withExecuteStoresinterface for testability - speed-panel-store.ts — Zustand + localStorage store for pins (with reorder), recents, groups CRUD, macros CRUD, step management
Design System
Section titled “Design System”The editor uses a three-layer design system:
theme.css— ~85 CSS custom properties (backgrounds, text, semantic colors, borders, spacing, shadows, typography, z-index, layout, transitions). Imported once inmain.tsxstyles.ts— ~27 reusableCSSPropertiesobjects (panelShell,buttonBase,buttonAccent,inputBase,overlayBackdrop,modalCard(), etc.) that reference the CSS variablesModalFrame.tsx— shared modal shell (backdrop + card + title + close button) used by all 7 modals
Panel components in shared.tsx (PanelHeader, ConfirmButton, EmptyState, useFocusHighlight) consume style primitives from styles.ts. All consumer files import styles from styles.ts, not from component files.
Build System
Section titled “Build System”tsc --build at the root builds all packages in dependency order using TypeScript project references. Each package has its own tsconfig.json that references its dependencies. Vitest runs tests across the monorepo.