dacha 0.18.0-alpha.8 → 0.18.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 (110) hide show
  1. package/build/contrib/components/index.d.ts +1 -0
  2. package/build/contrib/components/index.js +1 -0
  3. package/build/contrib/components/interpolation/index.d.ts +85 -0
  4. package/build/contrib/components/interpolation/index.js +101 -0
  5. package/build/contrib/components/rigid-body/index.d.ts +108 -14
  6. package/build/contrib/components/rigid-body/index.js +191 -22
  7. package/build/contrib/systems/animator/index.d.ts +3 -2
  8. package/build/contrib/systems/animator/index.js +6 -3
  9. package/build/contrib/systems/behavior-system/system.d.ts +4 -2
  10. package/build/contrib/systems/behavior-system/system.js +11 -3
  11. package/build/contrib/systems/behavior-system/types.d.ts +7 -10
  12. package/build/contrib/systems/character-controller/index.d.ts +4 -2
  13. package/build/contrib/systems/character-controller/index.js +22 -17
  14. package/build/contrib/systems/character-controller/one-way-validator.d.ts +15 -0
  15. package/build/contrib/systems/character-controller/one-way-validator.js +73 -0
  16. package/build/contrib/systems/game-stats-meter/index.d.ts +4 -3
  17. package/build/contrib/systems/game-stats-meter/index.js +11 -10
  18. package/build/contrib/systems/index.d.ts +2 -0
  19. package/build/contrib/systems/index.js +1 -0
  20. package/build/contrib/systems/interpolator/api.d.ts +40 -0
  21. package/build/contrib/systems/interpolator/api.js +70 -0
  22. package/build/contrib/systems/interpolator/index.d.ts +3 -0
  23. package/build/contrib/systems/interpolator/index.js +2 -0
  24. package/build/contrib/systems/interpolator/system.d.ts +31 -0
  25. package/build/contrib/systems/interpolator/system.js +96 -0
  26. package/build/contrib/systems/interpolator/tests/helpers.d.ts +13 -0
  27. package/build/contrib/systems/interpolator/tests/helpers.js +45 -0
  28. package/build/contrib/systems/interpolator/utils.d.ts +5 -0
  29. package/build/contrib/systems/interpolator/utils.js +41 -0
  30. package/build/contrib/systems/physics-system/api.d.ts +45 -1
  31. package/build/contrib/systems/physics-system/api.js +49 -0
  32. package/build/contrib/systems/physics-system/consts.d.ts +13 -0
  33. package/build/contrib/systems/physics-system/consts.js +17 -0
  34. package/build/contrib/systems/physics-system/physics-system.d.ts +2 -2
  35. package/build/contrib/systems/physics-system/physics-system.js +24 -4
  36. package/build/contrib/systems/physics-system/subsystems/collision-detection/dynamic-aabb-tree/index.d.ts +1 -1
  37. package/build/contrib/systems/physics-system/subsystems/collision-detection/dynamic-aabb-tree/index.js +21 -15
  38. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.d.ts +11 -11
  39. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +133 -125
  40. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/check-boxes-intersection.js +5 -3
  41. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/utils.d.ts +1 -0
  42. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/utils.js +2 -1
  43. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-capsule/check-box-and-capsule-intersection.js +4 -1
  44. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/check-box-and-segment-intersection.js +4 -2
  45. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/common/points.d.ts +2 -0
  46. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/common/points.js +16 -0
  47. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/index.js +2 -0
  48. package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/tests/helpers.js +3 -14
  49. package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.d.ts +5 -0
  50. package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.js +97 -81
  51. package/build/contrib/systems/physics-system/subsystems/collision-detection/shape-cast-checkers/tests/helpers.js +2 -7
  52. package/build/contrib/systems/physics-system/subsystems/collision-detection/tests/assertions.d.ts +1 -0
  53. package/build/contrib/systems/physics-system/subsystems/collision-detection/tests/assertions.js +7 -0
  54. package/build/contrib/systems/physics-system/subsystems/collision-detection/types.d.ts +0 -15
  55. package/build/contrib/systems/physics-system/subsystems/collision-detection/utils.d.ts +3 -0
  56. package/build/contrib/systems/physics-system/subsystems/collision-detection/utils.js +9 -0
  57. package/build/contrib/systems/physics-system/subsystems/constraint-solver/contact-state-manager.d.ts +63 -0
  58. package/build/contrib/systems/physics-system/subsystems/constraint-solver/contact-state-manager.js +170 -0
  59. package/build/contrib/systems/physics-system/subsystems/constraint-solver/contact-utils.d.ts +5 -0
  60. package/build/contrib/systems/physics-system/subsystems/constraint-solver/contact-utils.js +41 -0
  61. package/build/contrib/systems/physics-system/subsystems/constraint-solver/impulse-utils.d.ts +16 -0
  62. package/build/contrib/systems/physics-system/subsystems/constraint-solver/impulse-utils.js +77 -0
  63. package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.d.ts +53 -4
  64. package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.js +334 -116
  65. package/build/contrib/systems/physics-system/subsystems/constraint-solver/one-way-validator.d.ts +11 -0
  66. package/build/contrib/{utils → systems/physics-system/subsystems/constraint-solver}/one-way-validator.js +22 -25
  67. package/build/contrib/systems/physics-system/subsystems/constraint-solver/sleep-support-tracker.d.ts +13 -0
  68. package/build/contrib/systems/physics-system/subsystems/constraint-solver/sleep-support-tracker.js +42 -0
  69. package/build/contrib/systems/physics-system/subsystems/constraint-solver/tests/helpers.d.ts +4 -0
  70. package/build/contrib/systems/physics-system/subsystems/constraint-solver/tests/helpers.js +20 -0
  71. package/build/contrib/systems/physics-system/subsystems/physics/index.d.ts +15 -4
  72. package/build/contrib/systems/physics-system/subsystems/physics/index.js +131 -53
  73. package/build/contrib/systems/physics-system/subsystems/physics/mass-properties.d.ts +2 -0
  74. package/build/contrib/systems/physics-system/subsystems/physics/mass-properties.js +55 -0
  75. package/build/contrib/systems/physics-system/tests/helpers.d.ts +5 -2
  76. package/build/contrib/systems/physics-system/tests/helpers.js +11 -2
  77. package/build/contrib/systems/physics-system/types.d.ts +18 -2
  78. package/build/contrib/systems/renderer/actor-render-tree.js +15 -6
  79. package/build/contrib/systems/renderer/filters/index.d.ts +1 -1
  80. package/build/contrib/systems/renderer/filters/index.js +1 -1
  81. package/build/contrib/systems/renderer/material/index.d.ts +2 -1
  82. package/build/contrib/systems/renderer/material/index.js +1 -1
  83. package/build/contrib/systems/renderer/renderer.d.ts +2 -2
  84. package/build/contrib/systems/renderer/renderer.js +3 -4
  85. package/build/contrib/systems/renderer/types.d.ts +0 -3
  86. package/build/engine/data-lib/index.d.ts +1 -1
  87. package/build/engine/data-lib/index.js +1 -1
  88. package/build/engine/data-lib/pool.d.ts +9 -0
  89. package/build/engine/data-lib/pool.js +19 -0
  90. package/build/engine/engine.js +4 -1
  91. package/build/engine/game-loop.d.ts +3 -1
  92. package/build/engine/game-loop.js +11 -8
  93. package/build/engine/math-lib/math/ops.d.ts +16 -0
  94. package/build/engine/math-lib/math/ops.js +25 -0
  95. package/build/engine/scene/scene-manager.d.ts +4 -1
  96. package/build/engine/scene/scene-manager.js +5 -1
  97. package/build/engine/system/index.d.ts +1 -1
  98. package/build/engine/system/system.d.ts +10 -11
  99. package/build/engine/system/system.js +5 -2
  100. package/build/engine/time.d.ts +54 -0
  101. package/build/engine/time.js +77 -0
  102. package/build/index.d.ts +2 -1
  103. package/package.json +1 -1
  104. package/build/contrib/systems/physics-system/subsystems/collision-detection/dispersion-calculator/index.d.ts +0 -11
  105. package/build/contrib/systems/physics-system/subsystems/collision-detection/dispersion-calculator/index.js +0 -41
  106. package/build/contrib/utils/one-way-validator.d.ts +0 -12
  107. package/build/engine/data-lib/sort/index.d.ts +0 -1
  108. package/build/engine/data-lib/sort/index.js +0 -1
  109. package/build/engine/data-lib/sort/insertion-sort.d.ts +0 -1
  110. package/build/engine/data-lib/sort/insertion-sort.js +0 -14
@@ -1,4 +1,5 @@
1
- import type { ViewComponent, Time } from '../types';
1
+ import type { Time } from '../../../../engine/time';
2
+ import type { ViewComponent } from '../types';
2
3
  import type { ShaderConstructor, MaterialConfig } from './shader';
3
4
  interface MaterialSystemOptions {
4
5
  shaders?: ShaderConstructor[];
@@ -68,7 +68,7 @@ export class MaterialSystem {
68
68
  meta.materialSampler = view.texture.source;
69
69
  view.shader.resources.uSampler = view.texture.source;
70
70
  }
71
- view.shader.resources.uniformsGroup.uniforms.uTime = this.time.elapsed;
71
+ view.shader.resources.uniformsGroup.uniforms.uTime = this.time.elapsedTime;
72
72
  view.shader.resources.uniformsGroup.uniforms.uAlpha =
73
73
  view.getGlobalAlpha(true);
74
74
  const tint = view.getGlobalTint(true);
@@ -1,4 +1,4 @@
1
- import { WorldSystem, type WorldSystemOptions, type UpdateOptions } from '../../../engine/system';
1
+ import { WorldSystem, type WorldSystemOptions } from '../../../engine/system';
2
2
  import { type Scene } from '../../../engine/scene';
3
3
  /**
4
4
  * Renderer system that manages 2D graphics rendering using PIXI.js under the hood
@@ -30,5 +30,5 @@ export declare class Renderer extends WorldSystem {
30
30
  onSceneExit(): void;
31
31
  onSceneDestroy(scene: Scene): void;
32
32
  private updateCamera;
33
- update(options: UpdateOptions): void;
33
+ update(): void;
34
34
  }
@@ -36,7 +36,8 @@ export class Renderer extends WorldSystem {
36
36
  rendererApi;
37
37
  constructor(options) {
38
38
  super();
39
- const { globalOptions, windowNodeId, backgroundColor, templateCollection, world, resources, filterEffects, } = options;
39
+ const { globalOptions, windowNodeId, backgroundColor, templateCollection, world, resources, filterEffects, time, } = options;
40
+ this.time = time;
40
41
  this.backgroundColor = new Color(backgroundColor);
41
42
  this.window = getWindowNode(windowNodeId);
42
43
  this.resources = resources;
@@ -56,7 +57,6 @@ export class Renderer extends WorldSystem {
56
57
  this.application = new Application();
57
58
  this.worldContainer = new Container();
58
59
  this.assets = new Assets({ templateCollection });
59
- this.time = { elapsed: 0 };
60
60
  this.materialSystem = new MaterialSystem({
61
61
  shaders: this.resources?.shaders,
62
62
  time: this.time,
@@ -137,8 +137,7 @@ export class Renderer extends WorldSystem {
137
137
  this.worldContainer.position.set(this.application.renderer.width / 2, this.application.renderer.height / 2);
138
138
  this.worldContainer.pivot.set(x, y);
139
139
  }
140
- update(options) {
141
- this.time.elapsed += options.deltaTime / 1000;
140
+ update() {
142
141
  this.updateCamera();
143
142
  this.actorRenderTree?.update();
144
143
  this.filterSystem.update();
@@ -29,6 +29,3 @@ export interface RendererResources {
29
29
  filterEffects?: FilterEffectConstructor[];
30
30
  shaders?: ShaderConstructor[];
31
31
  }
32
- export interface Time {
33
- elapsed: number;
34
- }
@@ -1,3 +1,3 @@
1
1
  export { Queue } from './queue';
2
2
  export { CacheStore } from './cache-store';
3
- export { insertionSort } from './sort';
3
+ export { Pool } from './pool';
@@ -1,3 +1,3 @@
1
1
  export { Queue } from './queue';
2
2
  export { CacheStore } from './cache-store';
3
- export { insertionSort } from './sort';
3
+ export { Pool } from './pool';
@@ -0,0 +1,9 @@
1
+ export declare class Pool<T> {
2
+ private factory;
3
+ private reset?;
4
+ private items;
5
+ constructor(factory: () => T, reset?: ((item: T) => void) | undefined);
6
+ acquire(): T;
7
+ release(item: T): void;
8
+ clear(): void;
9
+ }
@@ -0,0 +1,19 @@
1
+ export class Pool {
2
+ factory;
3
+ reset;
4
+ items = [];
5
+ constructor(factory, reset) {
6
+ this.factory = factory;
7
+ this.reset = reset;
8
+ }
9
+ acquire() {
10
+ return this.items.pop() ?? this.factory();
11
+ }
12
+ release(item) {
13
+ this.reset?.(item);
14
+ this.items.push(item);
15
+ }
16
+ clear() {
17
+ this.items.length = 0;
18
+ }
19
+ }
@@ -1,6 +1,7 @@
1
1
  import { SceneManager } from './scene/scene-manager';
2
2
  import { TemplateCollection } from './template';
3
3
  import { GameLoop } from './game-loop';
4
+ import { Time } from './time';
4
5
  /**
5
6
  * Main game engine responsible for bootstrapping scenes and systems, managing the
6
7
  * game loop, and controlling lifecycle actions (play, pause, stop).
@@ -60,6 +61,7 @@ export class Engine {
60
61
  acc[option.name] = option.options;
61
62
  return acc;
62
63
  }, {});
64
+ const time = new Time();
63
65
  this.sceneManager = new SceneManager({
64
66
  sceneConfigs: scenes,
65
67
  systemConfigs: systems,
@@ -68,10 +70,11 @@ export class Engine {
68
70
  templateCollection,
69
71
  globalOptions,
70
72
  resources,
73
+ time,
71
74
  });
72
75
  await this.sceneManager.loadWorld();
73
76
  await this.sceneManager.loadScene(startSceneId, true);
74
- this.gameLoop = new GameLoop(this.sceneManager, globalOptions.performance);
77
+ this.gameLoop = new GameLoop(this.sceneManager, time, globalOptions.performance);
75
78
  this.gameLoop.run();
76
79
  }
77
80
  /**
@@ -1,4 +1,5 @@
1
1
  import type { SceneManager } from './scene';
2
+ import type { Time } from './time';
2
3
  export interface PerformanceSettings {
3
4
  maxFPS?: number;
4
5
  fixedUpdateRate?: number;
@@ -7,6 +8,7 @@ export interface PerformanceSettings {
7
8
  }
8
9
  export declare class GameLoop {
9
10
  private sceneManager;
11
+ private time;
10
12
  private msPerUpdate;
11
13
  private msPerFixedUpdate;
12
14
  private maxFrameDelta;
@@ -15,7 +17,7 @@ export declare class GameLoop {
15
17
  private previous;
16
18
  private lag;
17
19
  private bindedTick;
18
- constructor(sceneManager: SceneManager, performance?: PerformanceSettings);
20
+ constructor(sceneManager: SceneManager, time: Time, performance?: PerformanceSettings);
19
21
  private tick;
20
22
  run(): void;
21
23
  stop(): void;
@@ -2,6 +2,7 @@ import { eventQueue } from './event-target';
2
2
  import { DEFAULT_FIXED_UPDATE_RATE, DEFAULT_MAX_FPS, DEFAULT_MAX_FRAME_DELTA, DEFAULT_MAX_FIXED_UPDATES_PER_FRAME, } from './consts';
3
3
  export class GameLoop {
4
4
  sceneManager;
5
+ time;
5
6
  msPerUpdate;
6
7
  msPerFixedUpdate;
7
8
  maxFrameDelta;
@@ -10,8 +11,9 @@ export class GameLoop {
10
11
  previous;
11
12
  lag;
12
13
  bindedTick;
13
- constructor(sceneManager, performance) {
14
+ constructor(sceneManager, time, performance) {
14
15
  this.sceneManager = sceneManager;
16
+ this.time = time;
15
17
  this.msPerUpdate = 1000 / (performance?.maxFPS || DEFAULT_MAX_FPS);
16
18
  this.msPerFixedUpdate =
17
19
  1000 / (performance?.fixedUpdateRate || DEFAULT_FIXED_UPDATE_RATE);
@@ -19,27 +21,27 @@ export class GameLoop {
19
21
  this.maxFixedUpdatesPerFrame =
20
22
  performance?.maxFixedUpdatesPerFrame ||
21
23
  DEFAULT_MAX_FIXED_UPDATES_PER_FRAME;
24
+ this.time.fixedDeltaTime = this.msPerFixedUpdate / 1000;
22
25
  this.gameLoopId = 0;
23
26
  this.previous = 0;
24
27
  this.lag = 0;
25
28
  this.bindedTick = this.tick.bind(this);
26
29
  }
27
- tick() {
30
+ tick(timestamp) {
28
31
  this.gameLoopId = requestAnimationFrame(this.bindedTick);
29
- const current = performance.now();
30
- const elapsed = Math.min(current - this.previous, this.maxFrameDelta);
32
+ const current = timestamp;
33
+ const elapsed = Math.min(Math.max(current - this.previous, 0), this.maxFrameDelta);
31
34
  if (elapsed < this.msPerUpdate) {
32
35
  return;
33
36
  }
34
37
  this.lag += elapsed;
35
38
  eventQueue.update();
36
39
  const systems = this.sceneManager.getSystems();
37
- const fixedUpdateOptions = { deltaTime: this.msPerFixedUpdate };
38
40
  let fixedUpdates = 0;
39
41
  while (this.lag >= this.msPerFixedUpdate &&
40
42
  fixedUpdates < this.maxFixedUpdatesPerFrame) {
41
43
  systems.forEach((system) => {
42
- system.fixedUpdate?.(fixedUpdateOptions);
44
+ system.fixedUpdate?.();
43
45
  });
44
46
  this.lag -= this.msPerFixedUpdate;
45
47
  fixedUpdates += 1;
@@ -47,9 +49,9 @@ export class GameLoop {
47
49
  if (fixedUpdates === this.maxFixedUpdatesPerFrame) {
48
50
  this.lag = 0;
49
51
  }
50
- const options = { deltaTime: elapsed };
52
+ this.time._tick(elapsed / 1000, this.lag / this.msPerFixedUpdate);
51
53
  systems.forEach((system) => {
52
- system.update?.(options);
54
+ system.update?.();
53
55
  });
54
56
  if (this.msPerUpdate > 0) {
55
57
  this.previous = current - (elapsed % this.msPerUpdate);
@@ -64,6 +66,7 @@ export class GameLoop {
64
66
  }
65
67
  this.previous = performance.now();
66
68
  this.lag = 0;
69
+ this.time._reset();
67
70
  this.gameLoopId = requestAnimationFrame(this.bindedTick);
68
71
  }
69
72
  stop() {
@@ -118,4 +118,20 @@ export declare class MathOps {
118
118
  * ```
119
119
  */
120
120
  static clamp(value: number, min: number, max: number): number;
121
+ /**
122
+ * Signed shortest angular difference between two angles in radians
123
+ *
124
+ * The result is in (-PI, PI], so `from + delta` is angle-equivalent
125
+ * to `to` while rotating the short way around.
126
+ *
127
+ * @param from - Start angle in radians
128
+ * @param to - End angle in radians
129
+ * @returns Signed delta in radians
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * const delta = MathOps.getAngleDelta(3, -3); // ~0.283, crosses PI
134
+ * ```
135
+ */
136
+ static getAngleDelta(from: number, to: number): number;
121
137
  }
@@ -134,4 +134,29 @@ export class MathOps {
134
134
  }
135
135
  return value;
136
136
  }
137
+ /**
138
+ * Signed shortest angular difference between two angles in radians
139
+ *
140
+ * The result is in (-PI, PI], so `from + delta` is angle-equivalent
141
+ * to `to` while rotating the short way around.
142
+ *
143
+ * @param from - Start angle in radians
144
+ * @param to - End angle in radians
145
+ * @returns Signed delta in radians
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * const delta = MathOps.getAngleDelta(3, -3); // ~0.283, crosses PI
150
+ * ```
151
+ */
152
+ static getAngleDelta(from, to) {
153
+ let delta = (to - from) % (2 * Math.PI);
154
+ if (delta > Math.PI) {
155
+ delta -= 2 * Math.PI;
156
+ }
157
+ else if (delta <= -Math.PI) {
158
+ delta += 2 * Math.PI;
159
+ }
160
+ return delta;
161
+ }
137
162
  }
@@ -3,6 +3,7 @@ import type { ComponentConstructor } from '../component';
3
3
  import type { TemplateCollection } from '../template';
4
4
  import type { SystemConstructor } from '../system';
5
5
  import type { System } from '../system/system';
6
+ import type { Time } from '../time';
6
7
  import { Scene } from './scene';
7
8
  interface SceneManagerOptions {
8
9
  sceneConfigs: SceneConfig[];
@@ -12,6 +13,7 @@ interface SceneManagerOptions {
12
13
  templateCollection: TemplateCollection;
13
14
  globalOptions: Record<string, unknown>;
14
15
  resources: Record<string, unknown>;
16
+ time: Time;
15
17
  }
16
18
  export declare class SceneManager {
17
19
  private sceneConfigs;
@@ -20,13 +22,14 @@ export declare class SceneManager {
20
22
  private templateCollection;
21
23
  private globalOptions;
22
24
  private resources;
25
+ private time;
23
26
  private actorCreator;
24
27
  private actorSpawner;
25
28
  private world;
26
29
  private worldSystems;
27
30
  private loadedScenes;
28
31
  private activeSceneId?;
29
- constructor({ sceneConfigs, systemConfigs, availableSystems, components, templateCollection, globalOptions, resources, }: SceneManagerOptions);
32
+ constructor({ sceneConfigs, systemConfigs, availableSystems, components, templateCollection, globalOptions, resources, time, }: SceneManagerOptions);
30
33
  loadWorld(): Promise<void>;
31
34
  destroyWorld(): void;
32
35
  private handleLoadScene;
@@ -13,13 +13,14 @@ export class SceneManager {
13
13
  templateCollection;
14
14
  globalOptions;
15
15
  resources;
16
+ time;
16
17
  actorCreator;
17
18
  actorSpawner;
18
19
  world;
19
20
  worldSystems;
20
21
  loadedScenes;
21
22
  activeSceneId;
22
- constructor({ sceneConfigs, systemConfigs, availableSystems, components, templateCollection, globalOptions, resources, }) {
23
+ constructor({ sceneConfigs, systemConfigs, availableSystems, components, templateCollection, globalOptions, resources, time, }) {
23
24
  this.availableSystems = availableSystems.reduce((acc, AvailableSystem) => {
24
25
  acc[AvailableSystem.systemName] = AvailableSystem;
25
26
  return acc;
@@ -37,6 +38,7 @@ export class SceneManager {
37
38
  this.templateCollection = templateCollection;
38
39
  this.globalOptions = globalOptions;
39
40
  this.resources = resources;
41
+ this.time = time;
40
42
  this.actorCreator = new ActorCreator(components, templateCollection);
41
43
  this.actorSpawner = new ActorSpawner(this.actorCreator);
42
44
  this.world = new World({ id: uuid(), name: 'world' });
@@ -52,6 +54,7 @@ export class SceneManager {
52
54
  actorSpawner: this.actorSpawner,
53
55
  resources: this.resources[config.name],
54
56
  globalOptions: this.globalOptions,
57
+ time: this.time,
55
58
  world: this.world,
56
59
  };
57
60
  this.worldSystems.set(config.name, new SystemClass(options));
@@ -141,6 +144,7 @@ export class SceneManager {
141
144
  actorSpawner: this.actorSpawner,
142
145
  resources: this.resources[config.name],
143
146
  globalOptions: this.globalOptions,
147
+ time: this.time,
144
148
  scene,
145
149
  world: this.world,
146
150
  };
@@ -1,2 +1,2 @@
1
1
  export { SceneSystem, WorldSystem } from './system';
2
- export type { System, SystemConstructor, SceneSystemOptions, WorldSystemOptions, UpdateOptions, } from './system';
2
+ export type { System, SystemConstructor, SceneSystemOptions, WorldSystemOptions, } from './system';
@@ -6,6 +6,7 @@ import type { ActorSpawner } from '../actor';
6
6
  import type { TemplateCollection } from '../template';
7
7
  import type { Scene } from '../scene';
8
8
  import type { World } from '../world';
9
+ import type { Time } from '../time';
9
10
  import type { Constructor } from '../../types/utils';
10
11
  /**
11
12
  * Base options for all systems.
@@ -19,6 +20,8 @@ interface SystemOptions extends Record<string, unknown> {
19
20
  globalOptions: Record<string, unknown>;
20
21
  /** Template collection for actor creation */
21
22
  templateCollection: TemplateCollection;
23
+ /** Shared timing state */
24
+ time: Time;
22
25
  }
23
26
  /**
24
27
  * Options for scene-level systems.
@@ -36,13 +39,6 @@ export interface WorldSystemOptions extends SystemOptions {
36
39
  /** World this system operates on */
37
40
  world: World;
38
41
  }
39
- /**
40
- * Options passed to update methods with timing information.
41
- */
42
- export interface UpdateOptions {
43
- /** Time elapsed since last update in milliseconds */
44
- deltaTime: number;
45
- }
46
42
  /**
47
43
  * Abstract base class for all game systems.
48
44
  *
@@ -52,17 +48,20 @@ export interface UpdateOptions {
52
48
  * ```typescript
53
49
  * class MovementSystem extends SceneSystem {
54
50
  * private actorQuery: ActorQuery;
51
+ * private time: Time;
55
52
  *
56
53
  * constructor(options: SceneSystemOptions) {
57
- * super(options);
54
+ * super();
58
55
  *
56
+ * this.time = options.time;
59
57
  * this.actorQuery = new ActorQuery({
60
58
  * scene: options.scene,
61
59
  * filter: [Transform, Velocity]
62
60
  * });
63
61
  * }
64
62
  *
65
- * update({ deltaTime }: UpdateOptions): void {
63
+ * update(): void {
64
+ * const { deltaTime } = this.time;
66
65
  * const actors = this.actorQuery.getActors();
67
66
  *
68
67
  * for (const actor of actors) {
@@ -90,9 +89,9 @@ export declare abstract class System {
90
89
  /** Called when a scene is destroyed */
91
90
  onSceneDestroy?(scene: Scene): void;
92
91
  /** Called every frame with variable timestep */
93
- update?(options: UpdateOptions): void;
92
+ update?(): void;
94
93
  /** Called with fixed timestep for physics calculations */
95
- fixedUpdate?(options: UpdateOptions): void;
94
+ fixedUpdate?(): void;
96
95
  }
97
96
  /**
98
97
  * Abstract base class for world-level systems.
@@ -7,17 +7,20 @@
7
7
  * ```typescript
8
8
  * class MovementSystem extends SceneSystem {
9
9
  * private actorQuery: ActorQuery;
10
+ * private time: Time;
10
11
  *
11
12
  * constructor(options: SceneSystemOptions) {
12
- * super(options);
13
+ * super();
13
14
  *
15
+ * this.time = options.time;
14
16
  * this.actorQuery = new ActorQuery({
15
17
  * scene: options.scene,
16
18
  * filter: [Transform, Velocity]
17
19
  * });
18
20
  * }
19
21
  *
20
- * update({ deltaTime }: UpdateOptions): void {
22
+ * update(): void {
23
+ * const { deltaTime } = this.time;
21
24
  * const actors = this.actorQuery.getActors();
22
25
  *
23
26
  * for (const actor of actors) {
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @module Time
3
+ * @category Core
4
+ */
5
+ /**
6
+ * Shared timing state for the game.
7
+ *
8
+ * All durations are expressed in seconds.
9
+ *
10
+ * @category Core
11
+ */
12
+ export declare class Time {
13
+ private _deltaTime;
14
+ private _fixedDeltaTime;
15
+ private _elapsedTime;
16
+ private _alpha;
17
+ constructor();
18
+ /**
19
+ * Time elapsed since the last variable update in seconds.
20
+ *
21
+ * Use this for logic in `update`. In `fixedUpdate`, use
22
+ * {@link Time.fixedDeltaTime} instead.
23
+ */
24
+ get deltaTime(): number;
25
+ /**
26
+ * The constant fixed-update timestep in seconds.
27
+ *
28
+ * Set once from the configured fixed update rate. Use this for logic in
29
+ * `fixedUpdate`.
30
+ */
31
+ get fixedDeltaTime(): number;
32
+ set fixedDeltaTime(value: number);
33
+ /**
34
+ * Total time in seconds since the game started.
35
+ */
36
+ get elapsedTime(): number;
37
+ /**
38
+ * Interpolation factor in `[0, 1)` between the last two fixed steps, for
39
+ * smoothing rendered state. Only meaningful during `update`.
40
+ */
41
+ get alpha(): number;
42
+ /**
43
+ * Advances the per-frame timing state.
44
+ *
45
+ * @internal Called only by the game loop.
46
+ */
47
+ _tick(deltaTime: number, alpha: number): void;
48
+ /**
49
+ * Resets accumulated timing state.
50
+ *
51
+ * @internal Called only by the game loop.
52
+ */
53
+ _reset(): void;
54
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @module Time
3
+ * @category Core
4
+ */
5
+ /**
6
+ * Shared timing state for the game.
7
+ *
8
+ * All durations are expressed in seconds.
9
+ *
10
+ * @category Core
11
+ */
12
+ export class Time {
13
+ _deltaTime;
14
+ _fixedDeltaTime;
15
+ _elapsedTime;
16
+ _alpha;
17
+ constructor() {
18
+ this._deltaTime = 0;
19
+ this._fixedDeltaTime = 0;
20
+ this._elapsedTime = 0;
21
+ this._alpha = 0;
22
+ }
23
+ /**
24
+ * Time elapsed since the last variable update in seconds.
25
+ *
26
+ * Use this for logic in `update`. In `fixedUpdate`, use
27
+ * {@link Time.fixedDeltaTime} instead.
28
+ */
29
+ get deltaTime() {
30
+ return this._deltaTime;
31
+ }
32
+ /**
33
+ * The constant fixed-update timestep in seconds.
34
+ *
35
+ * Set once from the configured fixed update rate. Use this for logic in
36
+ * `fixedUpdate`.
37
+ */
38
+ get fixedDeltaTime() {
39
+ return this._fixedDeltaTime;
40
+ }
41
+ set fixedDeltaTime(value) {
42
+ this._fixedDeltaTime = value;
43
+ }
44
+ /**
45
+ * Total time in seconds since the game started.
46
+ */
47
+ get elapsedTime() {
48
+ return this._elapsedTime;
49
+ }
50
+ /**
51
+ * Interpolation factor in `[0, 1)` between the last two fixed steps, for
52
+ * smoothing rendered state. Only meaningful during `update`.
53
+ */
54
+ get alpha() {
55
+ return this._alpha;
56
+ }
57
+ /**
58
+ * Advances the per-frame timing state.
59
+ *
60
+ * @internal Called only by the game loop.
61
+ */
62
+ _tick(deltaTime, alpha) {
63
+ this._deltaTime = deltaTime;
64
+ this._elapsedTime += deltaTime;
65
+ this._alpha = alpha;
66
+ }
67
+ /**
68
+ * Resets accumulated timing state.
69
+ *
70
+ * @internal Called only by the game loop.
71
+ */
72
+ _reset() {
73
+ this._deltaTime = 0;
74
+ this._elapsedTime = 0;
75
+ this._alpha = 0;
76
+ }
77
+ }
package/build/index.d.ts CHANGED
@@ -4,7 +4,8 @@ export { VectorOps, MathOps, Vector2 } from './engine/math-lib';
4
4
  export * from './engine/consts';
5
5
  export * from './engine/types';
6
6
  export { WorldSystem, SceneSystem } from './engine/system';
7
- export type { System, WorldSystemOptions, SceneSystemOptions, UpdateOptions, } from './engine/system';
7
+ export type { System, WorldSystemOptions, SceneSystemOptions, } from './engine/system';
8
+ export type { Time } from './engine/time';
8
9
  export type { ActorCollectionFilter, ActorSpawner, ActorQueryFilter, } from './engine/actor';
9
10
  export type { EventTarget, Event, EventType, EventPayload, ListenerFn, } from './engine/event-target';
10
11
  export type { Scene } from './engine/scene';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacha",
3
- "version": "0.18.0-alpha.8",
3
+ "version": "0.18.0",
4
4
  "main": "./build/index.js",
5
5
  "types": "./build/index.d.ts",
6
6
  "exports": {
@@ -1,11 +0,0 @@
1
- import type { Axis, AABB } from '../types';
2
- export declare class DispersionCalculator {
3
- private axis;
4
- private sampleSize;
5
- private sum;
6
- private squaredSum;
7
- constructor(axis: Axis);
8
- addToSample(aabb: AABB): void;
9
- removeFromSample(aabb: AABB): void;
10
- getDispersion(): number;
11
- }
@@ -1,41 +0,0 @@
1
- export class DispersionCalculator {
2
- axis;
3
- sampleSize;
4
- sum;
5
- squaredSum;
6
- constructor(axis) {
7
- this.axis = axis;
8
- this.sampleSize = 0;
9
- this.sum = 0;
10
- this.squaredSum = 0;
11
- }
12
- addToSample(aabb) {
13
- const average = (aabb.min[this.axis] + aabb.max[this.axis]) * 0.5;
14
- this.sum += average;
15
- this.squaredSum += average ** 2;
16
- this.sampleSize += 1;
17
- }
18
- removeFromSample(aabb) {
19
- if (this.sampleSize === 0) {
20
- return;
21
- }
22
- this.sampleSize -= 1;
23
- if (this.sampleSize === 0) {
24
- this.sum = 0;
25
- this.squaredSum = 0;
26
- }
27
- else {
28
- const average = (aabb.min[this.axis] + aabb.max[this.axis]) * 0.5;
29
- this.sum -= average;
30
- this.squaredSum -= average ** 2;
31
- }
32
- }
33
- getDispersion() {
34
- if (this.sampleSize <= 1) {
35
- return 0;
36
- }
37
- const average = this.sum / this.sampleSize;
38
- const dispersion = this.squaredSum / this.sampleSize - average ** 2;
39
- return Math.max(0, dispersion);
40
- }
41
- }
@@ -1,12 +0,0 @@
1
- import type { Actor } from '../../engine/actor';
2
- import { type Point } from '../../engine/math-lib';
3
- export declare class OneWayValidator {
4
- private ignoredOneWayContacts;
5
- private oneWayContactUpdateIndex;
6
- constructor();
7
- private clearOneWayContacts;
8
- private trackOneWayContact;
9
- validate(oneWayActor: Actor, otherActor: Actor, normal: Point): boolean;
10
- update(): void;
11
- lateUpdate(): void;
12
- }