@zylem/game-lib 0.5.1 → 0.6.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.
@@ -0,0 +1,28 @@
1
+ import { RigidBody, Collider, KinematicCharacterController } from '@dimforge/rapier3d-compat';
2
+ import { Group, Mesh } from 'three';
3
+
4
+ type LifecycleFunction<T> = (params?: any) => void;
5
+ interface Entity<T = any> {
6
+ setup: (entity: T) => void;
7
+ destroy: () => void;
8
+ update: LifecycleFunction<T>;
9
+ type: string;
10
+ _collision?: (entity: any, other: any, globals?: any) => void;
11
+ _destroy?: (globals?: any) => void;
12
+ name?: string;
13
+ tag?: Set<string>;
14
+ }
15
+ interface StageEntity extends Entity {
16
+ uuid: string;
17
+ body: RigidBody;
18
+ group: Group;
19
+ mesh: Mesh;
20
+ instanceId: number;
21
+ collider: Collider;
22
+ controlledRotation: boolean;
23
+ characterController: KinematicCharacterController;
24
+ name: string;
25
+ markedForRemoval: boolean;
26
+ }
27
+
28
+ export type { Entity as E, LifecycleFunction as L, StageEntity as S };
@@ -57,8 +57,8 @@ type LoadingEvent = {
57
57
  };
58
58
  interface IGame<TGlobals extends Record<string, unknown> = any> {
59
59
  start: () => Promise<this>;
60
- nextStage: () => Promise<void>;
61
- previousStage: () => Promise<void>;
60
+ nextStage: () => void;
61
+ previousStage: () => void;
62
62
  reset: () => Promise<void>;
63
63
  pause: () => Promise<void>;
64
64
  resume: () => Promise<void>;
@@ -140,6 +140,17 @@ interface NodeInterface {
140
140
  }
141
141
 
142
142
  type BaseNodeOptions<T = any> = BaseNode | Partial<T>;
143
+ /**
144
+ * Lifecycle callback arrays - each lifecycle event can have multiple callbacks
145
+ * that execute in order.
146
+ */
147
+ interface LifecycleCallbacks<T> {
148
+ setup: Array<SetupFunction<T>>;
149
+ loaded: Array<LoadedFunction<T>>;
150
+ update: Array<UpdateFunction<T>>;
151
+ destroy: Array<DestroyFunction<T>>;
152
+ cleanup: Array<CleanupFunction<T>>;
153
+ }
143
154
  declare abstract class BaseNode<Options = any, T = any> implements NodeInterface {
144
155
  protected parent: NodeInterface | null;
145
156
  protected children: NodeInterface[];
@@ -148,12 +159,39 @@ declare abstract class BaseNode<Options = any, T = any> implements NodeInterface
148
159
  uuid: string;
149
160
  name: string;
150
161
  markedForRemoval: boolean;
151
- setup: SetupFunction<this>;
152
- loaded: LoadedFunction<this>;
153
- update: UpdateFunction<this>;
154
- destroy: DestroyFunction<this>;
155
- cleanup: CleanupFunction<this>;
162
+ /**
163
+ * Lifecycle callback arrays - use onSetup(), onUpdate(), etc. to add callbacks
164
+ */
165
+ protected lifecycleCallbacks: LifecycleCallbacks<this>;
156
166
  constructor(args?: BaseNodeOptions[]);
167
+ /**
168
+ * Add setup callbacks to be executed in order during nodeSetup
169
+ */
170
+ onSetup(...callbacks: Array<SetupFunction<this>>): this;
171
+ /**
172
+ * Add loaded callbacks to be executed in order during nodeLoaded
173
+ */
174
+ onLoaded(...callbacks: Array<LoadedFunction<this>>): this;
175
+ /**
176
+ * Add update callbacks to be executed in order during nodeUpdate
177
+ */
178
+ onUpdate(...callbacks: Array<UpdateFunction<this>>): this;
179
+ /**
180
+ * Add destroy callbacks to be executed in order during nodeDestroy
181
+ */
182
+ onDestroy(...callbacks: Array<DestroyFunction<this>>): this;
183
+ /**
184
+ * Add cleanup callbacks to be executed in order during nodeCleanup
185
+ */
186
+ onCleanup(...callbacks: Array<CleanupFunction<this>>): this;
187
+ /**
188
+ * Prepend setup callbacks (run before existing ones)
189
+ */
190
+ prependSetup(...callbacks: Array<SetupFunction<this>>): this;
191
+ /**
192
+ * Prepend update callbacks (run before existing ones)
193
+ */
194
+ prependUpdate(...callbacks: Array<UpdateFunction<this>>): this;
157
195
  setParent(parent: NodeInterface | null): void;
158
196
  getParent(): NodeInterface | null;
159
197
  add(baseNode: NodeInterface): void;
@@ -169,6 +207,8 @@ declare abstract class BaseNode<Options = any, T = any> implements NodeInterface
169
207
  nodeSetup(params: SetupContext<this>): void;
170
208
  nodeUpdate(params: UpdateContext<this>): void;
171
209
  nodeDestroy(params: DestroyContext<this>): void;
210
+ nodeLoaded(params: LoadedContext<this>): Promise<void>;
211
+ nodeCleanup(params: CleanupContext<this>): Promise<void>;
172
212
  getOptions(): Options;
173
213
  setOptions(options: Partial<Options>): void;
174
214
  }
@@ -204,15 +244,17 @@ declare class MaterialBuilder {
204
244
  setShader(customShader: ZylemShaderType): void;
205
245
  }
206
246
 
247
+ /**
248
+ * Options for configuring entity collision behavior.
249
+ */
207
250
  interface CollisionOptions {
208
251
  static?: boolean;
209
252
  sensor?: boolean;
210
- size?: Vector3;
211
- position?: Vector3;
253
+ size?: Vector3$1;
254
+ position?: Vector3$1;
212
255
  collisionType?: string;
213
256
  collisionFilter?: string[];
214
257
  }
215
-
216
258
  declare class CollisionBuilder {
217
259
  static: boolean;
218
260
  sensor: boolean;
@@ -255,11 +297,6 @@ interface Behavior {
255
297
  values: any;
256
298
  }
257
299
 
258
- interface LifeCycleDelegate<U> {
259
- setup?: ((params: SetupContext<U>) => void)[];
260
- update?: ((params: UpdateContext<U>) => void)[];
261
- destroy?: ((params: DestroyContext<U>) => void)[];
262
- }
263
300
  interface CollisionContext<T, O extends GameEntityOptions, TGlobals extends Record<string, unknown> = any> {
264
301
  entity: T;
265
302
  other: GameEntity<O>;
@@ -316,19 +353,30 @@ declare class GameEntity<O extends GameEntityOptions> extends BaseNode<O> implem
316
353
  custom: Record<string, any>;
317
354
  debugInfo: Record<string, any>;
318
355
  debugMaterial: ShaderMaterial | undefined;
319
- lifeCycleDelegate: LifeCycleDelegate<O>;
320
356
  collisionDelegate: CollisionDelegate<this, O>;
321
357
  collisionType?: string;
322
358
  behaviorCallbackMap: Record<BehaviorCallbackType, BehaviorCallback<this, O>[]>;
323
359
  constructor();
324
360
  create(): this;
325
- onSetup(...callbacks: ((params: SetupContext<this>) => void)[]): this;
326
- onUpdate(...callbacks: ((params: UpdateContext<this>) => void)[]): this;
327
- onDestroy(...callbacks: ((params: DestroyContext<this>) => void)[]): this;
361
+ /**
362
+ * Add collision callbacks
363
+ */
328
364
  onCollision(...callbacks: ((params: CollisionContext<this, O>) => void)[]): this;
365
+ /**
366
+ * Entity-specific setup - runs behavior callbacks
367
+ * (User callbacks are handled by BaseNode's lifecycleCallbacks.setup)
368
+ */
329
369
  _setup(params: SetupContext<this>): void;
330
370
  protected _loaded(_params: LoadedContext<this>): Promise<void>;
371
+ /**
372
+ * Entity-specific update - updates materials and runs behavior callbacks
373
+ * (User callbacks are handled by BaseNode's lifecycleCallbacks.update)
374
+ */
331
375
  _update(params: UpdateContext<this>): void;
376
+ /**
377
+ * Entity-specific destroy - runs behavior callbacks
378
+ * (User callbacks are handled by BaseNode's lifecycleCallbacks.destroy)
379
+ */
332
380
  _destroy(params: DestroyContext<this>): void;
333
381
  protected _cleanup(_params: CleanupContext<this>): Promise<void>;
334
382
  _collision(other: GameEntity<O>, globals?: any): void;
@@ -344,4 +392,4 @@ declare class GameEntity<O extends GameEntityOptions> extends BaseNode<O> implem
344
392
  buildInfo(): Record<string, string>;
345
393
  }
346
394
 
347
- export { type AnalogState as A, type BehaviorCallbackType as B, type CleanupContext as C, type DestroyFunction as D, GameEntity as G, type InputGamepad as I, type LoadingEvent as L, type MaterialOptions as M, type SetupFunction as S, type TexturePath as T, type UpdateContext as U, type Vec3 as V, type Behavior as a, type UpdateFunction as b, type SetupContext as c, type DestroyContext as d, BaseNode as e, type InputPlayerNumber as f, type Inputs as g, type ButtonState as h, GameEntityLifeCycle as i, type IGame as j, type LoadedContext as k, type GameEntityOptions as l, type CollisionContext as m };
395
+ export { type AnalogState as A, type BehaviorCallbackType as B, type CleanupContext as C, type DestroyFunction as D, GameEntity as G, type InputGamepad as I, type LoadingEvent as L, type MaterialOptions as M, type SetupContext as S, type TexturePath as T, type UpdateContext as U, type Vec3 as V, type Behavior as a, type SetupFunction as b, type UpdateFunction as c, type DestroyContext as d, BaseNode as e, type InputPlayerNumber as f, type Inputs as g, type ButtonState as h, GameEntityLifeCycle as i, type IGame as j, type LoadedContext as k, type GameEntityOptions as l, type CollisionContext as m };
package/dist/main.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- import { G as Game } from './core-C2mjetAd.js';
2
- export { V as Vect3, Z as ZylemGameConfig, c as createGame, g as gameConfig, a as globalChange, b as globalChanges, d as variableChange, e as variableChanges, v as vessel } from './core-C2mjetAd.js';
3
- export { S as StageOptions, c as createStage } from './stage-CrmY7V0i.js';
4
- export { e as entitySpawner } from './entity-spawner-DNnLYnZq.js';
5
- export { P as PerspectiveType, a as Perspectives, c as camera } from './camera-Dk-fOVZE.js';
6
- export { ZylemBox, actor, box, plane, rect, sphere, sprite, text, zone } from './entities.js';
7
- import { U as UpdateContext, B as BehaviorCallbackType } from './entity-bQElAdpo.js';
8
- export { a as Behavior, L as LoadingEvent } from './entity-bQElAdpo.js';
1
+ import { G as Game } from './core-CZhozNRH.js';
2
+ export { V as Vect3, Z as ZylemGameConfig, c as createGame, g as gameConfig, a as globalChange, b as globalChanges, d as variableChange, e as variableChanges, v as vessel } from './core-CZhozNRH.js';
3
+ export { a as StageOptions, c as createStage } from './stage-types-CD21XoIU.js';
4
+ import { S as StageBlueprint } from './blueprints-BOCc3Wve.js';
5
+ export { e as entitySpawner } from './blueprints-BOCc3Wve.js';
6
+ export { P as PerspectiveType, a as Perspectives, c as camera } from './camera-CpbDr4-V.js';
7
+ export { A as ACTOR_TYPE, B as BOX_TYPE, P as PLANE_TYPE, R as RECT_TYPE, d as SPHERE_TYPE, S as SPRITE_TYPE, T as TEXT_TYPE, e as ZONE_TYPE, Z as ZylemBox, c as actor, b as box, p as plane, r as rect, s as sphere, a as sprite, t as text, z as zone } from './entities-BAxfJOkk.js';
8
+ import { U as UpdateContext, B as BehaviorCallbackType, G as GameEntity } from './entity-COvRtFNG.js';
9
+ export { a as Behavior, L as LoadingEvent, S as SetupContext } from './entity-COvRtFNG.js';
9
10
  export { boundary2d, ricochet2DCollision, ricochet2DInBounds } from './behaviors.js';
10
11
  import { M as MoveableEntity } from './moveable-B_vyA6cw.js';
11
12
  export { m as makeMoveable, b as move, a as moveable, r as resetVelocity } from './moveable-B_vyA6cw.js';
@@ -15,10 +16,40 @@ import * as three from 'three';
15
16
  export { three as THREE };
16
17
  import * as RAPIER from '@dimforge/rapier3d-compat';
17
18
  export { RAPIER };
19
+ export { S as StageEntity } from './entity-Bq_eNEDI.js';
18
20
  import 'bitecs';
19
- import 'three/addons/controls/OrbitControls.js';
21
+ import '@sinclair/typebox';
20
22
  import 'three/examples/jsm/postprocessing/EffectComposer.js';
21
23
 
24
+ declare const stageState: {
25
+ previous: StageBlueprint | null;
26
+ current: StageBlueprint | null;
27
+ next: StageBlueprint | null;
28
+ isLoading: boolean;
29
+ };
30
+ declare const StageManager: {
31
+ staticRegistry: Map<string, {
32
+ name?: string | undefined;
33
+ assets?: string[] | undefined;
34
+ id: string;
35
+ entities: {
36
+ position?: [number, number] | undefined;
37
+ data?: {
38
+ [x: string]: any;
39
+ } | undefined;
40
+ id: string;
41
+ type: string;
42
+ }[];
43
+ }>;
44
+ registerStaticStage(id: string, blueprint: StageBlueprint): void;
45
+ loadStageData(stageId: string): Promise<StageBlueprint>;
46
+ transitionForward(nextStageId: string, loadStaticStage?: (id: string) => Promise<StageBlueprint>): Promise<void>;
47
+ /**
48
+ * Manually set the next stage to pre-load it.
49
+ */
50
+ preloadNext(stageId: string, loadStaticStage?: (id: string) => Promise<StageBlueprint>): Promise<void>;
51
+ };
52
+
22
53
  interface MovementSequence2DStep {
23
54
  name: string;
24
55
  moveX?: number;
@@ -54,6 +85,7 @@ declare function pingPongBeep(frequency?: number, duration?: number): void;
54
85
 
55
86
  /**
56
87
  * Set a global value by path.
88
+ * Emits a 'game:state:updated' event when the value changes.
57
89
  * @example setGlobal('score', 100)
58
90
  * @example setGlobal('player.health', 50)
59
91
  */
@@ -74,14 +106,15 @@ declare function createGlobal<T>(path: string, defaultValue: T): T;
74
106
  declare function getGlobal<T = unknown>(path: string): T | undefined;
75
107
  /**
76
108
  * Subscribe to changes on a global value at a specific path.
77
- * Returns an unsubscribe function.
109
+ * Returns an unsubscribe function. Subscriptions are automatically
110
+ * cleaned up when the game is disposed.
78
111
  * @example const unsub = onGlobalChange('score', (val) => console.log(val));
79
112
  */
80
113
  declare function onGlobalChange<T = unknown>(path: string, callback: (value: T) => void): () => void;
81
114
  /**
82
115
  * Subscribe to changes on multiple global paths.
83
116
  * Callback fires when any of the paths change, receiving all current values.
84
- * Returns an unsubscribe function.
117
+ * Subscriptions are automatically cleaned up when the game is disposed.
85
118
  * @example const unsub = onGlobalChanges(['score', 'lives'], ([score, lives]) => console.log(score, lives));
86
119
  */
87
120
  declare function onGlobalChanges<T extends unknown[] = unknown[]>(paths: string[], callback: (values: T) => void): () => void;
@@ -89,6 +122,11 @@ declare function onGlobalChanges<T extends unknown[] = unknown[]>(paths: string[
89
122
  * Get the entire globals object (read-only snapshot).
90
123
  */
91
124
  declare function getGlobals<T = Record<string, unknown>>(): T;
125
+ /**
126
+ * Unsubscribe all active global subscriptions.
127
+ * Used internally on game dispose to prevent old callbacks from firing.
128
+ */
129
+ declare function clearGlobalSubscriptions(): void;
92
130
 
93
131
  /**
94
132
  * Set a variable on an object by path.
@@ -123,13 +161,51 @@ declare function onVariableChange<T = unknown>(target: object, path: string, cal
123
161
  */
124
162
  declare function onVariableChanges<T extends unknown[] = unknown[]>(target: object, paths: string[], callback: (values: T) => void): () => void;
125
163
 
164
+ type DebugTools = 'select' | 'translate' | 'rotate' | 'scale' | 'delete' | 'none';
165
+ interface DebugState {
166
+ enabled: boolean;
167
+ paused: boolean;
168
+ tool: DebugTools;
169
+ selectedEntity: GameEntity<any> | null;
170
+ hoveredEntity: GameEntity<any> | null;
171
+ flags: Set<string>;
172
+ }
173
+ declare const debugState: DebugState;
174
+ declare function setPaused(paused: boolean): void;
175
+ declare function setDebugTool(tool: DebugTools): void;
176
+
177
+ /**
178
+ * State interface for editor-to-game communication
179
+ */
180
+ interface ZylemGameState {
181
+ gameState?: {
182
+ debugFlag?: boolean;
183
+ [key: string]: unknown;
184
+ };
185
+ toolbarState?: {
186
+ tool?: DebugTools;
187
+ paused?: boolean;
188
+ };
189
+ [key: string]: unknown;
190
+ }
126
191
  declare class ZylemGameElement extends HTMLElement {
127
192
  private _game;
193
+ private _state;
128
194
  private container;
129
195
  constructor();
130
196
  set game(game: Game<any>);
131
197
  get game(): Game<any> | null;
198
+ set state(value: ZylemGameState);
199
+ get state(): ZylemGameState;
200
+ /**
201
+ * Sync the web component's state with the game-lib's internal debug state
202
+ */
203
+ private syncDebugState;
204
+ /**
205
+ * Sync toolbar state with game-lib's debug state
206
+ */
207
+ private syncToolbarState;
132
208
  disconnectedCallback(): void;
133
209
  }
134
210
 
135
- export { Game, ZylemGameElement, createGlobal, createVariable, destroy, getGlobal, getGlobals, getVariable, movementSequence2D, onGlobalChange, onGlobalChanges, onVariableChange, onVariableChanges, pingPongBeep, ricochetSound, setGlobal, setVariable };
211
+ export { type DebugTools, Game, StageBlueprint, StageManager, UpdateContext, ZylemGameElement, type ZylemGameState, clearGlobalSubscriptions, createGlobal, createVariable, debugState, destroy, getGlobal, getGlobals, getVariable, movementSequence2D, onGlobalChange, onGlobalChanges, onVariableChange, onVariableChanges, pingPongBeep, ricochetSound, setDebugTool, setGlobal, setPaused, setVariable, stageState };