From d1632dc5d8e58c4824fdf85ebe517ed01d831d08 Mon Sep 17 00:00:00 2001 From: Andraxion Date: Sat, 27 Jun 2026 06:49:08 -0400 Subject: [PATCH] Add shared contract architecture note --- Future - Shared Contract.html | 594 ++++++++++++++++++++++++++++++++++ 1 file changed, 594 insertions(+) create mode 100644 Future - Shared Contract.html diff --git a/Future - Shared Contract.html b/Future - Shared Contract.html new file mode 100644 index 0000000..3e75132 --- /dev/null +++ b/Future - Shared Contract.html @@ -0,0 +1,594 @@ + + + + + + Future - Shared Contract + + + +
+
+
Architecture Note
+

Future - Shared Contract

+

+ The safest long-term split is to make a common core own the portable game domain, + while Worldshaper owns authoring workflows and World-Workshop + owns runtime execution, ECS, rendering, and simulation wiring. +

+
+ Decision rule: if a module can run unchanged in tests, browser, editor, and runtime + without depending on React, Pixi, Tauri, or bitECS, + it is a strong candidate for the shared core. +
+
+ +
+

Recommended Ownership Split

+
+
+

Shared Core

+

Owns the portable contract, validation, normalization, and pure game-domain logic.

+
    +
  • Authored content types
  • +
  • Stable IDs and references
  • +
  • Schema versions and migrations
  • +
  • Reference resolution
  • +
  • Pure gameplay formulas and rule evaluation
  • +
  • Prefab and archetype definitions
  • +
+
+
+

Runtime

+

Owns the executable simulation and all performance-driven or transient state.

+
    +
  • bitECS components and entity storage
  • +
  • Spawn and assembly from content to ECS
  • +
  • Systems, ticking, AI, pathfinding integration
  • +
  • Rendering, audio, input, camera
  • +
  • Runtime caches and live state
  • +
+
+
+

Editor

+

Owns source editing UX, layout, tools, and authoring-specific productivity features.

+
    +
  • Inspectors, forms, palettes, map editing
  • +
  • TS source rewriting and formatting
  • +
  • Undo/redo, selection, layout preferences
  • +
  • Authoring warnings and quick fixes
  • +
  • Studio-only metadata and workflows
  • +
+
+
+
+ +
+

What Belongs In The Shared Core

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AreaSafe To ShareWhy
Content definitionsWorld, Chunk, NpcTemplate, PlacedEntity, Ability, Dialogue, ItemThese are authored domain concepts, not renderer or ECS details.
Type helpersdefineNpc(), defineWorld(), definePrefab()Both editor and runtime benefit from a single shape and single set of defaults.
IDs and refsNpcId, WorldId, DialogueId, SpriteId, TemplateIdStable identifiers should mean the same thing everywhere.
ValidationReference checks, required fields, defaulting, normalization, semantic validationContent should be judged by one source of truth, not two slightly different validators.
MigrationsschemaVersion upgrades and canonical output transformsThis keeps old content loadable in both tools.
Pure rulesDialogue condition checks, loot rolls, stat formulas, cooldown math, faction logicThese are deterministic rules that do not need the runtime shell.
Content registryLookup and resolution APIs over loaded definitionsBoth projects need the same view of the authored world.
+ +
Shared core example: portable authored contractexport interface PlacedEntity {
+  id: EntityInstanceId;
+  templateId?: EntityTemplateId;
+  archetype: ArchetypeId;
+  position: { x: number; y: number; z: number };
+  spriteId?: SpriteId;
+  dialogueId?: DialogueId;
+  factionId?: FactionId;
+  tags?: string[];
+  overrides?: Partial<EntityTemplate>;
+}
+
+export function definePlacedEntity(
+  value: PlacedEntity,
+): PlacedEntity {
+  return normalizePlacedEntity(value);
+}
+
+ +
+

What Should Stay Runtime-Owned

+

+ The runtime should keep everything that is shaped primarily for execution speed, frame-to-frame state, + ECS storage layout, or engine integration. +

+
+
+

Keep These In World-Workshop

+
    +
  • bitECS component arrays and entity IDs
  • +
  • ECS world creation and system scheduling
  • +
  • Assembly from authored entities into spawned ECS entities
  • +
  • Transient state like routes, targets, planner handles, and sprite instances
  • +
  • Rendering, audio, input, camera, spatial index, pathfinder integration
  • +
+
+
+

Why

+
    +
  • These are not stable authoring concepts.
  • +
  • They will change when the engine changes.
  • +
  • They often depend on engine libraries and performance tradeoffs.
  • +
  • They should be free to evolve without forcing content migrations.
  • +
+
+
+ +
Runtime example: ECS remains runtime-onlyconst GridPosition = {
+  x: new Int16Array(MAX_ENTITIES),
+  y: new Int16Array(MAX_ENTITIES),
+  z: new Int16Array(MAX_ENTITIES),
+};
+
+const Target = {
+  x: new Int16Array(MAX_ENTITIES),
+  y: new Int16Array(MAX_ENTITIES),
+  z: new Int16Array(MAX_ENTITIES),
+  active: new Uint8Array(MAX_ENTITIES),
+};
+
+function spawnFriendlyNpc(world: GameWorld, def: ResolvedEntityDef): number {
+  const entity = addEntity(world);
+  addComponent(world, entity, GridPosition);
+  addComponent(world, entity, Target);
+  addComponent(world, entity, Agent);
+  // Runtime decides the exact ECS shape here.
+  return entity;
+}
+
+ +
+

What Should Stay Editor-Owned

+

+ The editor should keep everything that exists to improve authoring speed, visibility, and safety, + especially if it is tied to UI behavior or source editing mechanics. +

+
    +
  • Inspectors, map tools, palettes, graphs, and editor windows
  • +
  • Selection state, undo/redo, dirty tracking, docking, recent files
  • +
  • TS source rewriting, formatting, and file-structure conventions
  • +
  • Inline diagnostics, authoring warnings, quick fixes, bulk-edit tools
  • +
  • Editor-only metadata and local preferences
  • +
+ +
+ Important: do not move UI state or source-file IO details into the shared core. + Those will create coupling fast and usually provide very little reuse value. +
+
+ +
+

The Boundary To Protect

+

+ The shared core should describe what the authored thing is. The runtime should decide + how that thing becomes executable ECS state. +

+ +
+
+

Good Core Concepts

+
    +
  • EntityTemplate
  • +
  • PlacedEntity
  • +
  • ArchetypeId
  • +
  • BehaviorId
  • +
  • StatBlock
  • +
  • SpawnRule
  • +
  • VisualRef
  • +
+
+
+

Bad Core Concepts

+
    +
  • GridPosition typed arrays
  • +
  • RenderPosition
  • +
  • Target.active
  • +
  • Planner handles
  • +
  • Sprite instances
  • +
  • Route caches
  • +
  • Per-frame live ECS state
  • +
+
+
+ +
The bridge: authored data into runtime assembly// Shared core
+export interface EntityTemplate {
+  id: EntityTemplateId;
+  archetype: ArchetypeId;
+  spriteId?: SpriteId;
+  stats?: StatBlock;
+  dialogueId?: DialogueId;
+}
+
+// Runtime
+export function materializeEntity(
+  world: GameWorld,
+  entity: ResolvedPlacedEntity,
+): number {
+  switch (entity.archetype) {
+    case "friendly_npc":
+      return spawnFriendlyNpc(world, entity);
+    case "monster":
+      return spawnMonster(world, entity);
+    case "player_spawn":
+      return spawnPlayerMarker(world, entity);
+  }
+}
+
+ +
+

Tempting, But Usually Not Worth Sharing

+
+
Raw file IO: how a TS file is discovered, parsed, rewritten, and formatted should usually stay editor-side or build-side.
+
React components: UI does not become more reusable just because it sits in a shared package.
+
Pixi renderer code: renderer concerns are runtime concerns.
+
ECS storage: component arrays and world memory layout are engine implementation details.
+
Editor state: selections, panels, and tool modes are not game-domain concepts.
+
Live save-state internals: runtime persistence format may overlap with content, but live simulation state should stay runtime-owned.
+
+
+ +
+

Suggested Package Shape

+
A practical next-step layoutpackages/
+  world-core/
+    src/
+      ids/
+      content/
+      define/
+      validate/
+      normalize/
+      migrate/
+      resolve/
+      rules/
+      registry/
+
+  world-content-build/
+    src/
+      loadTsModules/
+      compileBundle/
+      emitArtifacts/
+
+Worldshaper/
+  src/
+    editor-ui/
+    source-editing/
+    tooling/
+
+World-Workshop/
+  src/
+    game/
+      ecs/
+      systems/
+      runtime/
+      rendering/
+      assembly/
+
+ +
+

Low-Risk Extraction Order

+
    +
  1. Extract IDs, record types, and defineX() helpers.
  2. +
  3. Extract validation, normalization, and migrations.
  4. +
  5. Extract reference resolution and a shared content registry.
  6. +
  7. Extract pure rules used by both projects.
  8. +
  9. Leave ECS assembly, rendering, and editor source-editing mechanics where they are.
  10. +
+ +
+ Why this order works: it gives immediate reuse and consistency without forcing an early, + risky merge of the two apps' most specialized code. +
+ + +
+
+ +