@woosh/meep-engine 3.60.9 → 3.61.1
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/CHANGELOG.md +90 -0
- package/package.json +1 -1
- package/src/engine/ecs/EntityManager.d.ts +3 -3
- package/src/engine/ecs/EntityManager.js +3 -3
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
- package/src/engine/graphics/ecs/decal/v2/Decal.d.ts +46 -2
- package/src/engine/graphics/ecs/decal/v2/Decal.d.ts.map +1 -1
- package/src/engine/graphics/ecs/decal/v2/Decal.js +74 -5
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +13 -1
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.d.ts +9 -0
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.d.ts.map +1 -0
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.js +37 -0
- package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DecalSystem.js +462 -447
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.d.ts +14 -0
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.d.ts.map +1 -1
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.js +53 -13
- package/src/engine/graphics3/decal/chunk_decal_record.d.ts +6 -1
- package/src/engine/graphics3/decal/chunk_decal_record.d.ts.map +1 -1
- package/src/engine/graphics3/decal/chunk_decal_record.js +28 -9
- package/src/engine/graphics3/decal/decal_gpu_records.d.ts +2 -1
- package/src/engine/graphics3/decal/decal_gpu_records.d.ts.map +1 -1
- package/src/engine/graphics3/decal/decal_gpu_records.js +26 -5
- package/src/engine/graphics3/decal/decal_material_samplers.d.ts +6 -0
- package/src/engine/graphics3/decal/decal_material_samplers.d.ts.map +1 -1
- package/src/engine/graphics3/decal/decal_material_samplers.js +13 -0
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +1 -1
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts +5 -0
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.js +69 -28
- package/src/engine/network/NetworkSession.d.ts +3 -0
- package/src/engine/network/NetworkSession.d.ts.map +1 -1
- package/src/engine/network/NetworkSession.js +68 -10
- package/src/engine/network/README.md +6 -3
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +51 -5
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +308 -34
- package/src/engine/network/replication/Replicator.d.ts +8 -2
- package/src/engine/network/replication/Replicator.d.ts.map +1 -1
- package/src/engine/network/replication/Replicator.js +13 -4
- package/src/engine/network/sim/ActionLog.d.ts +16 -2
- package/src/engine/network/sim/ActionLog.d.ts.map +1 -1
- package/src/engine/network/sim/ActionLog.js +33 -2
- package/src/engine/network/sim/RewindEngine.d.ts +9 -0
- package/src/engine/network/sim/RewindEngine.d.ts.map +1 -1
- package/src/engine/network/sim/RewindEngine.js +15 -1
- package/src/engine/network/state/FrameBufferRing.d.ts +12 -5
- package/src/engine/network/state/FrameBufferRing.d.ts.map +1 -1
- package/src/engine/network/state/FrameBufferRing.js +32 -6
- package/src/engine/network/time/TimeDilation.d.ts +30 -14
- package/src/engine/network/time/TimeDilation.d.ts.map +1 -1
- package/src/engine/network/time/TimeDilation.js +47 -17
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/generation/foliage/skeleton/ShootWoodHash.d.ts +3 -2
- package/src/generation/foliage/skeleton/ShootWoodHash.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/ShootWoodHash.js +25 -2
- package/src/shade/renderer/buffer/graph_read_buffer.d.ts +3 -1
- package/src/shade/renderer/buffer/graph_read_buffer.d.ts.map +1 -1
- package/src/shade/renderer/buffer/graph_read_buffer.js +9 -6
- package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.d.ts +5 -0
- package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.d.ts.map +1 -1
- package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.js +48 -43
- package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
- package/src/shade/renderer/material/GPUMaterialManager.js +117 -35
- package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts +2 -2
- package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
- package/src/shade/renderer/material/standard/fragment_gbuffer.js +10 -3
- package/src/shade/renderer/material/standard/material_gbuffer_vertex.d.ts +15 -3
- package/src/shade/renderer/material/standard/material_gbuffer_vertex.d.ts.map +1 -1
- package/src/shade/renderer/material/standard/material_gbuffer_vertex.js +25 -4
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +23 -5
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +294 -20
- package/src/shade/renderer/particles/resize/shader_particle_shrink_alive_list.d.ts +21 -0
- package/src/shade/renderer/particles/resize/shader_particle_shrink_alive_list.d.ts.map +1 -0
- package/src/shade/renderer/particles/resize/shader_particle_shrink_alive_list.js +83 -0
- package/src/shade/renderer/particles/resize/shader_particle_shrink_free_list.d.ts +21 -0
- package/src/shade/renderer/particles/resize/shader_particle_shrink_free_list.d.ts.map +1 -0
- package/src/shade/renderer/particles/resize/shader_particle_shrink_free_list.js +64 -0
- package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/chunk_restir_resolve.js +91 -94
- package/src/shade/renderer/restir/reservoir/chunk_rtxdi_stream_sample.js +1 -1
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.d.ts +14 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.js +36 -21
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.js +64 -0
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.js +13 -18
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.js +28 -30
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.js +15 -16
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.d.ts +0 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.js +15 -18
- package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_bitset_or.d.ts +32 -0
- package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_bitset_or.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/subgroup/chunk_subgroup_bitset_or.js +73 -0
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +8 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +7 -3
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.d.ts +0 -2
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.js +0 -6
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { assert } from "../../core/assert.js";
|
|
2
2
|
import { BinaryBuffer } from "../../core/binary/BinaryBuffer.js";
|
|
3
3
|
import Signal from "../../core/events/signal/Signal.js";
|
|
4
|
+
import { clamp } from "../../core/math/clamp.js";
|
|
4
5
|
import { EntityObserver } from "../ecs/EntityObserver.js";
|
|
5
6
|
import { UUID } from "../ecs/guid/UUID.js";
|
|
6
7
|
import { BinarySerializationRegistry, } from "../ecs/storage/binary/BinarySerializationRegistry.js";
|
|
@@ -677,6 +678,14 @@ export class NetworkSession {
|
|
|
677
678
|
*/
|
|
678
679
|
#host_frame_seen = -1;
|
|
679
680
|
|
|
681
|
+
/**
|
|
682
|
+
* Client: the newest host frame this client's world holds — the frame the last join's snapshot
|
|
683
|
+
* was taken at, or a frame applied from the host's action stream since, whichever is newer — or
|
|
684
|
+
* -1 before the first join. It is what a RESUME_HELLO claims, and a resumed stream starts after it.
|
|
685
|
+
* @private @type {number}
|
|
686
|
+
*/
|
|
687
|
+
#host_frame_applied = -1;
|
|
688
|
+
|
|
680
689
|
/**
|
|
681
690
|
* Client: the host's newest depth feedback — its latest sight of this client's frame minus its
|
|
682
691
|
* own sim frame, measured where this client's input lands — and that latest sight itself (the
|
|
@@ -841,6 +850,9 @@ export class NetworkSession {
|
|
|
841
850
|
* - `frame_capacity` sizes the action-log ring (rollback depth + back-fill
|
|
842
851
|
* range + retransmit window — see {@link DEFAULT_ACTION_LOG_FRAME_CAPACITY}).
|
|
843
852
|
* Default 32. Raise it for high-RTT / lossy links.
|
|
853
|
+
* - `time_dilation` (client role): defaults to one built for round trips up to
|
|
854
|
+
* `frame_capacity` frames. One of your own should be too: its
|
|
855
|
+
* `max_round_trip_frames` is what keeps it from overshooting.
|
|
844
856
|
* - `scope_filter` defaults to {@link OwnerAwareScope} on the host.
|
|
845
857
|
* - `server_resume_grace_ms` (host role): how long peer state is
|
|
846
858
|
* retained after a transport drop before being freed. Default 30s.
|
|
@@ -956,8 +968,7 @@ export class NetworkSession {
|
|
|
956
968
|
|
|
957
969
|
this.#time_dilation = time_dilation || new TimeDilation({
|
|
958
970
|
target_buffer_depth: this.simulation_delay_ticks > 0 ? this.simulation_delay_ticks : 2,
|
|
959
|
-
|
|
960
|
-
gain: 0.05,
|
|
971
|
+
max_round_trip_frames: this.frame_capacity,
|
|
961
972
|
});
|
|
962
973
|
this.#adaptive_render_delay = adaptive_render_delay || new AdaptiveRenderDelay({
|
|
963
974
|
tick_period_ms: this.tick_period_ms,
|
|
@@ -1263,10 +1274,12 @@ export class NetworkSession {
|
|
|
1263
1274
|
// and "spectator" (no sampler — sampler-driven onPredict
|
|
1264
1275
|
// returns no actions, so the predict-reconcile machinery
|
|
1265
1276
|
// exists but stays idle).
|
|
1277
|
+
// Only Replay rewinds, so only Replay needs a late host record put back in its frame.
|
|
1266
1278
|
this.#client = new ServerAuthoritativeClient({
|
|
1267
1279
|
...orchestrator_opts,
|
|
1268
1280
|
time_dilation: this.#time_dilation,
|
|
1269
1281
|
auto_reconcile: this.#reconcile === NetworkSessionReconcile.Replay,
|
|
1282
|
+
rebase_on_arrival: this.#reconcile === NetworkSessionReconcile.Replay,
|
|
1270
1283
|
});
|
|
1271
1284
|
if (this.#reconcile === NetworkSessionReconcile.Correct) {
|
|
1272
1285
|
this.#client.peer.onAuthState.add((_peer_id, server_frame, network_id, buffer) => {
|
|
@@ -1496,7 +1509,14 @@ export class NetworkSession {
|
|
|
1496
1509
|
// Resume candidate. Wait for RESUME_HELLO; restore
|
|
1497
1510
|
// baseline + add to connected_peers on validation.
|
|
1498
1511
|
// Don't queue INITIAL_SYNC — it'll only fire if we
|
|
1499
|
-
// RESUME_REJECT.
|
|
1512
|
+
// RESUME_REJECT. Its action stream waits for the claim too:
|
|
1513
|
+
// until the host has read it, neither the peer's token nor
|
|
1514
|
+
// the frame its world is held through is known. A stream
|
|
1515
|
+
// packed meanwhile starts at the ring floor, under frames
|
|
1516
|
+
// the client has already applied, and the client's apply
|
|
1517
|
+
// watermark starts afresh with the connection: it would
|
|
1518
|
+
// apply them again.
|
|
1519
|
+
this.#peer.hold_outbound(remote_peer_id);
|
|
1500
1520
|
} else {
|
|
1501
1521
|
// Fresh peer. Queue initial-sync for the next host tick.
|
|
1502
1522
|
this.#queue_initial_sync(remote_peer_id);
|
|
@@ -1554,7 +1574,7 @@ export class NetworkSession {
|
|
|
1554
1574
|
// we don't speak is one the host has to time out.
|
|
1555
1575
|
const token = this.session_token;
|
|
1556
1576
|
if (token !== null || this.#has_ever_connected) {
|
|
1557
|
-
const last_acked = Math.max(0, this.#
|
|
1577
|
+
const last_acked = Math.max(0, this.#host_frame_applied);
|
|
1558
1578
|
this.#peer.send_resume_hello(
|
|
1559
1579
|
remote_peer_id, this.local_peer_id, last_acked,
|
|
1560
1580
|
token !== null, token !== null ? token.data : NO_SESSION_TOKEN,
|
|
@@ -1893,10 +1913,11 @@ export class NetworkSession {
|
|
|
1893
1913
|
// Client: drive the reconnect timer.
|
|
1894
1914
|
this.#tick_reconnect(dt_ms);
|
|
1895
1915
|
|
|
1896
|
-
// Time dilation: run the whole local simulation
|
|
1897
|
-
//
|
|
1898
|
-
//
|
|
1899
|
-
|
|
1916
|
+
// Time dilation: run the whole local simulation fast or slow, as the host asks, by
|
|
1917
|
+
// stretching the wall time each step consumes — a few percent to steer, slower in
|
|
1918
|
+
// proportion to a lead it has to repay. The step itself — and so every system's dt — is
|
|
1919
|
+
// unchanged, and the render alpha stays a true fraction of it.
|
|
1920
|
+
this.entity_manager.fixedStepTimeScale = 1 / this.#dilation_in_force();
|
|
1900
1921
|
}
|
|
1901
1922
|
|
|
1902
1923
|
// Idle reaping: a connected peer that has gone silent past the timeout
|
|
@@ -2427,6 +2448,9 @@ export class NetworkSession {
|
|
|
2427
2448
|
this.#align_to_host(frame_number);
|
|
2428
2449
|
this.#forget_predicted_world();
|
|
2429
2450
|
this.#binding_answer = BindingAnswer.Synced;
|
|
2451
|
+
// The world is the host's as of this frame, whatever the one it replaced held: a resume
|
|
2452
|
+
// claiming less would be sent frames the snapshot already holds.
|
|
2453
|
+
this.#host_frame_applied = frame_number;
|
|
2430
2454
|
|
|
2431
2455
|
// Input from here on is predicted on the host's world. What was predicted before —
|
|
2432
2456
|
// held since this binding was made, or still in the log from before it — was
|
|
@@ -2489,6 +2513,34 @@ export class NetworkSession {
|
|
|
2489
2513
|
this.#client.forget_timeline();
|
|
2490
2514
|
}
|
|
2491
2515
|
|
|
2516
|
+
/**
|
|
2517
|
+
* Client: the dilation factor to run at — the host's, as far as the report it came from still
|
|
2518
|
+
* holds. A report names the newest frame of this client's the host has seen, which the host keeps
|
|
2519
|
+
* as a running maximum and never lowers.
|
|
2520
|
+
*
|
|
2521
|
+
* - About a frame the clock has since gone back past, the report is about frames the client has
|
|
2522
|
+
* left: nominal rate.
|
|
2523
|
+
* - With no report on this binding, or none for longer than the longest round trip the dilation is
|
|
2524
|
+
* built for, the last one is stale: it may steer, within `max_dilation`, but repays nothing — the
|
|
2525
|
+
* lead it described may be gone, and repaying it again would put the client behind.
|
|
2526
|
+
*
|
|
2527
|
+
* @returns {number}
|
|
2528
|
+
*/
|
|
2529
|
+
#dilation_in_force() {
|
|
2530
|
+
const time_dilation = this.#time_dilation;
|
|
2531
|
+
const factor = this.#client.dilation_factor;
|
|
2532
|
+
const seen = this.#host_marker_seen;
|
|
2533
|
+
const age = this.#local_frame - seen;
|
|
2534
|
+
|
|
2535
|
+
if (seen >= 0 && age <= 0) return 1;
|
|
2536
|
+
|
|
2537
|
+
if (seen < 0 || age > time_dilation.max_round_trip_frames) {
|
|
2538
|
+
return clamp(factor, 1 - time_dilation.max_dilation, 1 + time_dilation.max_dilation);
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
return factor;
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2492
2544
|
/**
|
|
2493
2545
|
* Client, as a step opens: more than the host's input window behind, the client re-takes the
|
|
2494
2546
|
* host's time.
|
|
@@ -2942,8 +2994,11 @@ export class NetworkSession {
|
|
|
2942
2994
|
}
|
|
2943
2995
|
|
|
2944
2996
|
// Valid resume. Restore the action-stream baseline so the
|
|
2945
|
-
// replicator packs from `last_acked + 1`,
|
|
2997
|
+
// replicator packs from `last_acked + 1`, release the stream
|
|
2998
|
+
// `connect()` held from that frame on — nothing the client
|
|
2999
|
+
// already holds is sent on this connection — then accept.
|
|
2946
3000
|
this.#peer.baseline.set_acked(claimed_peer_id, last_acked_frame);
|
|
3001
|
+
this.#peer.release_outbound(transport_peer_id, last_acked_frame + 1);
|
|
2947
3002
|
this.#peer_grace_state.delete(claimed_peer_id);
|
|
2948
3003
|
this.#connected_peers.add(transport_peer_id);
|
|
2949
3004
|
this.#peer.send_resume_accept(transport_peer_id);
|
|
@@ -3680,12 +3735,15 @@ export class NetworkSession {
|
|
|
3680
3735
|
/**
|
|
3681
3736
|
* Record post-apply state for every remote-owned entity into the
|
|
3682
3737
|
* network timeline. Locally-owned entities are predicted, not
|
|
3683
|
-
* interpolated from the network, so they're skipped.
|
|
3738
|
+
* interpolated from the network, so they're skipped. The frame is
|
|
3739
|
+
* one the world now holds, which a resume claims.
|
|
3684
3740
|
*
|
|
3685
3741
|
* Doesn't fire on the host — the replicator's deferral path doesn't
|
|
3686
3742
|
* emit `onFrameApplied`, so the host gets no recording naturally.
|
|
3687
3743
|
*/
|
|
3688
3744
|
#on_frame_applied(_peer_id, frame_number) {
|
|
3745
|
+
if (frame_number > this.#host_frame_applied) this.#host_frame_applied = frame_number;
|
|
3746
|
+
|
|
3689
3747
|
const log = this.#interp_log;
|
|
3690
3748
|
const interpolands = this.#interpolands;
|
|
3691
3749
|
|
|
@@ -59,8 +59,8 @@ nothing else to set up. What that takes, and where it lives:
|
|
|
59
59
|
the step closes (`closeFixedStep`), so physics, controllers and game code all simulate inside the
|
|
60
60
|
frame. There is no `session.tick()` to call (it is deprecated and inert);
|
|
61
61
|
`entity_manager.update(dt)` — the engine loop — drives everything. Client time dilation is the
|
|
62
|
-
engine's `fixedStepTimeScale`: the step cadence stretches by a few percent
|
|
63
|
-
doubled. The session's timers — render playout, idle reaping, grace window — run on the same
|
|
62
|
+
engine's `fixedStepTimeScale`: the step cadence stretches — by a few percent to steer, by more to
|
|
63
|
+
repay a lead the host's lost time left — and no step is dropped or doubled. The session's timers — render playout, idle reaping, grace window — run on the same
|
|
64
64
|
frame time.
|
|
65
65
|
- **The network writes where the simulation writes.** Every transport the session is given is held
|
|
66
66
|
(`DeferredTransport`): what arrives is applied as the next step opens, after the interpolation
|
|
@@ -128,7 +128,10 @@ connection:
|
|
|
128
128
|
|
|
129
129
|
- **`RESUME_ACCEPT`**: the host kept the client's session, so the world the client has been
|
|
130
130
|
predicting on goes on. Everything predicted meanwhile is sent, input predicted while cut off
|
|
131
|
-
included, and the host applies it late.
|
|
131
|
+
included, and the host applies it late. The host sends the new connection none of its own action
|
|
132
|
+
stream until it has read the client's `RESUME_HELLO`, and then the frames after the one the client
|
|
133
|
+
claims to hold the world through: the frame its last join's snapshot was taken at, or the newest
|
|
134
|
+
frame it has applied since.
|
|
132
135
|
- **`INITIAL_SYNC`**: the host's snapshot replaces the client's world. Nothing predicted before it
|
|
133
136
|
is ever sent, on this connection or a later one that resumes it: that input was predicted on a
|
|
134
137
|
world that is gone. The client's input starts at the frame the snapshot sets its counter to.
|
|
@@ -54,6 +54,27 @@
|
|
|
54
54
|
* third. Here the authored half is `onReplay`'s job and the arrived half is
|
|
55
55
|
* this one's.
|
|
56
56
|
*
|
|
57
|
+
* - Records that arrive from a peer for a frame this client has already
|
|
58
|
+
* predicted past belong in that frame, under the prediction since, and
|
|
59
|
+
* before the frame's corrections, which already hold what they did. The
|
|
60
|
+
* frames after it were predicted without them and hold the prior state they
|
|
61
|
+
* captured then, so a rewind across those frames would put back what the
|
|
62
|
+
* records changed — a rewind about any other entity included. Where the
|
|
63
|
+
* records write something a frame after theirs, or a correction of their
|
|
64
|
+
* own frame, holds prior state of, the client takes them back off the
|
|
65
|
+
* world, rewinds to the end of their frame and back past its corrections,
|
|
66
|
+
* applies them there, the corrections after them, and replays what came
|
|
67
|
+
* after, as a reconciliation replays. Records about nothing written since
|
|
68
|
+
* stay where they landed: for everything they write, the present still holds
|
|
69
|
+
* what the end of their frame held. The test is on what records write, not
|
|
70
|
+
* what they read: one that only reads state written since — copying a
|
|
71
|
+
* predicted value into an entity nothing else writes — keeps what it read at
|
|
72
|
+
* the present until a replay crosses its frame. The replay is a
|
|
73
|
+
* reconciliation's, so a local record {@link onReplay} does not produce is
|
|
74
|
+
* lost from the frames it rebuilds. Records for a frame the action log has
|
|
75
|
+
* moved past have no frame to go in: they are applied where they land, and
|
|
76
|
+
* not logged.
|
|
77
|
+
*
|
|
57
78
|
* - A no-op short-circuit is built in: before doing the rewind+replay, the
|
|
58
79
|
* orchestrator gives the user a chance to compute what the replay WOULD
|
|
59
80
|
* produce via {@link onComputeExpected}; if that matches the current
|
|
@@ -83,6 +104,7 @@ export class ServerAuthoritativeClient {
|
|
|
83
104
|
* time_dilation?: TimeDilation,
|
|
84
105
|
* max_packets_per_tick?: number,
|
|
85
106
|
* auto_reconcile?: boolean,
|
|
107
|
+
* rebase_on_arrival?: boolean,
|
|
86
108
|
* clock: function(): number,
|
|
87
109
|
* tick_period_ms: number,
|
|
88
110
|
* send_rate_bytes_per_second?: number,
|
|
@@ -96,8 +118,8 @@ export class ServerAuthoritativeClient {
|
|
|
96
118
|
* `time_dilation`: optional pre-configured {@link TimeDilation}.
|
|
97
119
|
* On TIME_DILATION feedback the client recomputes
|
|
98
120
|
* {@link dilation_factor} for the caller to scale its tick cadence.
|
|
99
|
-
* Defaults to
|
|
100
|
-
* first feedback arrives.
|
|
121
|
+
* Defaults to one built for round trips up to `frame_capacity` frames;
|
|
122
|
+
* `dilation_factor` is 1.0 until the first feedback arrives.
|
|
101
123
|
*
|
|
102
124
|
* `max_packets_per_tick`: forwarded to {@link NetworkPeer}; how many
|
|
103
125
|
* action-stream packets a tick may send the server.
|
|
@@ -107,8 +129,15 @@ export class ServerAuthoritativeClient {
|
|
|
107
129
|
* own reconciliation — `NetworkSession` corrects by comparison instead —
|
|
108
130
|
* turns it off and listens to `peer.onAuthState` itself; {@link reconcile}
|
|
109
131
|
* remains available to it.
|
|
132
|
+
*
|
|
133
|
+
* `rebase_on_arrival` (default true): put the records a peer sends for a
|
|
134
|
+
* frame this client has already predicted past in that frame, under what it
|
|
135
|
+
* predicted since, by rewind and replay — see the class notes. It keeps the
|
|
136
|
+
* log true for the rewinds this client reconciles by. A caller that never
|
|
137
|
+
* rewinds — `NetworkSession` correcting by comparison — turns it off, and
|
|
138
|
+
* the records are applied to the world as it is when they arrive.
|
|
110
139
|
*/
|
|
111
|
-
constructor({ world, binary_registry, replicated_components, action_classes, scope_filter, frame_capacity, initial_buffer_size, input_ring_capacity, input_byte_size, reconcile_epsilon, time_dilation, max_packets_per_tick, auto_reconcile, clock, tick_period_ms, send_rate_bytes_per_second, max_message_bytes, receive_window_bytes, max_queued_bytes, }: {
|
|
140
|
+
constructor({ world, binary_registry, replicated_components, action_classes, scope_filter, frame_capacity, initial_buffer_size, input_ring_capacity, input_byte_size, reconcile_epsilon, time_dilation, max_packets_per_tick, auto_reconcile, rebase_on_arrival, clock, tick_period_ms, send_rate_bytes_per_second, max_message_bytes, receive_window_bytes, max_queued_bytes, }: {
|
|
112
141
|
world: EntityComponentDataset;
|
|
113
142
|
binary_registry: BinarySerializationRegistry;
|
|
114
143
|
replicated_components: Function[];
|
|
@@ -122,6 +151,7 @@ export class ServerAuthoritativeClient {
|
|
|
122
151
|
time_dilation?: TimeDilation;
|
|
123
152
|
max_packets_per_tick?: number;
|
|
124
153
|
auto_reconcile?: boolean;
|
|
154
|
+
rebase_on_arrival?: boolean;
|
|
125
155
|
clock: () => number;
|
|
126
156
|
tick_period_ms: number;
|
|
127
157
|
send_rate_bytes_per_second?: number;
|
|
@@ -131,7 +161,10 @@ export class ServerAuthoritativeClient {
|
|
|
131
161
|
});
|
|
132
162
|
/** @type {number} */
|
|
133
163
|
reconcile_count: number;
|
|
134
|
-
/**
|
|
164
|
+
/**
|
|
165
|
+
* Frames replayed, by reconciliations and by records put back in their frame.
|
|
166
|
+
* @type {number}
|
|
167
|
+
*/
|
|
135
168
|
replay_frame_count: number;
|
|
136
169
|
/**
|
|
137
170
|
* Records that arrived from a peer and were reapplied by a replay, over the
|
|
@@ -147,6 +180,13 @@ export class ServerAuthoritativeClient {
|
|
|
147
180
|
* @type {number}
|
|
148
181
|
*/
|
|
149
182
|
reconcile_abandoned_count: number;
|
|
183
|
+
/**
|
|
184
|
+
* Frames of records from a peer that arrived after this client had predicted past them, wrote
|
|
185
|
+
* something written later — in a frame after theirs, or by a correction of their own — and so
|
|
186
|
+
* were put back in their frame by a rewind and a replay. See {@link #land_arrived}.
|
|
187
|
+
* @type {number}
|
|
188
|
+
*/
|
|
189
|
+
rebase_count: number;
|
|
150
190
|
/** @type {NetworkPeer} */
|
|
151
191
|
peer: NetworkPeer;
|
|
152
192
|
/** @type {EntityComponentDataset} */
|
|
@@ -190,7 +230,10 @@ export class ServerAuthoritativeClient {
|
|
|
190
230
|
/**
|
|
191
231
|
* Tick-period multiplier from the latest TIME_DILATION feedback.
|
|
192
232
|
* `< 1.0` ⇒ caller should run faster, `> 1.0` ⇒ slower. 1.0 until
|
|
193
|
-
* the first feedback arrives.
|
|
233
|
+
* the first feedback arrives. It follows every report, and holds while
|
|
234
|
+
* none come: a caller that seeks its frames back, or loses the host,
|
|
235
|
+
* judges whether the latest report still holds before running at it, as
|
|
236
|
+
* `NetworkSession` does.
|
|
194
237
|
*
|
|
195
238
|
* scheduled_tick_period_ms = TICK_PERIOD_MS * client.dilation_factor;
|
|
196
239
|
*
|
|
@@ -284,6 +327,9 @@ export class ServerAuthoritativeClient {
|
|
|
284
327
|
* longer holds the frames its rewind needed. Args:
|
|
285
328
|
* `(server_frame, network_id)`.
|
|
286
329
|
*
|
|
330
|
+
* Nothing of it is done: the world stays at the present, and the
|
|
331
|
+
* server's state is not applied.
|
|
332
|
+
*
|
|
287
333
|
* This is a real loss of replicated state and not a hiccup: state a peer
|
|
288
334
|
* does not own reaches it on the action stream, and an owner that
|
|
289
335
|
* publishes on change never sends it again — so whatever that window
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerAuthoritativeClient.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/orchestrator/ServerAuthoritativeClient.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ServerAuthoritativeClient.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/orchestrator/ServerAuthoritativeClient.js"],"names":[],"mappings":"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"}
|