@series-inc/rundot-syncplay 6.0.0-rc.49 → 6.0.0-rc.51
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/MIGRATING-RC49-TO-RC51.md +26 -0
- package/core/src/physics/physics-profile-wasm-module.generated.mjs +1 -1
- package/core/src/physics/physics-wasm-module.generated.mjs +1 -1
- package/core/src/physics2d/physics2d-wasm-module.generated.mjs +1 -1
- package/dist/engine-runtime.js +1 -35
- package/dist/lag-compensation3d.js +5 -2
- package/dist/networked-client.js +18 -1
- package/dist/sorted-free-id.d.ts +1 -0
- package/dist/sorted-free-id.js +38 -0
- package/package.json +4 -2
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Syncplay rc.51
|
|
2
|
+
|
|
3
|
+
This release adds cross-engine determinism verification. No public API, wire format, or checksum changes.
|
|
4
|
+
|
|
5
|
+
The release also carries two fixes that landed after the rc.50 candidate cut:
|
|
6
|
+
|
|
7
|
+
- The default retained window never shrinks below its default (#5472).
|
|
8
|
+
- The lag-compensation snapshot detaches occluders, so a rewind can no longer alias a live body (#5487).
|
|
9
|
+
|
|
10
|
+
rc.50 was never published. rc.51 is the first release after rc.49.
|
|
11
|
+
|
|
12
|
+
## Cross-engine determinism corpus
|
|
13
|
+
|
|
14
|
+
- `tests/golden/cross-engine/` is the record of what every JavaScript engine must reproduce byte for byte. Seven session scenarios and a manifest, captured by `scripts/capture-cross-engine.mjs` and verified with `--check`.
|
|
15
|
+
- Scripted sessions run `createSimulatedSyncplayMatch` with real clients on lossy, jittered links, so prediction, rollback and resimulation execute in the engine under test. The recorded corpus shows 94 to 192 rollbacks per scenario at depth 16.
|
|
16
|
+
- Per-frame records carry `getConfirmedStateChecksum(frame)`, the value the wire path commits, so a divergence in the bytes a late joiner hydrates cannot pass.
|
|
17
|
+
- Coverage counters with floors: a scenario that did not produce its rollbacks, its depth or its frames fails instead of passing quietly.
|
|
18
|
+
- `scripts/diff-cross-engine-reports.mjs` is the engine equality gate. Without it, each engine only proves it is self-consistent and two engines that disagree both pass.
|
|
19
|
+
- `scripts/check-cross-engine-corpus-drift.mjs` is the tamper gate: a corpus recapture needs a claim in `allowed-cross-engine-recaptures.json` naming the pull request.
|
|
20
|
+
- CI runs the corpus in the chromium, webkit and firefox lanes and adds a `cross-engine-equality` job that diffs the reports.
|
|
21
|
+
|
|
22
|
+
## Verification
|
|
23
|
+
|
|
24
|
+
- `npm run capture:cross-engine -- --check`: `CROSS_ENGINE_CORPUS_OK`.
|
|
25
|
+
- `node scripts/verify-cross-engine.mjs`: `CROSS_ENGINE_VERIFY_OK scenarios=7 mismatches=0`.
|
|
26
|
+
- The gates fail loudly on a divergent report, a missing source digest, an empty or failing report, and an unclaimed corpus change.
|
|
@@ -24,7 +24,7 @@ export const physicsProfileWasmMetadata = Object.freeze({
|
|
|
24
24
|
"sourceHash": "b722a26af630cb3feb4dd63125ce534ae375fb01a916c013eb779c922a4e4c17",
|
|
25
25
|
"wasmSha256": "f3605958e0292779f909d350c0e7a59ac8d5356c4a4252c7c9f865eb77acf0ac",
|
|
26
26
|
"artifact": "profile",
|
|
27
|
-
"packageVersion": "6.0.0-rc.
|
|
27
|
+
"packageVersion": "6.0.0-rc.51",
|
|
28
28
|
"compilerFlags": [
|
|
29
29
|
"-std=c++20",
|
|
30
30
|
"-O3",
|
|
@@ -24,7 +24,7 @@ export const physicsWasmMetadata = Object.freeze({
|
|
|
24
24
|
"sourceHash": "cb3f4f665a22af2922f7f722a03f59bb12b087521faa13cb4b6dd56ebc788683",
|
|
25
25
|
"wasmSha256": "cee9ef345a6f8d42e35b21553fd414f38e17ac9ad3753a1bf9fc3d4c8c61f7c7",
|
|
26
26
|
"artifact": "production",
|
|
27
|
-
"packageVersion": "6.0.0-rc.
|
|
27
|
+
"packageVersion": "6.0.0-rc.51",
|
|
28
28
|
"compilerFlags": [
|
|
29
29
|
"-std=c++20",
|
|
30
30
|
"-O3",
|
|
@@ -50,7 +50,7 @@ export const physics2dWasmMetadata = Object.freeze({
|
|
|
50
50
|
"sourceHash": "faa090a03a6fddaf79c704fb1d76f810955ff35597449c8cec9541a75905a37e",
|
|
51
51
|
"wasmSha256": "49cb90541deed40f5fff1015bb578e13ec9a793d51931c1227e3e5a11bbfa3f7",
|
|
52
52
|
"artifact": "production",
|
|
53
|
-
"packageVersion": "6.0.0-rc.
|
|
53
|
+
"packageVersion": "6.0.0-rc.51",
|
|
54
54
|
"compilerFlags": [
|
|
55
55
|
"-std=c++20",
|
|
56
56
|
"-O3",
|
package/dist/engine-runtime.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { insertSortedFreeId } from './sorted-free-id.js';
|
|
1
2
|
import { canonicalStringify, cloneCanonical, defaultChecksum } from './canonical.js';
|
|
2
3
|
import { DeterministicRandom } from './random.js';
|
|
3
4
|
import { parseDeterministicSchemaDsl, } from './schema-dsl-binary.js';
|
|
@@ -1568,41 +1569,6 @@ function compareRuntimeMessages(left, right) {
|
|
|
1568
1569
|
/* istanbul ignore next -- runtime message ordering tests cover frame and sequence sort arms. */
|
|
1569
1570
|
return left.frame - right.frame || left.sequence - right.sequence || compareStrings(left.type, right.type);
|
|
1570
1571
|
}
|
|
1571
|
-
/**
|
|
1572
|
-
* Insert a freed id into a free list that is kept ascending at all times, so
|
|
1573
|
-
* reuse can take the smallest id with `shift()`. The list never holds a
|
|
1574
|
-
* duplicate: every free site frees a live id exactly once. Binary search plus a
|
|
1575
|
-
* splice replaces the push-then-sort that re-ordered the whole list per free.
|
|
1576
|
-
*
|
|
1577
|
-
* A forged ref can reach a free site with a non-numeric id: `assertLiveEntity`
|
|
1578
|
-
* accepts a ref whose `generation` is `undefined` when the id has no recorded
|
|
1579
|
-
* generation. The pre-change code sorted such an id to the end of the list,
|
|
1580
|
-
* because its comparator returns NaN for it, and a later valid id keeps that
|
|
1581
|
-
* order. A NaN comparator has no specified result, so this helper cannot
|
|
1582
|
-
* reproduce that placement with a binary search. Any list that has seen a
|
|
1583
|
-
* forged id therefore keeps the exact pre-change push-then-sort path for good.
|
|
1584
|
-
*/
|
|
1585
|
-
const forgedFreeIdLists = new WeakSet();
|
|
1586
|
-
function insertSortedFreeId(list, id) {
|
|
1587
|
-
if (!Number.isInteger(id) || forgedFreeIdLists.has(list)) {
|
|
1588
|
-
forgedFreeIdLists.add(list);
|
|
1589
|
-
list.push(id);
|
|
1590
|
-
list.sort((left, right) => left - right);
|
|
1591
|
-
return;
|
|
1592
|
-
}
|
|
1593
|
-
let low = 0;
|
|
1594
|
-
let high = list.length;
|
|
1595
|
-
while (low < high) {
|
|
1596
|
-
const middle = (low + high) >>> 1;
|
|
1597
|
-
if (list[middle] < id) {
|
|
1598
|
-
low = middle + 1;
|
|
1599
|
-
}
|
|
1600
|
-
else {
|
|
1601
|
-
high = middle;
|
|
1602
|
-
}
|
|
1603
|
-
}
|
|
1604
|
-
list.splice(low, 0, id);
|
|
1605
|
-
}
|
|
1606
1572
|
function createEntity(state) {
|
|
1607
1573
|
const id = state.freeEntityIds.length === 0 ? state.nextEntityId : state.freeEntityIds.shift();
|
|
1608
1574
|
if (id === state.nextEntityId) {
|
|
@@ -86,7 +86,7 @@ export function createDeterministicLagCompensation3DHistory(options) {
|
|
|
86
86
|
const withoutChecksum = {
|
|
87
87
|
maxStoredFrames,
|
|
88
88
|
targets: normalizeLagCompensatedTargets3D(targets),
|
|
89
|
-
occluders,
|
|
89
|
+
occluders: normalizePhysicsBodies(occluders),
|
|
90
90
|
};
|
|
91
91
|
return {
|
|
92
92
|
...withoutChecksum,
|
|
@@ -564,7 +564,10 @@ function normalizeLagCompensatedTargets3D(targets) {
|
|
|
564
564
|
return normalized;
|
|
565
565
|
}
|
|
566
566
|
function normalizePhysicsBodies(bodies) {
|
|
567
|
-
return [...bodies].sort((left, right) => compareStrings(left.id, right.id)).map((body) => ({
|
|
567
|
+
return [...bodies].sort((left, right) => compareStrings(left.id, right.id)).map((body) => ({
|
|
568
|
+
...body,
|
|
569
|
+
shape: typeof body.shape === "object" && body.shape !== null ? structuredClone(body.shape) : body.shape,
|
|
570
|
+
}));
|
|
568
571
|
}
|
|
569
572
|
function lagCompensatedTargetKey(target) {
|
|
570
573
|
return `${target.frame}:${target.targetId}`;
|
package/dist/networked-client.js
CHANGED
|
@@ -779,7 +779,24 @@ export function createNetworkedSyncplayClient(options) {
|
|
|
779
779
|
playerCount: message.playerCount,
|
|
780
780
|
defaultInput: options.defaultInput,
|
|
781
781
|
...(options.requires === undefined ? {} : { requires: options.requires }),
|
|
782
|
-
|
|
782
|
+
// The retained window must cover every reader of a past frame, and it must
|
|
783
|
+
// never be smaller than the historical default of 256:
|
|
784
|
+
// - rollback correction restores up to maxPredictionTicks frames back
|
|
785
|
+
// (measured: depth 8 needs 10, depth 16 needs 18).
|
|
786
|
+
// - snapshot donation serves the newest tick that EVERY human reporter has
|
|
787
|
+
// reported, so the target lags this client by the SLOWEST reporter's round
|
|
788
|
+
// trip plus up to one cadence. Latency is unbounded, so that margin
|
|
789
|
+
// cannot be derived. The old default of 256 is a margin, not a
|
|
790
|
+
// guarantee: it too fails past a lag threshold. It is kept because it
|
|
791
|
+
// is the only bound we can state without measuring the peer's RTT.
|
|
792
|
+
// - when checksumCadenceTicks + maxPredictionTicks exceeds 254, the
|
|
793
|
+
// requirement is genuinely larger than the old default and the window grows.
|
|
794
|
+
// An explicitly supplied snapshotBufferSize is always honoured as given.
|
|
795
|
+
...(options.snapshotBufferSize === undefined
|
|
796
|
+
? {
|
|
797
|
+
snapshotBufferSize: Math.max(256, checksumCadenceTicks + maxPredictionTicks + 2),
|
|
798
|
+
}
|
|
799
|
+
: { snapshotBufferSize: options.snapshotBufferSize }),
|
|
783
800
|
...checksumPolicy,
|
|
784
801
|
...(options.maxCatchUpFrames === undefined ? {} : { maxCatchUpFrames: options.maxCatchUpFrames }),
|
|
785
802
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function insertSortedFreeId(list: number[], id: number): void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Insert a freed id into a free list that is kept ascending at all times, so
|
|
3
|
+
* reuse can take the smallest id with `shift()`. The list never holds a
|
|
4
|
+
* duplicate: every free site frees a live id exactly once. Binary search plus a
|
|
5
|
+
* splice replaces the push-then-sort that re-ordered the whole list per free.
|
|
6
|
+
*
|
|
7
|
+
* A forged ref can reach a free site with a non-numeric id: `assertLiveEntity`
|
|
8
|
+
* accepts a ref whose `generation` is `undefined` when the id has no recorded
|
|
9
|
+
* generation. The pre-change code sorted such an id to the end of the list,
|
|
10
|
+
* because its comparator returns NaN for it, and a later valid id keeps that
|
|
11
|
+
* order. A NaN comparator has no specified result, so this helper cannot
|
|
12
|
+
* reproduce that placement with a binary search. Any list that has seen a
|
|
13
|
+
* forged id therefore keeps the exact pre-change push-then-sort path for good.
|
|
14
|
+
*
|
|
15
|
+
* See docs/syncplay-optimization-log.md for the measurements behind this and
|
|
16
|
+
* for the rules a change here must keep.
|
|
17
|
+
*/
|
|
18
|
+
const forgedFreeIdLists = new WeakSet();
|
|
19
|
+
export function insertSortedFreeId(list, id) {
|
|
20
|
+
if (!Number.isInteger(id) || forgedFreeIdLists.has(list)) {
|
|
21
|
+
forgedFreeIdLists.add(list);
|
|
22
|
+
list.push(id);
|
|
23
|
+
list.sort((left, right) => left - right);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
let low = 0;
|
|
27
|
+
let high = list.length;
|
|
28
|
+
while (low < high) {
|
|
29
|
+
const middle = (low + high) >>> 1;
|
|
30
|
+
if (list[middle] < id) {
|
|
31
|
+
low = middle + 1;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
high = middle;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
list.splice(low, 0, id);
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@series-inc/rundot-syncplay",
|
|
3
|
-
"version": "6.0.0-rc.
|
|
3
|
+
"version": "6.0.0-rc.51",
|
|
4
4
|
"description": "Kinetix orchestration, rollback, replay, late-join, and deterministic networking for RUN.game",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -236,6 +236,7 @@
|
|
|
236
236
|
"core/src",
|
|
237
237
|
"core/world-kernel.d.ts",
|
|
238
238
|
"dist",
|
|
239
|
+
"!dist/cross-engine",
|
|
239
240
|
"extensions",
|
|
240
241
|
"hub",
|
|
241
242
|
"plugins",
|
|
@@ -256,6 +257,7 @@
|
|
|
256
257
|
"MIGRATING-RC44-TO-RC45.md",
|
|
257
258
|
"MIGRATING-RC47-TO-RC48.md",
|
|
258
259
|
"MIGRATING-RC48-TO-RC49.md",
|
|
260
|
+
"MIGRATING-RC49-TO-RC51.md",
|
|
259
261
|
"bench/wreck-yard-sleeping-contacts.json"
|
|
260
262
|
],
|
|
261
263
|
"sideEffects": [
|
|
@@ -269,7 +271,7 @@
|
|
|
269
271
|
"test:core": "node --expose-gc --import tsx --test --test-concurrency=1 tests/canonical.test.ts tests/canonical-portability.test.ts tests/runtime-session.test.ts tests/kinetix-runtime-session.test.ts tests/runtime-support.test.ts tests/runtime-guards.test.ts tests/r3f-render-adapter.test.ts tests/snapshot-cost.test.ts tests/sdkSession.test.ts tests/input-authority.test.ts tests/session-wire.test.ts tests/runtime-room-metadata.test.ts tests/session-snapshot.test.ts tests/authority-room.test.ts tests/networked-client-snapshot.test.ts tests/runner.test.ts tests/testing.test.ts tests/browser-session.test.ts tests/secret-config.test.ts tests/secret-protocol.test.ts tests/secret-authority.test.ts tests/secret-client.test.ts tests/secret-holder-release.test.ts tests/seat-control-parity.test.ts tests/seat-control.test.ts tests/seat-control-runtime.test.ts tests/late-join-checksum.test.ts tests/late-join-input-backfill.test.ts tests/replay-scoring.test.ts tests/bot-backfill.test.ts tests/latency-simulation.test.ts tests/production-input-budget.test.ts tests/time-sync.test.ts tests/match-log.test.ts tests/spectator.test.ts tests/synctest.test.ts tests/instant-replay.test.ts tests/session-promotion.test.ts tests/entrypoints.test.ts tests/physics-profile-bundle.test.ts tests/physics-profile-init.test.ts tests/export-surface.test.ts tests/module-seam.test.ts tests/module-contract-portability.test.ts tests/module-identity.test.ts tests/module-corpus.test.ts tests/component-model.test.ts tests/component-model-rollback.test.ts tests/component-model-integration.test.ts tests/actors-ai.test.ts tests/character-3d.test.ts tests/character-3d-certification.test.ts tests/combat-modules.test.ts tests/combat-modules-integration.test.ts tests/firearm.test.ts tests/gameplay-effects.test.ts tests/spatial-interaction.test.ts tests/stats-abilities.test.ts tests/inventory-equipment.test.ts tests/inventory-equipment-certification.test.ts tests/platformer-2d.test.ts tests/platformer-2d-certification.test.ts tests/module-promotion.test.ts tests/module-docs.test.ts tests/module-bundle-budget.test.ts tests/published-side-effects.test.ts tests/host-timing.test.ts tests/test-manifest.test.ts tests/coarse-region.test.ts tests/input-codec.test.ts tests/command-ingress.test.ts tests/session-reconfigure.test.ts tests/prediction-mode.test.ts tests/ephemeral-channel.test.ts tests/runner-surface.test.ts tests/runner-harness.test.ts tests/effects-adapter-bounds.test.ts tests/simulated-match-secrets.test.ts tests/run-glue-surface.test.mjs core/tests/core-boundary.test.mjs tests/math-core-parity.test.ts tests/math-profile.test.ts tests/movement3d-kcc-unit-contract.test.ts tests/movement3d-static-ground.test.ts tests/physical-assembly.test.ts tests/physical-assembly-determinism.test.ts tests/physical-assembly-certification.test.ts tests/physical-assembly-multiplayer.test.ts tests/state-digest.test.ts tests/large-blob-state.test.ts tests/math-installation-order.test.ts tests/networked-blob-state.test.ts tests/networked-checksum-burst.test.ts tests/networked-runtime-commit.test.ts tests/physics-helper-motion-reads.test.ts tests/physics-unit-conversions.test.ts tests/portal-physics.test.ts tests/physics-checkpoint-capacity.test.ts tests/runner-cleanup.test.ts tests/runtime-release-outcome.test.ts tests/session-checkpoint-budget.test.ts tests/session-owned-cleanup.test.ts tests/tool-owned-adapter.test.ts tests/tool-runtime-lifetime.test.ts tests/movement3d-revision1-baseline.test.ts tests/movement3d-revision1-corpus.test.ts tests/legacy-query-revision1-corpus.test.ts tests/physics-support-boundary.test.ts tests/kcc-corpus-encoding.test.ts tests/voxel-swept-quad-paint.test.ts tests/physics-support-artifact.test.ts tests/movement3d-revision1-binding.test.ts tests/physics-si-pulley-runtime.test.ts tests/vehicle-2d.test.ts tests/vehicle-2d-rollback.test.ts tests/vehicle-state3d.test.ts tests/vehicle-state3d-artifact.test.ts tests/partner-rc22-codecs-units.test.ts tests/vehicle-acceptance-matrix.test.ts tests/partner-tarball-closure.test.ts tests/physics-si-rope-gear-powertrain-runtime.test.ts tests/voxel-body-state.test.ts tests/voxel-carve-cell-sizes.test.ts tests/wreck-yard-d-features.test.ts tests/wreck-yard-regression.test.ts tests/wreck-yard-rc33-gaps.test.ts tests/query-index-parity.test.ts tests/query-index-maintenance.test.ts tests/query-index-churn.test.ts tests/query-index-drift.test.ts tests/query-index-rollback.test.ts tests/portal-render3d.test.ts tests/portal-view-budget.test.ts tests/portal-queries-inside.test.ts tests/portal-render-state.test.ts tests/portal-host-walls.test.ts tests/portal-queries.test.ts tests/portal-placement.test.ts tests/portal-proxies.test.ts tests/portal-a7.test.ts tests/portal-review.test.ts tests/portal-physics-gaps.test.ts tests/extraction.test.ts tests/plugin-lifecycle.test.ts tests/core-zero-io-boundary.test.ts tests/movement3d-revision3-standing.test.mjs tests/movement3d-revision3-recovery.test.mjs tests/coop-shaped-offline.test.ts tests/physics-debug-overlay.test.ts tests/collider-preparation.test.ts tests/navmesh-geometry-cooking.test.ts tests/presentation-ik.test.ts tests/lag-compensation-history.test.ts tests/js-hotpath-regression.test.ts tests/physics-materials-boundary.test.ts tests/physics-materials.test.ts",
|
|
270
272
|
"test:sdk-contract": "node --import tsx --test tests/sdk-runtime-contract.test.ts",
|
|
271
273
|
"test:soak": "tsx --test tests/runtime-soak.test.ts",
|
|
272
|
-
"test:extended": "node --expose-gc --import tsx --test --test-concurrency=1 tests/performance-primitives.test.ts tests/portal-straddler-mesh-cost.test.ts && tsx --test tests/animation.test.ts tests/asset-cooking.test.ts tests/backend-proof-checksum-vectors.test.ts tests/bot-documents.test.ts tests/bot-primitives.test.ts tests/collision.test.ts tests/command-timeline.test.ts tests/config-bundle.test.ts tests/deterministic-primitives.test.ts tests/ecs-lite.test.ts tests/effects-adapter.test.ts tests/engine-runtime.test.ts tests/errors.test.ts tests/events.test.ts tests/input-button.test.ts tests/load-128-players.test.ts tests/math.test.ts tests/movement.test.ts tests/movement3d.test.ts tests/multiclient-authority.test.ts tests/navigation.test.ts tests/noise.test.ts tests/physics3d-geometry-limits.test.ts tests/physics3d-shared.test.ts tests/physics3d-static-memoization.test.ts tests/random.test.ts tests/rollback-history.test.ts tests/schema-artifacts.test.ts tests/schema-codegen.test.ts tests/schema-dsl-binary.test.ts tests/schema.test.ts tests/signals.test.ts tests/sparse-set.test.ts tests/static-checker.test.ts tests/system-lifecycle.test.ts tests/wire-canonical-sentinels.test.ts tests/ws-frame.test.ts tests/wreck-yard-defects.test.ts tests/wreck-yard-performance-harness.test.ts tests/wreck-yard-partner-verification-rc15.test.ts tests/query-index-cost.test.ts tests/wreck-yard-vehicle-batch.test.ts tests/engine-runtime-free-list.test.ts",
|
|
274
|
+
"test:extended": "node --expose-gc --import tsx --test --test-concurrency=1 tests/performance-primitives.test.ts tests/js-hotpath-perf-guard.test.ts tests/portal-straddler-mesh-cost.test.ts && tsx --test tests/animation.test.ts tests/asset-cooking.test.ts tests/backend-proof-checksum-vectors.test.ts tests/bot-documents.test.ts tests/bot-primitives.test.ts tests/collision.test.ts tests/command-timeline.test.ts tests/config-bundle.test.ts tests/deterministic-primitives.test.ts tests/ecs-lite.test.ts tests/effects-adapter.test.ts tests/engine-runtime.test.ts tests/errors.test.ts tests/events.test.ts tests/input-button.test.ts tests/load-128-players.test.ts tests/math.test.ts tests/movement.test.ts tests/movement3d.test.ts tests/multiclient-authority.test.ts tests/navigation.test.ts tests/noise.test.ts tests/physics3d-geometry-limits.test.ts tests/physics3d-shared.test.ts tests/physics3d-static-memoization.test.ts tests/random.test.ts tests/rollback-history.test.ts tests/schema-artifacts.test.ts tests/schema-codegen.test.ts tests/schema-dsl-binary.test.ts tests/schema.test.ts tests/signals.test.ts tests/sparse-set.test.ts tests/static-checker.test.ts tests/system-lifecycle.test.ts tests/wire-canonical-sentinels.test.ts tests/ws-frame.test.ts tests/wreck-yard-defects.test.ts tests/wreck-yard-performance-harness.test.ts tests/wreck-yard-partner-verification-rc15.test.ts tests/query-index-cost.test.ts tests/wreck-yard-vehicle-batch.test.ts tests/engine-runtime-free-list.test.ts",
|
|
273
275
|
"test:ci": "npm run build && npm run test",
|
|
274
276
|
"build:native": "node core/scripts/build-native.mjs",
|
|
275
277
|
"build:wasm-physics": "node core/scripts/build-wasm-physics.mjs",
|