@sadhaka/loom-engine 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +344 -0
  3. package/dist/animation/animation-clip.d.ts +12 -0
  4. package/dist/animation/animation-clip.d.ts.map +1 -0
  5. package/dist/animation/animation-clip.js +85 -0
  6. package/dist/animation/animation-clip.js.map +1 -0
  7. package/dist/animation/animation-state-pool.d.ts +25 -0
  8. package/dist/animation/animation-state-pool.d.ts.map +1 -0
  9. package/dist/animation/animation-state-pool.js +113 -0
  10. package/dist/animation/animation-state-pool.js.map +1 -0
  11. package/dist/asset/sprite-sheet-loader.d.ts +41 -0
  12. package/dist/asset/sprite-sheet-loader.d.ts.map +1 -0
  13. package/dist/asset/sprite-sheet-loader.js +313 -0
  14. package/dist/asset/sprite-sheet-loader.js.map +1 -0
  15. package/dist/audio/audio-bus.d.ts +43 -0
  16. package/dist/audio/audio-bus.d.ts.map +1 -0
  17. package/dist/audio/audio-bus.js +258 -0
  18. package/dist/audio/audio-bus.js.map +1 -0
  19. package/dist/combat/mob-catalog.d.ts +29 -0
  20. package/dist/combat/mob-catalog.d.ts.map +1 -0
  21. package/dist/combat/mob-catalog.js +104 -0
  22. package/dist/combat/mob-catalog.js.map +1 -0
  23. package/dist/components/health.d.ts +28 -0
  24. package/dist/components/health.d.ts.map +1 -0
  25. package/dist/components/health.js +150 -0
  26. package/dist/components/health.js.map +1 -0
  27. package/dist/components/interactable.d.ts +30 -0
  28. package/dist/components/interactable.d.ts.map +1 -0
  29. package/dist/components/interactable.js +94 -0
  30. package/dist/components/interactable.js.map +1 -0
  31. package/dist/components/particle-emitter.d.ts +62 -0
  32. package/dist/components/particle-emitter.d.ts.map +1 -0
  33. package/dist/components/particle-emitter.js +193 -0
  34. package/dist/components/particle-emitter.js.map +1 -0
  35. package/dist/components/pursue.d.ts +23 -0
  36. package/dist/components/pursue.d.ts.map +1 -0
  37. package/dist/components/pursue.js +96 -0
  38. package/dist/components/pursue.js.map +1 -0
  39. package/dist/components/ranged-attack.d.ts +44 -0
  40. package/dist/components/ranged-attack.d.ts.map +1 -0
  41. package/dist/components/ranged-attack.js +120 -0
  42. package/dist/components/ranged-attack.js.map +1 -0
  43. package/dist/components/sprite.d.ts +27 -0
  44. package/dist/components/sprite.d.ts.map +1 -0
  45. package/dist/components/sprite.js +122 -0
  46. package/dist/components/sprite.js.map +1 -0
  47. package/dist/components/transform.d.ts +30 -0
  48. package/dist/components/transform.d.ts.map +1 -0
  49. package/dist/components/transform.js +150 -0
  50. package/dist/components/transform.js.map +1 -0
  51. package/dist/director/director-bridge.d.ts +22 -0
  52. package/dist/director/director-bridge.d.ts.map +1 -0
  53. package/dist/director/director-bridge.js +23 -0
  54. package/dist/director/director-bridge.js.map +1 -0
  55. package/dist/director/director-encounter-system.d.ts +21 -0
  56. package/dist/director/director-encounter-system.d.ts.map +1 -0
  57. package/dist/director/director-encounter-system.js +128 -0
  58. package/dist/director/director-encounter-system.js.map +1 -0
  59. package/dist/director/director-system.d.ts +19 -0
  60. package/dist/director/director-system.d.ts.map +1 -0
  61. package/dist/director/director-system.js +179 -0
  62. package/dist/director/director-system.js.map +1 -0
  63. package/dist/director/event-envelope.d.ts +144 -0
  64. package/dist/director/event-envelope.d.ts.map +1 -0
  65. package/dist/director/event-envelope.js +108 -0
  66. package/dist/director/event-envelope.js.map +1 -0
  67. package/dist/director/knot-context-resource.d.ts +25 -0
  68. package/dist/director/knot-context-resource.d.ts.map +1 -0
  69. package/dist/director/knot-context-resource.js +152 -0
  70. package/dist/director/knot-context-resource.js.map +1 -0
  71. package/dist/director/mock-director-bridge.d.ts +18 -0
  72. package/dist/director/mock-director-bridge.d.ts.map +1 -0
  73. package/dist/director/mock-director-bridge.js +75 -0
  74. package/dist/director/mock-director-bridge.js.map +1 -0
  75. package/dist/director/snapshot-recovery.d.ts +37 -0
  76. package/dist/director/snapshot-recovery.d.ts.map +1 -0
  77. package/dist/director/snapshot-recovery.js +180 -0
  78. package/dist/director/snapshot-recovery.js.map +1 -0
  79. package/dist/director/sse-director-bridge.d.ts +42 -0
  80. package/dist/director/sse-director-bridge.d.ts.map +1 -0
  81. package/dist/director/sse-director-bridge.js +280 -0
  82. package/dist/director/sse-director-bridge.js.map +1 -0
  83. package/dist/engine.d.ts +25 -0
  84. package/dist/engine.d.ts.map +1 -0
  85. package/dist/engine.js +166 -0
  86. package/dist/engine.js.map +1 -0
  87. package/dist/entity.d.ts +17 -0
  88. package/dist/entity.d.ts.map +1 -0
  89. package/dist/entity.js +77 -0
  90. package/dist/entity.js.map +1 -0
  91. package/dist/index.d.ts +85 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +64 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/input/input-manager.d.ts +91 -0
  96. package/dist/input/input-manager.d.ts.map +1 -0
  97. package/dist/input/input-manager.js +349 -0
  98. package/dist/input/input-manager.js.map +1 -0
  99. package/dist/input/tap-to-walk.d.ts +27 -0
  100. package/dist/input/tap-to-walk.d.ts.map +1 -0
  101. package/dist/input/tap-to-walk.js +118 -0
  102. package/dist/input/tap-to-walk.js.map +1 -0
  103. package/dist/input/virtual-dpad.d.ts +34 -0
  104. package/dist/input/virtual-dpad.d.ts.map +1 -0
  105. package/dist/input/virtual-dpad.js +267 -0
  106. package/dist/input/virtual-dpad.js.map +1 -0
  107. package/dist/renderer/camera.d.ts +26 -0
  108. package/dist/renderer/camera.d.ts.map +1 -0
  109. package/dist/renderer/camera.js +39 -0
  110. package/dist/renderer/camera.js.map +1 -0
  111. package/dist/renderer/canvas2d-device.d.ts +26 -0
  112. package/dist/renderer/canvas2d-device.d.ts.map +1 -0
  113. package/dist/renderer/canvas2d-device.js +252 -0
  114. package/dist/renderer/canvas2d-device.js.map +1 -0
  115. package/dist/renderer/graphics-device.d.ts +36 -0
  116. package/dist/renderer/graphics-device.d.ts.map +1 -0
  117. package/dist/renderer/graphics-device.js +12 -0
  118. package/dist/renderer/graphics-device.js.map +1 -0
  119. package/dist/renderer/iso-projection.d.ts +11 -0
  120. package/dist/renderer/iso-projection.d.ts.map +1 -0
  121. package/dist/renderer/iso-projection.js +59 -0
  122. package/dist/renderer/iso-projection.js.map +1 -0
  123. package/dist/resources.d.ts +28 -0
  124. package/dist/resources.d.ts.map +1 -0
  125. package/dist/resources.js +53 -0
  126. package/dist/resources.js.map +1 -0
  127. package/dist/system.d.ts +14 -0
  128. package/dist/system.d.ts.map +1 -0
  129. package/dist/system.js +25 -0
  130. package/dist/system.js.map +1 -0
  131. package/dist/systems/animation-system.d.ts +8 -0
  132. package/dist/systems/animation-system.d.ts.map +1 -0
  133. package/dist/systems/animation-system.js +77 -0
  134. package/dist/systems/animation-system.js.map +1 -0
  135. package/dist/systems/attack-system.d.ts +17 -0
  136. package/dist/systems/attack-system.d.ts.map +1 -0
  137. package/dist/systems/attack-system.js +94 -0
  138. package/dist/systems/attack-system.js.map +1 -0
  139. package/dist/systems/damage-system.d.ts +18 -0
  140. package/dist/systems/damage-system.d.ts.map +1 -0
  141. package/dist/systems/damage-system.js +77 -0
  142. package/dist/systems/damage-system.js.map +1 -0
  143. package/dist/systems/input-system.d.ts +7 -0
  144. package/dist/systems/input-system.d.ts.map +1 -0
  145. package/dist/systems/input-system.js +27 -0
  146. package/dist/systems/input-system.js.map +1 -0
  147. package/dist/systems/interaction-system.d.ts +23 -0
  148. package/dist/systems/interaction-system.d.ts.map +1 -0
  149. package/dist/systems/interaction-system.js +120 -0
  150. package/dist/systems/interaction-system.js.map +1 -0
  151. package/dist/systems/particle-emitter-system.d.ts +8 -0
  152. package/dist/systems/particle-emitter-system.d.ts.map +1 -0
  153. package/dist/systems/particle-emitter-system.js +161 -0
  154. package/dist/systems/particle-emitter-system.js.map +1 -0
  155. package/dist/systems/particle-render-system.d.ts +7 -0
  156. package/dist/systems/particle-render-system.d.ts.map +1 -0
  157. package/dist/systems/particle-render-system.js +53 -0
  158. package/dist/systems/particle-render-system.js.map +1 -0
  159. package/dist/systems/particle-simulation-system.d.ts +8 -0
  160. package/dist/systems/particle-simulation-system.d.ts.map +1 -0
  161. package/dist/systems/particle-simulation-system.js +45 -0
  162. package/dist/systems/particle-simulation-system.js.map +1 -0
  163. package/dist/systems/projectile-render-system.d.ts +7 -0
  164. package/dist/systems/projectile-render-system.d.ts.map +1 -0
  165. package/dist/systems/projectile-render-system.js +35 -0
  166. package/dist/systems/projectile-render-system.js.map +1 -0
  167. package/dist/systems/projectile-system.d.ts +7 -0
  168. package/dist/systems/projectile-system.d.ts.map +1 -0
  169. package/dist/systems/projectile-system.js +114 -0
  170. package/dist/systems/projectile-system.js.map +1 -0
  171. package/dist/systems/pursue-system.d.ts +7 -0
  172. package/dist/systems/pursue-system.d.ts.map +1 -0
  173. package/dist/systems/pursue-system.js +83 -0
  174. package/dist/systems/pursue-system.js.map +1 -0
  175. package/dist/systems/ranged-attack-system.d.ts +7 -0
  176. package/dist/systems/ranged-attack-system.d.ts.map +1 -0
  177. package/dist/systems/ranged-attack-system.js +98 -0
  178. package/dist/systems/ranged-attack-system.js.map +1 -0
  179. package/dist/systems/sprite-render-system.d.ts +9 -0
  180. package/dist/systems/sprite-render-system.d.ts.map +1 -0
  181. package/dist/systems/sprite-render-system.js +108 -0
  182. package/dist/systems/sprite-render-system.js.map +1 -0
  183. package/dist/systems/veil-budget-system.d.ts +7 -0
  184. package/dist/systems/veil-budget-system.d.ts.map +1 -0
  185. package/dist/systems/veil-budget-system.js +37 -0
  186. package/dist/systems/veil-budget-system.js.map +1 -0
  187. package/dist/util/color.d.ts +19 -0
  188. package/dist/util/color.d.ts.map +1 -0
  189. package/dist/util/color.js +45 -0
  190. package/dist/util/color.js.map +1 -0
  191. package/dist/util/math.d.ts +26 -0
  192. package/dist/util/math.d.ts.map +1 -0
  193. package/dist/util/math.js +47 -0
  194. package/dist/util/math.js.map +1 -0
  195. package/dist/util/typed-arrays.d.ts +7 -0
  196. package/dist/util/typed-arrays.d.ts.map +1 -0
  197. package/dist/util/typed-arrays.js +42 -0
  198. package/dist/util/typed-arrays.js.map +1 -0
  199. package/dist/vfx/particle-pool.d.ts +61 -0
  200. package/dist/vfx/particle-pool.d.ts.map +1 -0
  201. package/dist/vfx/particle-pool.js +204 -0
  202. package/dist/vfx/particle-pool.js.map +1 -0
  203. package/dist/vfx/projectile-pool.d.ts +56 -0
  204. package/dist/vfx/projectile-pool.d.ts.map +1 -0
  205. package/dist/vfx/projectile-pool.js +157 -0
  206. package/dist/vfx/projectile-pool.js.map +1 -0
  207. package/dist/world.d.ts +23 -0
  208. package/dist/world.d.ts.map +1 -0
  209. package/dist/world.js +101 -0
  210. package/dist/world.js.map +1 -0
  211. package/dist/zone/zone-catalog.d.ts +17 -0
  212. package/dist/zone/zone-catalog.d.ts.map +1 -0
  213. package/dist/zone/zone-catalog.js +116 -0
  214. package/dist/zone/zone-catalog.js.map +1 -0
  215. package/dist/zone/zone-state.d.ts +18 -0
  216. package/dist/zone/zone-state.d.ts.map +1 -0
  217. package/dist/zone/zone-state.js +52 -0
  218. package/dist/zone/zone-state.js.map +1 -0
  219. package/package.json +56 -0
@@ -0,0 +1,23 @@
1
+ import { EntityAllocator, type EntityId } from './entity.js';
2
+ import { ResourceRegistry } from './resources.js';
3
+ import { type System, type SystemPhase } from './system.js';
4
+ export declare class World {
5
+ readonly entities: EntityAllocator;
6
+ readonly resources: ResourceRegistry;
7
+ private pools;
8
+ private systemsByPhase;
9
+ constructor();
10
+ registerPool<T>(key: string, pool: T): void;
11
+ getPool<T>(key: string): T | undefined;
12
+ requirePool<T>(key: string): T;
13
+ addSystem(system: System, phase?: SystemPhase): void;
14
+ update(dt: number): void;
15
+ countEntities(): number;
16
+ countSystems(): number;
17
+ countSystemsInPhase(phase: SystemPhase): number;
18
+ createEntity(): EntityId;
19
+ destroyEntity(e: EntityId): boolean;
20
+ }
21
+ export declare const POOL_TRANSFORM = "transform";
22
+ export declare const POOL_SPRITE = "sprite";
23
+ //# sourceMappingURL=world.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../src/world.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,KAAK,MAAM,EACX,KAAK,WAAW,EAGjB,MAAM,aAAa,CAAC;AAErB,qBAAa,KAAK;IAChB,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IAKrC,OAAO,CAAC,KAAK,CAAmC;IAIhD,OAAO,CAAC,cAAc,CAAyC;;IAY/D,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAI3C,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAItC,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC;IAU9B,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,WAAgC,GAAG,IAAI;IAUxE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAWxB,aAAa,IAAI,MAAM;IAIvB,YAAY,IAAI,MAAM;IAQtB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM;IAK/C,YAAY,IAAI,QAAQ;IAIxB,aAAa,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;CAGpC;AAKD,eAAO,MAAM,cAAc,cAAc,CAAC;AAC1C,eAAO,MAAM,WAAW,WAAW,CAAC"}
package/dist/world.js ADDED
@@ -0,0 +1,101 @@
1
+ // World - the ECS container for the Loom Engine.
2
+ //
3
+ // Holds:
4
+ // - EntityAllocator: 32-bit handle allocator
5
+ // - Component pools: registered by string key, opaque to the world
6
+ // - Systems: ordered by phase, run in registration order within
7
+ // a phase
8
+ // - Resources: singleton state (Time, Camera, Device, Input, RNG)
9
+ //
10
+ // Systems read/write pools + resources directly. The world doesn't
11
+ // dispatch queries; systems are responsible for knowing which pools
12
+ // they need.
13
+ //
14
+ // Inspiration:
15
+ // - PlayCanvas ECS shape (component-pool registration pattern)
16
+ // - Bevy ECS scheduling (Resource pattern, phase ordering)
17
+ // See PRIOR-ART.md.
18
+ import { EntityAllocator } from './entity.js';
19
+ import { ResourceRegistry } from './resources.js';
20
+ import { SYSTEM_PHASE_LOGIC, SYSTEM_PHASES_IN_ORDER, } from './system.js';
21
+ export class World {
22
+ entities;
23
+ resources;
24
+ // Component pools registered by string key. Opaque - the world
25
+ // never inspects them, just stores + hands back. Systems know what
26
+ // type each pool is (TransformPool, SpritePool, etc.).
27
+ pools = new Map();
28
+ // Systems indexed by phase. Within a phase, registration order is
29
+ // preserved (Map iteration is insertion-ordered for string keys).
30
+ systemsByPhase = new Map();
31
+ constructor() {
32
+ this.entities = new EntityAllocator();
33
+ this.resources = new ResourceRegistry();
34
+ for (const phase of SYSTEM_PHASES_IN_ORDER) {
35
+ this.systemsByPhase.set(phase, []);
36
+ }
37
+ }
38
+ // Component pool registration. The pool is whatever the caller
39
+ // passes; the world is just a typed Map under the hood.
40
+ registerPool(key, pool) {
41
+ this.pools.set(key, pool);
42
+ }
43
+ getPool(key) {
44
+ return this.pools.get(key);
45
+ }
46
+ requirePool(key) {
47
+ const v = this.pools.get(key);
48
+ if (v === undefined) {
49
+ throw new Error('World: required pool "' + key + '" not registered');
50
+ }
51
+ return v;
52
+ }
53
+ // System registration. Default phase is LOGIC; render systems
54
+ // pass SYSTEM_PHASE_RENDER explicitly.
55
+ addSystem(system, phase = SYSTEM_PHASE_LOGIC) {
56
+ const list = this.systemsByPhase.get(phase);
57
+ if (!list) {
58
+ // Phase not in SYSTEM_PHASES_IN_ORDER - guard rail.
59
+ throw new Error('World: unknown system phase ' + phase);
60
+ }
61
+ list.push(system);
62
+ }
63
+ // Run all systems in phase order. dt is seconds-since-last-tick.
64
+ update(dt) {
65
+ for (const phase of SYSTEM_PHASES_IN_ORDER) {
66
+ const list = this.systemsByPhase.get(phase);
67
+ if (!list)
68
+ continue;
69
+ for (const sys of list) {
70
+ sys.update(this, dt);
71
+ }
72
+ }
73
+ }
74
+ // Diagnostics.
75
+ countEntities() {
76
+ return this.entities.count();
77
+ }
78
+ countSystems() {
79
+ let total = 0;
80
+ for (const list of this.systemsByPhase.values()) {
81
+ total += list.length;
82
+ }
83
+ return total;
84
+ }
85
+ countSystemsInPhase(phase) {
86
+ return this.systemsByPhase.get(phase)?.length ?? 0;
87
+ }
88
+ // Convenience passthrough for the most common operation.
89
+ createEntity() {
90
+ return this.entities.create();
91
+ }
92
+ destroyEntity(e) {
93
+ return this.entities.destroy(e);
94
+ }
95
+ }
96
+ // Conventional pool keys. Systems and components use these to find
97
+ // each other so a pool registered as POOL_TRANSFORM is discoverable
98
+ // by any system that needs transforms.
99
+ export const POOL_TRANSFORM = 'transform';
100
+ export const POOL_SPRITE = 'sprite';
101
+ //# sourceMappingURL=world.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"world.js","sourceRoot":"","sources":["../src/world.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { ZoneId } from './zone-state.js';
2
+ import type { ColorRGBA } from '../util/color.js';
3
+ export interface ZoneTilePalette {
4
+ fill: Readonly<ColorRGBA>;
5
+ stroke: Readonly<ColorRGBA>;
6
+ highlight: Readonly<ColorRGBA>;
7
+ }
8
+ export interface ZoneCatalogEntry {
9
+ id: ZoneId;
10
+ name: string;
11
+ knot: 'str' | 'dex' | 'int' | 'mixed' | 'center';
12
+ palette: ZoneTilePalette;
13
+ musicLevel: number;
14
+ exits: ReadonlyArray<ZoneId>;
15
+ }
16
+ export declare const ZONE_CATALOG: Record<ZoneId, ZoneCatalogEntry>;
17
+ //# sourceMappingURL=zone-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zone-catalog.d.ts","sourceRoot":"","sources":["../../src/zone/zone-catalog.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,MAAM,WAAW,eAAe;IAE9B,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE1B,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE5B,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,MAAM,CAAC;IAIb,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IAGjD,OAAO,EAAE,eAAe,CAAC;IAGzB,UAAU,EAAE,MAAM,CAAC;IAGnB,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAiGzD,CAAC"}
@@ -0,0 +1,116 @@
1
+ // ZoneCatalog - data table of zone configurations.
2
+ //
3
+ // Each zone entry describes the rendering hints (tile palette, mood,
4
+ // ambient audio bus level), the NPCs that live there, and the
5
+ // connections to other zones. Phase 8 v1 ships 2 zones:
6
+ //
7
+ // lastlight_plaza - Act 1 convergence hub. Misha Dev greets the
8
+ // player. Portal connects to iron_reach.
9
+ // iron_reach - Strknot starter zone. Forge-city aesthetic,
10
+ // smoke-stained stone palette, no NPCs in v1
11
+ // beyond the return portal back to Plaza.
12
+ //
13
+ // Per LOOM-CLASS-SYSTEM-SPEC Section 3, the other 5 knot zones
14
+ // (saltsprig, the_archive, hammerwash, crystwell, forge_archive,
15
+ // centerknot_crossroads) get their own entries in subsequent
16
+ // sessions as the spec ships them.
17
+ import { hexToRgba } from '../util/color.js';
18
+ export const ZONE_CATALOG = {
19
+ lastlight_plaza: {
20
+ id: 'lastlight_plaza',
21
+ name: 'Lastlight Plaza',
22
+ knot: 'center',
23
+ palette: {
24
+ fill: hexToRgba(0x3a3a4e), // muted lavender-grey stone
25
+ stroke: hexToRgba(0x6a6a8a),
26
+ highlight: hexToRgba(0x9a9aba),
27
+ },
28
+ musicLevel: 0.6,
29
+ exits: ['iron_reach'],
30
+ },
31
+ iron_reach: {
32
+ id: 'iron_reach',
33
+ name: 'Iron Reach',
34
+ knot: 'str',
35
+ palette: {
36
+ fill: hexToRgba(0x4a2418), // smoke-stained brick
37
+ stroke: hexToRgba(0x804020),
38
+ highlight: hexToRgba(0xc06030),
39
+ },
40
+ musicLevel: 0.9,
41
+ exits: ['lastlight_plaza'],
42
+ },
43
+ saltsprig: {
44
+ id: 'saltsprig',
45
+ name: 'Saltsprig',
46
+ knot: 'dex',
47
+ palette: {
48
+ fill: hexToRgba(0x1a4a52),
49
+ stroke: hexToRgba(0x2a8c95),
50
+ highlight: hexToRgba(0x5ac9d6),
51
+ },
52
+ musicLevel: 0.7,
53
+ exits: ['lastlight_plaza'],
54
+ },
55
+ the_archive: {
56
+ id: 'the_archive',
57
+ name: 'The Archive',
58
+ knot: 'int',
59
+ palette: {
60
+ fill: hexToRgba(0x2a1a3a),
61
+ stroke: hexToRgba(0x603b91),
62
+ highlight: hexToRgba(0x9b5de5),
63
+ },
64
+ musicLevel: 0.5,
65
+ exits: ['lastlight_plaza'],
66
+ },
67
+ hammerwash: {
68
+ id: 'hammerwash',
69
+ name: 'Hammerwash',
70
+ knot: 'mixed',
71
+ palette: {
72
+ fill: hexToRgba(0x3a3030),
73
+ stroke: hexToRgba(0x5a4040),
74
+ highlight: hexToRgba(0xa07060),
75
+ },
76
+ musicLevel: 0.8,
77
+ exits: ['lastlight_plaza'],
78
+ },
79
+ crystwell: {
80
+ id: 'crystwell',
81
+ name: 'Crystwell',
82
+ knot: 'mixed',
83
+ palette: {
84
+ fill: hexToRgba(0x1a3a4a),
85
+ stroke: hexToRgba(0x456080),
86
+ highlight: hexToRgba(0x80a0c8),
87
+ },
88
+ musicLevel: 0.7,
89
+ exits: ['lastlight_plaza'],
90
+ },
91
+ forge_archive: {
92
+ id: 'forge_archive',
93
+ name: 'Forge-Archive',
94
+ knot: 'mixed',
95
+ palette: {
96
+ fill: hexToRgba(0x3a2030),
97
+ stroke: hexToRgba(0x6b3050),
98
+ highlight: hexToRgba(0xa86090),
99
+ },
100
+ musicLevel: 0.7,
101
+ exits: ['lastlight_plaza'],
102
+ },
103
+ centerknot_crossroads: {
104
+ id: 'centerknot_crossroads',
105
+ name: 'Centerknot Crossroads',
106
+ knot: 'center',
107
+ palette: {
108
+ fill: hexToRgba(0x2a2a30),
109
+ stroke: hexToRgba(0x6a6a40),
110
+ highlight: hexToRgba(0xffd86a),
111
+ },
112
+ musicLevel: 0.6,
113
+ exits: ['lastlight_plaza'],
114
+ },
115
+ };
116
+ //# sourceMappingURL=zone-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zone-catalog.js","sourceRoot":"","sources":["../../src/zone/zone-catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export type ZoneId = 'lastlight_plaza' | 'iron_reach' | 'saltsprig' | 'the_archive' | 'hammerwash' | 'crystwell' | 'forge_archive' | 'centerknot_crossroads';
2
+ export type TransitionKind = 'walk' | 'portal' | 'cinematic' | 'instant';
3
+ export interface ZoneStateResource {
4
+ activeZoneId: ZoneId;
5
+ transition: {
6
+ fromZoneId: ZoneId;
7
+ toZoneId: ZoneId;
8
+ kind: TransitionKind;
9
+ startMs: number;
10
+ durationMs: number;
11
+ } | null;
12
+ }
13
+ export declare function createZoneState(initial?: ZoneId): ZoneStateResource;
14
+ export declare function beginTransition(state: ZoneStateResource, toZoneId: ZoneId, kind: TransitionKind, durationMs: number, nowMs: number): boolean;
15
+ export declare function tickTransition(state: ZoneStateResource, nowMs: number): number;
16
+ export declare function isTransitioning(state: ZoneStateResource): boolean;
17
+ export declare const RESOURCE_ZONE_STATE = "zone_state";
18
+ //# sourceMappingURL=zone-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zone-state.d.ts","sourceRoot":"","sources":["../../src/zone/zone-state.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,MAAM,GACd,iBAAiB,GACjB,YAAY,GACZ,WAAW,GACX,aAAa,GACb,YAAY,GACZ,WAAW,GACX,eAAe,GACf,uBAAuB,CAAC;AAE5B,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,iBAAiB;IAEhC,YAAY,EAAE,MAAM,CAAC;IAGrB,UAAU,EAAE;QACV,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,cAAc,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;CACV;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,MAA0B,GAAG,iBAAiB,CAKtF;AAID,wBAAgB,eAAe,CAC7B,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAUT;AAMD,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAU9E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAEjE;AAED,eAAO,MAAM,mBAAmB,eAAe,CAAC"}
@@ -0,0 +1,52 @@
1
+ // ZoneState - resource tracking the active zone + transition state.
2
+ //
3
+ // Per LOOM-CLASS-SYSTEM-SPEC Section 3 the v1 ARPG ships with 7
4
+ // knot zones plus the Lastlight Plaza hub. The renderer holds one
5
+ // ZoneState resource that names the current zone and any in-progress
6
+ // transition. ZoneSystem applies scene.transition events from the
7
+ // Director (or local triggers in the demo) to mutate this resource.
8
+ //
9
+ // Render systems read activeZoneId to pick the appropriate tile
10
+ // atlas / palette / ambient audio. The Director-bridge populates
11
+ // scene.transition events when the player crosses portals.
12
+ export function createZoneState(initial = 'lastlight_plaza') {
13
+ return {
14
+ activeZoneId: initial,
15
+ transition: null,
16
+ };
17
+ }
18
+ // Begin a zone transition. Idempotent against the current zone (no-
19
+ // op if the from and to are the same).
20
+ export function beginTransition(state, toZoneId, kind, durationMs, nowMs) {
21
+ if (state.activeZoneId === toZoneId)
22
+ return false;
23
+ state.transition = {
24
+ fromZoneId: state.activeZoneId,
25
+ toZoneId,
26
+ kind,
27
+ startMs: nowMs,
28
+ durationMs: Math.max(1, durationMs),
29
+ };
30
+ return true;
31
+ }
32
+ // Tick the active transition. When the duration elapses, set
33
+ // activeZoneId to the target and clear the transition. Returns the
34
+ // transition progress in [0, 1] for renderer fades, or -1 if no
35
+ // transition is active.
36
+ export function tickTransition(state, nowMs) {
37
+ if (!state.transition)
38
+ return -1;
39
+ const t = state.transition;
40
+ const elapsed = nowMs - t.startMs;
41
+ if (elapsed >= t.durationMs) {
42
+ state.activeZoneId = t.toZoneId;
43
+ state.transition = null;
44
+ return 1;
45
+ }
46
+ return Math.max(0, elapsed / t.durationMs);
47
+ }
48
+ export function isTransitioning(state) {
49
+ return state.transition !== null;
50
+ }
51
+ export const RESOURCE_ZONE_STATE = 'zone_state';
52
+ //# sourceMappingURL=zone-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zone-state.js","sourceRoot":"","sources":["../../src/zone/zone-state.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,EAAE;AACF,gEAAgE;AAChE,kEAAkE;AAClE,qEAAqE;AACrE,kEAAkE;AAClE,oEAAoE;AACpE,EAAE;AACF,gEAAgE;AAChE,iEAAiE;AACjE,2DAA2D;AA4B3D,MAAM,UAAU,eAAe,CAAC,UAAkB,iBAAiB;IACjE,OAAO;QACL,YAAY,EAAE,OAAO;QACrB,UAAU,EAAE,IAAI;KACjB,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,uCAAuC;AACvC,MAAM,UAAU,eAAe,CAC7B,KAAwB,EACxB,QAAgB,EAChB,IAAoB,EACpB,UAAkB,EAClB,KAAa;IAEb,IAAI,KAAK,CAAC,YAAY,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClD,KAAK,CAAC,UAAU,GAAG;QACjB,UAAU,EAAE,KAAK,CAAC,YAAY;QAC9B,QAAQ;QACR,IAAI;QACJ,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC;KACpC,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6DAA6D;AAC7D,mEAAmE;AACnE,gEAAgE;AAChE,wBAAwB;AACxB,MAAM,UAAU,cAAc,CAAC,KAAwB,EAAE,KAAa;IACpE,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,OAAO,CAAC,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;IAC3B,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC;IAClC,IAAI,OAAO,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QAC5B,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,QAAQ,CAAC;QAChC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;QACxB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAwB;IACtD,OAAO,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@sadhaka/loom-engine",
3
+ "version": "0.10.0",
4
+ "description": "Browser-first 2D / 2.5D game engine. Canvas2D, ECS, render-graph stages, Director-bridge SSE integration. Built from scratch in TypeScript for TheWorldTable.ai.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "keywords": [
21
+ "game-engine",
22
+ "ecs",
23
+ "browser",
24
+ "typescript",
25
+ "isometric",
26
+ "sse",
27
+ "director-events"
28
+ ],
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/sadhaka/loom-engine"
32
+ },
33
+ "homepage": "https://loom-engine.pages.dev/",
34
+ "bugs": {
35
+ "url": "https://github.com/sadhaka/loom-engine/issues"
36
+ },
37
+ "scripts": {
38
+ "build": "tsc",
39
+ "build:demo": "tsc -p tsconfig.demo.json",
40
+ "build:all": "npm run build && npm run build:demo",
41
+ "watch": "tsc --watch",
42
+ "clean": "rm -rf dist demo/*.js demo/*.js.map",
43
+ "test": "tsx --test tests/smoke.test.ts tests/world.test.ts tests/asset-loader.test.ts tests/animation.test.ts tests/vfx.test.ts tests/audio-input.test.ts tests/director.test.ts tests/combat.test.ts tests/projectile.test.ts tests/arpg.test.ts tests/snapshot-recovery.test.ts tests/touch-input.test.ts",
44
+ "docs": "typedoc",
45
+ "docs:ci": "typedoc --out docs-build --cleanOutputDir",
46
+ "prepublishOnly": "npm test && npm run build"
47
+ },
48
+ "devDependencies": {
49
+ "tsx": "^4.19.0",
50
+ "typedoc": "^0.28.19",
51
+ "typedoc-plugin-markdown": "^4.11.0",
52
+ "typescript": "^5.4.0"
53
+ },
54
+ "license": "MIT",
55
+ "author": "Misha Mitiev"
56
+ }