@typeonce/ritmo-browser 0.6.0 → 0.7.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.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # `@typeonce/ritmo-browser`
2
2
 
3
+ Migrating from bevy-ts? See the [package migration guide](https://github.com/typeonce-dev/ritmo/blob/main/MIGRATION.md).
4
+
3
5
  Browser integrations for ritmo: a fixed-step game loop (`FixedLoop`), keyboard actions with press/release edges, bound by character or by physical key (`Keyboard`), mouse and pen position and button edges over an element (`Pointer`), on-screen touch controls with a floating stick and drag-to-aim buttons (`Touch`), scripted and recorded keyboard and pointer timelines for tests and replays, and a system that copies input into a resource (`InputCapture`).
4
6
 
5
7
  ```sh
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The browser's monotonic clock as a core `HostClock`.
3
+ *
4
+ * `window.performance.now()` never goes backwards, unlike `Date.now`
5
+ * (`HostClock.standard`). The window is passed in, so nothing reads a global.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const runtime = Game.Runtime.make({ services, debug: { hostClock: BrowserHostClock.make(window) } })
10
+ * ```
11
+ *
12
+ * @module BrowserHostClock
13
+ */
14
+ import type { HostClock } from "@typeonce/ritmo";
15
+ /** What the clock needs from the window. */
16
+ export interface Host {
17
+ readonly performance: {
18
+ readonly now: () => number;
19
+ };
20
+ }
21
+ /** A host clock reading `host.performance.now()`. */
22
+ export declare const make: (host: Host) => HostClock.HostClock;
23
+ //# sourceMappingURL=BrowserHostClock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserHostClock.d.ts","sourceRoot":"","sources":["../src/BrowserHostClock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,4CAA4C;AAC5C,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAA;KAAE,CAAA;CACrD;AAED,qDAAqD;AACrD,eAAO,MAAM,IAAI,SAAU,IAAI,KAAG,SAAS,CAAC,SAAoD,CAAA"}
@@ -0,0 +1,3 @@
1
+ /** A host clock reading `host.performance.now()`. */
2
+ export const make = (host) => ({ now: () => host.performance.now() });
3
+ //# sourceMappingURL=BrowserHostClock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BrowserHostClock.js","sourceRoot":"","sources":["../src/BrowserHostClock.ts"],"names":[],"mappings":"AAoBA,qDAAqD;AACrD,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAU,EAAuB,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA"}
@@ -8,6 +8,7 @@
8
8
  * @module FixedLoop
9
9
  * @docGroup browser
10
10
  */
11
+ import type * as Clock from "@typeonce/ritmo/Clock";
11
12
  import * as Result from "@typeonce/ritmo/Result";
12
13
  /** One renderer or browser tick measured in milliseconds. */
13
14
  export interface Tick {
@@ -23,8 +24,11 @@ export interface TickSource<TTick extends Tick = Tick> {
23
24
  }
24
25
  /** Validated fixed-step timing policy. */
25
26
  export interface Options {
26
- /** Simulation duration advanced by every fixed update. */
27
- readonly stepSeconds: number;
27
+ /**
28
+ * The fixed step every update advances (`Clock.hz(60)`): the same value
29
+ * the game's clock resource runs at, so the loop and the clock agree.
30
+ */
31
+ readonly step: Clock.Step;
28
32
  /** Maximum host-frame duration admitted into the accumulator. */
29
33
  readonly maxFrameSeconds: number;
30
34
  /** Maximum number of simulation updates performed for one host frame. */
@@ -1 +1 @@
1
- {"version":3,"file":"FixedLoop.d.ts","sourceRoot":"","sources":["../src/FixedLoop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FixedLoop.d.ts","sourceRoot":"","sources":["../src/FixedLoop.ts"],"names":[],"mappings":"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"}
package/dist/FixedLoop.js CHANGED
@@ -1,18 +1,8 @@
1
- /**
2
- * Deterministic fixed-step timing for browser and renderer hosts.
3
- *
4
- * The loop owns the timing policy that is easy to get subtly wrong in every
5
- * game: frame clamping, catch-up limits, interpolation, cancellation, and
6
- * typed update failures. It does not know about an ECS runtime or renderer.
7
- *
8
- * @module FixedLoop
9
- * @docGroup browser
10
- */
11
1
  import * as Result from "@typeonce/ritmo/Result";
12
2
  /** Wraps a host-specific subscription function in the canonical source type. */
13
3
  export const source = (subscribe) => ({ subscribe });
14
4
  const validate = (options) => {
15
- for (const field of ["stepSeconds", "maxFrameSeconds"]) {
5
+ for (const field of ["maxFrameSeconds"]) {
16
6
  const value = options[field];
17
7
  if (!Number.isFinite(value) || value <= 0) {
18
8
  return Result.failure({
@@ -72,24 +62,24 @@ export const start = (options) => {
72
62
  let droppedSeconds = rawSeconds - elapsedSeconds;
73
63
  accumulator += elapsedSeconds;
74
64
  let fixedSteps = 0;
75
- while (accumulator >= options.stepSeconds && fixedSteps < options.maxStepsPerFrame) {
76
- const update = options.update(options.stepSeconds);
65
+ while (accumulator >= options.step.dt && fixedSteps < options.maxStepsPerFrame) {
66
+ const update = options.update(options.step.dt);
77
67
  if (!update.ok) {
78
68
  fail({ kind: "UpdateFailure", error: update.error });
79
69
  return;
80
70
  }
81
- accumulator -= options.stepSeconds;
71
+ accumulator -= options.step.dt;
82
72
  fixedSteps += 1;
83
73
  }
84
- if (accumulator >= options.stepSeconds) {
85
- const droppedWholeSteps = Math.floor(accumulator / options.stepSeconds) * options.stepSeconds;
74
+ if (accumulator >= options.step.dt) {
75
+ const droppedWholeSteps = Math.floor(accumulator / options.step.dt) * options.step.dt;
86
76
  accumulator -= droppedWholeSteps;
87
77
  droppedSeconds += droppedWholeSteps;
88
78
  }
89
79
  options.render({
90
80
  elapsedSeconds,
91
81
  fixedSteps,
92
- alpha: accumulator / options.stepSeconds,
82
+ alpha: accumulator / options.step.dt,
93
83
  droppedSeconds
94
84
  });
95
85
  };
@@ -1 +1 @@
1
- {"version":3,"file":"FixedLoop.js","sourceRoot":"","sources":["../src/FixedLoop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FixedLoop.js","sourceRoot":"","sources":["../src/FixedLoop.ts"],"names":[],"mappings":"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"}
@@ -64,7 +64,7 @@ export interface Options<S extends Schema.Any, Service extends ServiceDescriptor
64
64
  /**
65
65
  * The generated system. It requires the source service and the resource.
66
66
  */
67
- export type CaptureSystem<S extends Schema.Any, Root, Needs extends ServiceDescriptor | ResourceDescriptor | ConditionNeedsFromConditions<ReadonlyArray<Condition>>> = Schema.BoundSystem<S, Root, any, void, never, string, Needs>;
67
+ export type CaptureSystem<S extends Schema.Any, Root, Needs extends ServiceDescriptor | ResourceDescriptor | ConditionNeedsFromConditions<ReadonlyArray<Condition>>> = Schema.BoundSystem<S, Root, any, never, string, Needs>;
68
68
  /**
69
69
  * Builds the system that writes `source.snapshot()` into `resource`.
70
70
  */
@@ -1 +1 @@
1
- {"version":3,"file":"InputCapture.d.ts","sourceRoot":"","sources":["../src/InputCapture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAEpD;;GAEG;AACH,MAAM,WAAW,MAAM,CAAC,KAAK;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,KAAK,CAAA;CAC/B;AAED,KAAK,iBAAiB,GAAG,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;AAC3D,KAAK,kBAAkB,GAAG,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;AAE7D;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,OAAO,SAAS,iBAAiB,IACtD,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,KAAK,CAAA;AAEvE,MAAM,WAAW,OAAO,CACtB,CAAC,SAAS,MAAM,CAAC,GAAG,EACpB,OAAO,SAAS,iBAAiB,EACjC,QAAQ,SAAS,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAC7C,IAAI,SAAS,aAAa,CAAC,SAAS,CAAC,GAAG,SAAS,EAAE;IAEnD,uBAAuB;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,GAAG,4CAA4C,CAAA;IACvH,kGAAkG;IAClG,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;IACjF;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,SAAS,iBAAiB,GAAG,kBAAkB,GAAG,4BAA4B,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,IACjK,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;AAE9D;;GAEG;AACH,eAAO,MAAM,MAAM,GACjB,CAAC,SAAS,MAAM,CAAC,GAAG,EACpB,IAAI,EACJ,KAAK,CAAC,OAAO,SAAS,iBAAiB,EACvC,KAAK,CAAC,QAAQ,SAAS,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,EACnD,KAAK,CAAC,IAAI,SAAS,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,EAAE,QAEzD,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,WACjB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,KAC3C,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,4BAA4B,CAAC,IAAI,CAAC,CAOiB,CAAA"}
1
+ {"version":3,"file":"InputCapture.d.ts","sourceRoot":"","sources":["../src/InputCapture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAEpD;;GAEG;AACH,MAAM,WAAW,MAAM,CAAC,KAAK;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,KAAK,CAAA;CAC/B;AAED,KAAK,iBAAiB,GAAG,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;AAC3D,KAAK,kBAAkB,GAAG,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;AAE7D;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,OAAO,SAAS,iBAAiB,IACtD,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,KAAK,CAAA;AAEvE,MAAM,WAAW,OAAO,CACtB,CAAC,SAAS,MAAM,CAAC,GAAG,EACpB,OAAO,SAAS,iBAAiB,EACjC,QAAQ,SAAS,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAC7C,IAAI,SAAS,aAAa,CAAC,SAAS,CAAC,GAAG,SAAS,EAAE;IAEnD,uBAAuB;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,GAAG,4CAA4C,CAAA;IACvH,kGAAkG;IAClG,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;IACjF;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,SAAS,iBAAiB,GAAG,kBAAkB,GAAG,4BAA4B,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,IACjK,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;AAExD;;GAEG;AACH,eAAO,MAAM,MAAM,GACjB,CAAC,SAAS,MAAM,CAAC,GAAG,EACpB,IAAI,EACJ,KAAK,CAAC,OAAO,SAAS,iBAAiB,EACvC,KAAK,CAAC,QAAQ,SAAS,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,EACnD,KAAK,CAAC,IAAI,SAAS,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,EAAE,QAEzD,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,WACjB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,KAC3C,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,4BAA4B,CAAC,IAAI,CAAC,CAOiB,CAAA"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  /** Browser host integrations kept outside the renderer-agnostic ECS core. */
2
+ export * as BrowserHostClock from "./BrowserHostClock.ts";
2
3
  export * as FixedLoop from "./FixedLoop.ts";
3
4
  export * as InputCapture from "./InputCapture.ts";
4
5
  export * as Keyboard from "./Keyboard.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC,eAAO,MAAM,UAAU,EAAG,SAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC,eAAO,MAAM,UAAU,EAAG,SAAkB,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  /** Browser host integrations kept outside the renderer-agnostic ECS core. */
2
+ export * as BrowserHostClock from "./BrowserHostClock.js";
2
3
  export * as FixedLoop from "./FixedLoop.js";
3
4
  export * as InputCapture from "./InputCapture.js";
4
5
  export * as Keyboard from "./Keyboard.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC,MAAM,CAAC,MAAM,UAAU,GAAG,SAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC,MAAM,CAAC,MAAM,UAAU,GAAG,SAAkB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typeonce/ritmo-browser",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Browser fixed-step loop, keyboard actions, and input capture for Ritmo",
5
5
  "author": "Sandro Maglione",
6
6
  "license": "MIT",
@@ -47,7 +47,7 @@
47
47
  "provenance": true
48
48
  },
49
49
  "dependencies": {
50
- "@typeonce/ritmo": "^0.6.0"
50
+ "@typeonce/ritmo": "^0.7.0"
51
51
  },
52
52
  "engines": {
53
53
  "node": ">=20"
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The browser's monotonic clock as a core `HostClock`.
3
+ *
4
+ * `window.performance.now()` never goes backwards, unlike `Date.now`
5
+ * (`HostClock.standard`). The window is passed in, so nothing reads a global.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const runtime = Game.Runtime.make({ services, debug: { hostClock: BrowserHostClock.make(window) } })
10
+ * ```
11
+ *
12
+ * @module BrowserHostClock
13
+ */
14
+ import type { HostClock } from "@typeonce/ritmo"
15
+
16
+ /** What the clock needs from the window. */
17
+ export interface Host {
18
+ readonly performance: { readonly now: () => number }
19
+ }
20
+
21
+ /** A host clock reading `host.performance.now()`. */
22
+ export const make = (host: Host): HostClock.HostClock => ({ now: () => host.performance.now() })
package/src/FixedLoop.ts CHANGED
@@ -8,6 +8,7 @@
8
8
  * @module FixedLoop
9
9
  * @docGroup browser
10
10
  */
11
+ import type * as Clock from "@typeonce/ritmo/Clock"
11
12
  import * as Result from "@typeonce/ritmo/Result"
12
13
 
13
14
  /** One renderer or browser tick measured in milliseconds. */
@@ -27,8 +28,11 @@ export interface TickSource<TTick extends Tick = Tick> {
27
28
 
28
29
  /** Validated fixed-step timing policy. */
29
30
  export interface Options {
30
- /** Simulation duration advanced by every fixed update. */
31
- readonly stepSeconds: number
31
+ /**
32
+ * The fixed step every update advances (`Clock.hz(60)`): the same value
33
+ * the game's clock resource runs at, so the loop and the clock agree.
34
+ */
35
+ readonly step: Clock.Step
32
36
  /** Maximum host-frame duration admitted into the accumulator. */
33
37
  readonly maxFrameSeconds: number
34
38
  /** Maximum number of simulation updates performed for one host frame. */
@@ -86,7 +90,7 @@ export const source = <TTick extends Tick>(
86
90
  ): TickSource<TTick> => ({ subscribe })
87
91
 
88
92
  const validate = (options: Options): Result.Result<void, InvalidOptions> => {
89
- for (const field of ["stepSeconds", "maxFrameSeconds"] as const) {
93
+ for (const field of ["maxFrameSeconds"] as const) {
90
94
  const value = options[field]
91
95
  if (!Number.isFinite(value) || value <= 0) {
92
96
  return Result.failure({
@@ -155,18 +159,18 @@ export const start = <TTick extends Tick, UpdateError>(
155
159
  accumulator += elapsedSeconds
156
160
 
157
161
  let fixedSteps = 0
158
- while (accumulator >= options.stepSeconds && fixedSteps < options.maxStepsPerFrame) {
159
- const update = options.update(options.stepSeconds)
162
+ while (accumulator >= options.step.dt && fixedSteps < options.maxStepsPerFrame) {
163
+ const update = options.update(options.step.dt)
160
164
  if (!update.ok) {
161
165
  fail({ kind: "UpdateFailure", error: update.error })
162
166
  return
163
167
  }
164
- accumulator -= options.stepSeconds
168
+ accumulator -= options.step.dt
165
169
  fixedSteps += 1
166
170
  }
167
171
 
168
- if (accumulator >= options.stepSeconds) {
169
- const droppedWholeSteps = Math.floor(accumulator / options.stepSeconds) * options.stepSeconds
172
+ if (accumulator >= options.step.dt) {
173
+ const droppedWholeSteps = Math.floor(accumulator / options.step.dt) * options.step.dt
170
174
  accumulator -= droppedWholeSteps
171
175
  droppedSeconds += droppedWholeSteps
172
176
  }
@@ -174,7 +178,7 @@ export const start = <TTick extends Tick, UpdateError>(
174
178
  options.render({
175
179
  elapsedSeconds,
176
180
  fixedSteps,
177
- alpha: accumulator / options.stepSeconds,
181
+ alpha: accumulator / options.step.dt,
178
182
  droppedSeconds
179
183
  })
180
184
  }
@@ -76,7 +76,7 @@ export interface Options<
76
76
  * The generated system. It requires the source service and the resource.
77
77
  */
78
78
  export type CaptureSystem<S extends Schema.Any, Root, Needs extends ServiceDescriptor | ResourceDescriptor | ConditionNeedsFromConditions<ReadonlyArray<Condition>>> =
79
- Schema.BoundSystem<S, Root, any, void, never, string, Needs>
79
+ Schema.BoundSystem<S, Root, any, never, string, Needs>
80
80
 
81
81
  /**
82
82
  * Builds the system that writes `source.snapshot()` into `resource`.
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  /** Browser host integrations kept outside the renderer-agnostic ECS core. */
2
+ export * as BrowserHostClock from "./BrowserHostClock.ts"
2
3
  export * as FixedLoop from "./FixedLoop.ts"
3
4
  export * as InputCapture from "./InputCapture.ts"
4
5
  export * as Keyboard from "./Keyboard.ts"