@woosh/meep-engine 3.64.0 → 3.65.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/CHANGELOG.md +85 -0
- package/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.d.ts +5 -0
- package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
- package/src/core/binary/BinaryBuffer.js +39 -5
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts +65 -6
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +451 -101
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +4 -2
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +4 -2
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts +8 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +45 -10
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +237 -119
- package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts +143 -0
- package/src/engine/graphics/ecs/grass/GrassSpecies.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GrassSpecies.js +189 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.d.ts +25 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GrassSurface.js +32 -0
- package/src/engine/graphics/ecs/grass/GroundCover.d.ts +68 -0
- package/src/engine/graphics/ecs/grass/GroundCover.d.ts.map +1 -0
- package/src/engine/graphics/ecs/grass/GroundCover.js +85 -0
- package/src/engine/graphics/texture/sampler/exr_to_sampler2d.d.ts +27 -0
- package/src/engine/graphics/texture/sampler/exr_to_sampler2d.d.ts.map +1 -0
- package/src/engine/graphics/texture/sampler/exr_to_sampler2d.js +91 -0
- package/src/engine/graphics/texture/sampler/sampler2d_to_exr.d.ts +23 -0
- package/src/engine/graphics/texture/sampler/sampler2d_to_exr.d.ts.map +1 -0
- package/src/engine/graphics/texture/sampler/sampler2d_to_exr.js +64 -0
- package/src/engine/graphics3/GrassSurfaceSystem.d.ts +153 -0
- package/src/engine/graphics3/GrassSurfaceSystem.d.ts.map +1 -0
- package/src/engine/graphics3/GrassSurfaceSystem.js +1076 -0
- package/src/engine/graphics3/GroundCoverSystem.d.ts +33 -0
- package/src/engine/graphics3/GroundCoverSystem.d.ts.map +1 -0
- package/src/engine/graphics3/GroundCoverSystem.js +58 -0
- package/src/engine/network/NetworkSession.d.ts.map +1 -1
- package/src/engine/network/NetworkSession.js +372 -110
- package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/NetworkPeer.js +6 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +9 -2
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +325 -140
- package/src/engine/network/sim/SimActionExecutor.d.ts +4 -1
- package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
- package/src/engine/network/sim/SimActionExecutor.js +65 -9
- package/src/engine/network/state/PredictionHistory.d.ts.map +1 -1
- package/src/engine/network/state/PredictionHistory.js +6 -1
- package/src/engine/network/time/AdaptiveRenderDelay.d.ts +25 -14
- package/src/engine/network/time/AdaptiveRenderDelay.d.ts.map +1 -1
- package/src/engine/network/time/AdaptiveRenderDelay.js +38 -20
- package/src/engine/network/time/RenderPlayout.d.ts +23 -3
- package/src/engine/network/time/RenderPlayout.d.ts.map +1 -1
- package/src/engine/network/time/RenderPlayout.js +40 -4
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts +5 -1
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.d.ts.map +1 -1
- package/src/engine/physics/fluid/obstacle/chunk_fluid_obstacle_record.js +27 -1
- package/src/format/image/exr/ExrCompression.d.ts +22 -0
- package/src/format/image/exr/ExrCompression.d.ts.map +1 -0
- package/src/format/image/exr/ExrCompression.js +27 -0
- package/src/format/image/exr/ExrImage.d.ts +32 -0
- package/src/format/image/exr/ExrImage.d.ts.map +1 -0
- package/src/format/image/exr/ExrImage.js +32 -0
- package/src/format/image/exr/ExrPixelType.d.ts +13 -0
- package/src/format/image/exr/ExrPixelType.d.ts.map +1 -0
- package/src/format/image/exr/ExrPixelType.js +18 -0
- package/src/format/image/exr/exr_compare_names.d.ts +16 -0
- package/src/format/image/exr/exr_compare_names.d.ts.map +1 -0
- package/src/format/image/exr/exr_compare_names.js +25 -0
- package/src/format/image/exr/exr_constants.d.ts +49 -0
- package/src/format/image/exr/exr_constants.d.ts.map +1 -0
- package/src/format/image/exr/exr_constants.js +56 -0
- package/src/format/image/exr/exr_read.d.ts +32 -0
- package/src/format/image/exr/exr_read.d.ts.map +1 -0
- package/src/format/image/exr/exr_read.js +531 -0
- package/src/format/image/exr/exr_sample_bits.d.ts +16 -0
- package/src/format/image/exr/exr_sample_bits.d.ts.map +1 -0
- package/src/format/image/exr/exr_sample_bits.js +21 -0
- package/src/format/image/exr/exr_scanlines_per_chunk.d.ts +17 -0
- package/src/format/image/exr/exr_scanlines_per_chunk.d.ts.map +1 -0
- package/src/format/image/exr/exr_scanlines_per_chunk.js +31 -0
- package/src/format/image/exr/exr_write.d.ts +27 -0
- package/src/format/image/exr/exr_write.d.ts.map +1 -0
- package/src/format/image/exr/exr_write.js +378 -0
- package/src/shade/device/shader/ShaderModuleCompiler.d.ts +2 -0
- package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
- package/src/shade/device/shader/ShaderModuleCompiler.js +25 -2
- package/src/shade/playground/grass_surfaces/index.html +75 -0
- package/src/shade/playground/grass_surfaces/main.d.ts +2 -0
- package/src/shade/playground/grass_surfaces/main.d.ts.map +1 -0
- package/src/shade/playground/grass_surfaces/main.js +593 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts +62 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.d.ts.map +1 -0
- package/src/shade/playground/grass_surfaces/read_grass_surfaces.js +188 -0
- package/src/shade/playground/probe_clipmap/index.html +5 -0
- package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap/main.js +34 -1
- package/src/shade/playground/probe_clipmap_box/README.md +5 -1
- package/src/shade/playground/probe_clipmap_box/index.html +12 -0
- package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap_box/main.js +15 -0
- package/src/shade/playground/probe_clipmap_box/scene.d.ts +8 -1
- package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap_box/scene.js +74 -6
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +47 -43
- package/src/shade/renderer/extension/ViewTextures.d.ts +12 -5
- package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
- package/src/shade/renderer/extension/ViewTextures.js +19 -5
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +3 -1
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts.map +1 -1
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.js +6 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +7 -0
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.js +10 -0
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +7 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +46 -15
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts +3 -2
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/bundle/ModelCacheBundle.js +3 -2
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts +22 -0
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.d.ts.map +1 -0
- package/src/shade/renderer/geometry/sdf/bundle/model_cache_bundle_sort_morton.js +247 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +50 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +101 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSettings.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +8 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +12 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts +12 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_clipmap_trace.js +35 -29
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_clipmap.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/debug/graph_probe_clipmap_debug_brick_material.js +6 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/GPUBrickMaterial.js +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts +6 -5
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/chunk_brick_material.js +15 -14
- package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/material/shader_brick_material_gather.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +19 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +128 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +19 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +27 -15
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts +19 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/ProbeClipmapScreenWants.js +35 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +3 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +18 -14
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts +40 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_box_cages.js +174 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.d.ts +4 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_material.js +10 -10
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts +31 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_parallax.js +54 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +8 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +10 -21
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +7 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +33 -29
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts +28 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/graph_probe_clipmap_want_meshlets.js +138 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +7 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +28 -17
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +13 -9
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +18 -11
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +18 -18
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +44 -48
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_relocate.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +2 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts +5 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_schedule.js +15 -30
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +11 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +29 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts +40 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_late.js +126 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts +36 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.d.ts.map +1 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_meshlets.js +221 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts +40 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.d.ts.map +1 -0
- package/src/shade/renderer/gpu_primitive/age_eviction/chunk_age_eviction.js +86 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts +135 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/GPUGrassBlades.js +676 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts +145 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/GRASS_BLADE.js +179 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts +63 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade.js +244 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts +58 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/chunk_grass_blade_wind.js +174 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts +25 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_id_draw.js +133 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts +80 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_mechanics.js +92 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts +29 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/grass_blade_resolve.js +175 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts +14 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_draw_args.js +45 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts +61 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_blade_expand.js +340 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts +46 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.d.ts.map +1 -0
- package/src/shade/renderer/grass/blade/shader_grass_cell_count.js +280 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.d.ts +60 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.d.ts.map +1 -0
- package/src/shade/renderer/grass/population/chunk_grass_population.js +171 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.d.ts +99 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/GPUGrassPress.js +436 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts +179 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/GRASS_PRESS.js +217 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.d.ts +65 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/chunk_grass_press.js +296 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts +31 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/shader_grass_press_mark.js +169 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts +27 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.d.ts.map +1 -0
- package/src/shade/renderer/grass/press/shader_grass_press_stamp.js +183 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts +193 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GPUGrassSurfaces.js +1253 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts +211 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE.js +241 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts +82 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/GRASS_SURFACE_VIEW.js +111 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts +39 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_column_cross.js +85 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts +29 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_directory.js +112 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts +27 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_slot.js +50 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts +21 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_frame.js +41 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts +32 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surface_window.js +136 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts +37 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_surfel.js +85 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts +25 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/chunk_grass_tile.js +52 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts +23 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_directory_fill.js +87 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts +43 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake.js +265 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts +13 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_bake_command.js +49 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts +62 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_invalidate.js +162 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts +40 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_retire.js +155 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts +19 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_schedule.js +58 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts +30 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_want.js +251 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts +21 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.d.ts.map +1 -0
- package/src/shade/renderer/grass/surface/shader_grass_surface_window_count.js +75 -0
- package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +4 -23
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts +12 -0
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/velocity/view_velocity_matrices.js +29 -0
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +22 -0
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +3 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts +27 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/scene/GRASS_SURFACE_PARAMS_STRUCT.js +38 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts +28 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/scene/MESH_GROUND_COVER_STRUCT.js +58 -0
- package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
- package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +8 -0
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +8 -0
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +21 -3
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts +37 -0
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/ray/chunk_ray_query_nearest_among.js +148 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts +20 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/sdf/chunk_shape_record_line_span.js +169 -0
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts +18 -0
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.d.ts.map +1 -1
- package/src/shade/renderer/texture/atlas/chunk_tile_atlas_slot_origin.js +28 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts +13 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.d.ts.map +1 -0
- package/src/shade/renderer/texture/atlas/tile_atlas_slot_shift.js +22 -0
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +4 -0
- package/src/shade/renderer/wind/GPUSceneWind.d.ts +52 -5
- package/src/shade/renderer/wind/GPUSceneWind.d.ts.map +1 -1
- package/src/shade/renderer/wind/GPUSceneWind.js +164 -8
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts +3 -1
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.d.ts.map +1 -1
- package/src/shade/renderer/wind/WIND_FIELD_UNIFORM.js +3 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts +2 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.d.ts.map +1 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_cascades.js +18 -13
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts +13 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.d.ts.map +1 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_previous.js +23 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts +1 -0
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.d.ts.map +1 -1
- package/src/shade/renderer/wind/chunk_wind_field_sample_uniform.js +6 -1
- package/src/shade/renderer/wind/wind_field_add_resources.d.ts +11 -0
- package/src/shade/renderer/wind/wind_field_add_resources.d.ts.map +1 -1
- package/src/shade/renderer/wind/wind_field_add_resources.js +15 -0
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { assert } from "../../../core/assert.js";
|
|
2
2
|
import { BinaryBuffer } from "../../../core/binary/BinaryBuffer.js";
|
|
3
|
-
import { binarySearchHighIndex } from "../../../core/collection/array/binarySearchHighIndex.js";
|
|
4
3
|
import Signal from "../../../core/events/signal/Signal.js";
|
|
5
|
-
import { number_compare_ascending } from "../../../core/primitives/numbers/number_compare_ascending.js";
|
|
6
4
|
import { NetworkIdentity } from "../ecs/components/NetworkIdentity.js";
|
|
7
5
|
import { make_owner_authorization } from "../ecs/owner_authorization.js";
|
|
8
6
|
import { Replicator } from "../replication/Replicator.js";
|
|
@@ -104,26 +102,71 @@ export const LateInput = Object.freeze({
|
|
|
104
102
|
* @copyright Company Named Limited (c) 2026
|
|
105
103
|
*/
|
|
106
104
|
export class ServerAuthoritativeServer {
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
105
|
+
// Pending input: the records that have arrived and are not applied yet. Parallel arrays, of
|
|
106
|
+
// which the first #pending_count entries are the records. Like every scratch list here, the
|
|
107
|
+
// arrays are written over from the start and never cut short: an array cut to length 0 gives
|
|
108
|
+
// up its storage, and the next record allocates it again.
|
|
109
|
+
#pending_count = 0;
|
|
110
110
|
#pending_frames = /** @type {number[]} */ ([]);
|
|
111
111
|
#pending_senders = /** @type {number[]} */ ([]);
|
|
112
112
|
#pending_type_ids = /** @type {number[]} */ ([]);
|
|
113
|
+
// each from the payload pool, and at least as long as the record: see #pending_lengths
|
|
113
114
|
#pending_payloads = /** @type {Uint8Array[]} */ ([]);
|
|
114
|
-
#
|
|
115
|
+
#pending_lengths = /** @type {number[]} */ ([]);
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The oldest frame a pending record is tagged for: where a tick's replay starts. Infinity
|
|
119
|
+
* while nothing is pending.
|
|
120
|
+
* @type {number}
|
|
121
|
+
*/
|
|
122
|
+
#pending_oldest_frame = Infinity;
|
|
123
|
+
|
|
115
124
|
#peer_max_received_frame;
|
|
116
|
-
|
|
117
|
-
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Byte arrays for record payloads, free to be taken: the first {@link #payload_pool_count}
|
|
128
|
+
* entries. A record is copied out of a buffer that is about to be reused — a receive buffer, a
|
|
129
|
+
* log frame being reopened — and its copy goes back here once the record is applied or dropped,
|
|
130
|
+
* so a steady stream of input allocates none.
|
|
131
|
+
* @type {Uint8Array[]}
|
|
132
|
+
*/
|
|
133
|
+
#payload_pool = [];
|
|
134
|
+
#payload_pool_count = 0;
|
|
118
135
|
|
|
119
136
|
/**
|
|
120
137
|
* The recorded — not executed — records of the frame being replayed ({@link SENDER_RECORDED}),
|
|
121
138
|
* in log order: carried into the replayed frame as they are, since what produced them is not
|
|
122
|
-
* re-run by a replay.
|
|
123
|
-
*
|
|
139
|
+
* re-run by a replay. Parallel arrays, the first {@link #carried_count} entries; the payloads
|
|
140
|
+
* are from the pool.
|
|
141
|
+
*/
|
|
142
|
+
#carried_count = 0;
|
|
143
|
+
#carried_type_ids = /** @type {number[]} */ ([]);
|
|
144
|
+
#carried_payloads = /** @type {Uint8Array[]} */ ([]);
|
|
145
|
+
#carried_lengths = /** @type {number[]} */ ([]);
|
|
146
|
+
|
|
147
|
+
// The input of the frame being opened — its history, its pending records, the local queue —
|
|
148
|
+
// before it is put in sender order. Parallel arrays, the first #sort_count entries.
|
|
149
|
+
#sort_count = 0;
|
|
150
|
+
#sort_senders = /** @type {number[]} */ ([]);
|
|
151
|
+
#sort_type_ids = /** @type {number[]} */ ([]);
|
|
152
|
+
#sort_payloads = /** @type {Uint8Array[]} */ ([]);
|
|
153
|
+
#sort_lengths = /** @type {number[]} */ ([]);
|
|
154
|
+
// whether the payload is the frame's own copy, from the pool, to give back once applied
|
|
155
|
+
#sort_pooled = /** @type {boolean[]} */ ([]);
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* The frame's input in the order it is applied: indices into the sort arrays, by sender, and
|
|
159
|
+
* within a sender in the order they were added.
|
|
160
|
+
* @type {Int32Array}
|
|
161
|
+
*/
|
|
162
|
+
#sort_order = new Int32Array(64);
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Counting-sort scratch: per sender byte, where its records start in {@link #sort_order}.
|
|
166
|
+
* @type {Int32Array}
|
|
124
167
|
*/
|
|
125
|
-
#
|
|
126
|
-
|
|
168
|
+
#sort_sender_starts = new Int32Array(257);
|
|
169
|
+
|
|
127
170
|
#payload_buf;
|
|
128
171
|
// Walks a frame's records, for the history read.
|
|
129
172
|
#cursor = new ActionRecordCursor();
|
|
@@ -377,9 +420,7 @@ export class ServerAuthoritativeServer {
|
|
|
377
420
|
// accumulate in pending until tick() drains them.
|
|
378
421
|
this.peer.replicator.on_pending_action = (peer_id, frame_number, type_id, buf, off, len, ordinal) => {
|
|
379
422
|
assert.isNonNegativeInteger(ordinal, 'ordinal');
|
|
380
|
-
|
|
381
|
-
payload.set(buf.raw_bytes.subarray(off, off + len));
|
|
382
|
-
this.#pending_add(frame_number, ordinal, peer_id, type_id, payload);
|
|
423
|
+
this.#pending_add(frame_number, ordinal, peer_id, type_id, buf.raw_bytes, off, len);
|
|
383
424
|
if (frame_number > this.last_client_frame_processed) {
|
|
384
425
|
this.last_client_frame_processed = frame_number;
|
|
385
426
|
}
|
|
@@ -641,7 +682,7 @@ export class ServerAuthoritativeServer {
|
|
|
641
682
|
|
|
642
683
|
// 1. Drop pending entries outside the action_log's rewindable window.
|
|
643
684
|
const window_oldest = Math.max(0, sim_frame - this.action_log.frame_capacity + 1);
|
|
644
|
-
if (this.#
|
|
685
|
+
if (this.#pending_oldest_frame < window_oldest) {
|
|
645
686
|
this.#pending_trim_to_window(window_oldest);
|
|
646
687
|
}
|
|
647
688
|
|
|
@@ -655,12 +696,10 @@ export class ServerAuthoritativeServer {
|
|
|
655
696
|
// hold — a retransmission of an applied record is dropped on
|
|
656
697
|
// arrival, see __pending_add — so the oldest pending frame is the
|
|
657
698
|
// oldest frame whose outcome can change, and a rewind to it is
|
|
658
|
-
// never wasted. `
|
|
659
|
-
// ascending; entries `> sim_frame` stay buffered.
|
|
699
|
+
// never wasted. Entries `> sim_frame` stay buffered.
|
|
660
700
|
let replay_start = sim_frame;
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
replay_start = refs[0];
|
|
701
|
+
if (this.#pending_oldest_frame <= sim_frame) {
|
|
702
|
+
replay_start = this.#pending_oldest_frame;
|
|
664
703
|
}
|
|
665
704
|
|
|
666
705
|
try {
|
|
@@ -768,29 +807,29 @@ export class ServerAuthoritativeServer {
|
|
|
768
807
|
* @private
|
|
769
808
|
*/
|
|
770
809
|
#open_frame(f, fresh) {
|
|
771
|
-
|
|
810
|
+
// also gives back what a frame that did not finish left behind
|
|
811
|
+
this.#sort_reset();
|
|
772
812
|
|
|
773
813
|
// Read historical actions out of action_log[f] BEFORE begin_frame(f)
|
|
774
814
|
// recycles the buffer. The sender_id is recorded per-record (see
|
|
775
815
|
// SimActionExecutor), so the stable sort below produces deterministic
|
|
776
816
|
// order regardless of how history was originally interleaved.
|
|
777
|
-
this.#read_historical(f
|
|
778
|
-
for (let i = 0; i < this.#historical_scratch.length; i++) {
|
|
779
|
-
const h = this.#historical_scratch[i];
|
|
780
|
-
this.#sort_scratch.push({ sender_id: h.sender_id, type_id: h.type_id, payload: h.payload });
|
|
781
|
-
}
|
|
817
|
+
this.#read_historical(f);
|
|
782
818
|
|
|
783
819
|
// Append the pending actions for this frame. Pending holds only records that had not
|
|
784
820
|
// arrived before (see #pending_add): a copy of what the log already holds is recognised on
|
|
785
821
|
// arrival by its identity and never gets here, so nothing in it duplicates history. Nothing
|
|
786
822
|
// is compared by bytes — two records alike in every byte are two records (a held key).
|
|
787
|
-
|
|
823
|
+
const pending_count = this.#pending_count;
|
|
824
|
+
for (let i = 0; i < pending_count; i++) {
|
|
788
825
|
if (this.#pending_frames[i] !== f) continue;
|
|
789
|
-
this.#
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
826
|
+
this.#sort_push(
|
|
827
|
+
this.#pending_senders[i],
|
|
828
|
+
this.#pending_type_ids[i],
|
|
829
|
+
this.#pending_payloads[i],
|
|
830
|
+
this.#pending_lengths[i],
|
|
831
|
+
false,
|
|
832
|
+
);
|
|
794
833
|
}
|
|
795
834
|
|
|
796
835
|
// Locally-authored actions join the merge as input, and only on the
|
|
@@ -803,27 +842,138 @@ export class ServerAuthoritativeServer {
|
|
|
803
842
|
if (fresh && this.#local_type_ids.length > 0) {
|
|
804
843
|
const sender = this.server_peer_id >= 0 ? this.server_peer_id : SENDER_LOCAL;
|
|
805
844
|
for (let i = 0; i < this.#local_type_ids.length; i++) {
|
|
806
|
-
this.#
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
payload: this.#local_payloads[i],
|
|
810
|
-
});
|
|
845
|
+
const payload = this.#local_payloads[i];
|
|
846
|
+
|
|
847
|
+
this.#sort_push(sender, this.#local_type_ids[i], payload, payload.length, false);
|
|
811
848
|
}
|
|
812
849
|
this.#local_type_ids.length = 0;
|
|
813
850
|
this.#local_payloads.length = 0;
|
|
814
851
|
}
|
|
815
852
|
|
|
816
|
-
// Stable
|
|
817
|
-
//
|
|
818
|
-
|
|
819
|
-
this.#sort_scratch.sort((a, b) => a.sender_id - b.sender_id);
|
|
853
|
+
// Stable order by sender: equal sender_ids keep the order they were added in, with
|
|
854
|
+
// historical entries appearing before newly-arrived pending entries for the same sender.
|
|
855
|
+
this.#sort_by_sender();
|
|
820
856
|
|
|
821
857
|
// Open the frame, execute all.
|
|
822
858
|
this.action_log.begin_frame(f);
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
859
|
+
|
|
860
|
+
const count = this.#sort_count;
|
|
861
|
+
const order = this.#sort_order;
|
|
862
|
+
|
|
863
|
+
for (let i = 0; i < count; i++) {
|
|
864
|
+
const k = order[i];
|
|
865
|
+
|
|
866
|
+
this.#apply_payload(this.#sort_type_ids[k], this.#sort_senders[k], this.#sort_payloads[k], this.#sort_lengths[k]);
|
|
826
867
|
}
|
|
868
|
+
|
|
869
|
+
this.#sort_reset();
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Add a record to the input of the frame being opened.
|
|
874
|
+
*
|
|
875
|
+
* @param {number} sender_id a sender byte, `[0, 255]`
|
|
876
|
+
* @param {number} type_id
|
|
877
|
+
* @param {Uint8Array} payload
|
|
878
|
+
* @param {number} length how many of `payload`'s bytes are the record
|
|
879
|
+
* @param {boolean} pooled the payload is the frame's own copy, to give back once applied
|
|
880
|
+
* @private
|
|
881
|
+
*/
|
|
882
|
+
#sort_push(sender_id, type_id, payload, length, pooled) {
|
|
883
|
+
const index = this.#sort_count++;
|
|
884
|
+
|
|
885
|
+
this.#sort_senders[index] = sender_id;
|
|
886
|
+
this.#sort_type_ids[index] = type_id;
|
|
887
|
+
this.#sort_payloads[index] = payload;
|
|
888
|
+
this.#sort_lengths[index] = length;
|
|
889
|
+
this.#sort_pooled[index] = pooled;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Empty the frame's input, giving back the payloads that were its own copies.
|
|
894
|
+
* @private
|
|
895
|
+
*/
|
|
896
|
+
#sort_reset() {
|
|
897
|
+
const count = this.#sort_count;
|
|
898
|
+
|
|
899
|
+
for (let i = 0; i < count; i++) {
|
|
900
|
+
if (this.#sort_pooled[i]) {
|
|
901
|
+
this.#payload_release(this.#sort_payloads[i]);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
this.#sort_count = 0;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* Fill {@link #sort_order} with the frame's input by sender, keeping, within a sender, the
|
|
910
|
+
* order the records were added in. A counting sort over the sender byte: linear in the records,
|
|
911
|
+
* and nothing is allocated unless the frame holds more records than any before it.
|
|
912
|
+
* @private
|
|
913
|
+
*/
|
|
914
|
+
#sort_by_sender() {
|
|
915
|
+
const count = this.#sort_count;
|
|
916
|
+
const senders = this.#sort_senders;
|
|
917
|
+
const starts = this.#sort_sender_starts;
|
|
918
|
+
|
|
919
|
+
if (this.#sort_order.length < count) {
|
|
920
|
+
this.#sort_order = new Int32Array(Math.max(count, this.#sort_order.length * 2));
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
const order = this.#sort_order;
|
|
924
|
+
|
|
925
|
+
starts.fill(0);
|
|
926
|
+
|
|
927
|
+
// how many records each sender has, one slot along...
|
|
928
|
+
for (let i = 0; i < count; i++) {
|
|
929
|
+
starts[senders[i] + 1]++;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// ...summed, is where each sender's records start
|
|
933
|
+
for (let s = 0; s < 256; s++) {
|
|
934
|
+
starts[s + 1] += starts[s];
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
for (let i = 0; i < count; i++) {
|
|
938
|
+
order[starts[senders[i]]++] = i;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* A byte array of at least `length` bytes for a record's payload, from the pool when it has
|
|
944
|
+
* one long enough on top. One that is too short is let go of, so the pool's arrays grow to the
|
|
945
|
+
* records that pass through it.
|
|
946
|
+
*
|
|
947
|
+
* @param {number} length
|
|
948
|
+
* @returns {Uint8Array}
|
|
949
|
+
* @private
|
|
950
|
+
*/
|
|
951
|
+
#payload_acquire(length) {
|
|
952
|
+
const count = this.#payload_pool_count;
|
|
953
|
+
|
|
954
|
+
if (count > 0) {
|
|
955
|
+
const pool = this.#payload_pool;
|
|
956
|
+
const top = pool[count - 1];
|
|
957
|
+
|
|
958
|
+
pool[count - 1] = null;
|
|
959
|
+
this.#payload_pool_count = count - 1;
|
|
960
|
+
|
|
961
|
+
if (top.length >= length) {
|
|
962
|
+
return top;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
return new Uint8Array(length);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
/**
|
|
970
|
+
* Give a payload array back to the pool. The caller no longer reads it.
|
|
971
|
+
*
|
|
972
|
+
* @param {Uint8Array} payload
|
|
973
|
+
* @private
|
|
974
|
+
*/
|
|
975
|
+
#payload_release(payload) {
|
|
976
|
+
this.#payload_pool[this.#payload_pool_count++] = payload;
|
|
827
977
|
}
|
|
828
978
|
|
|
829
979
|
/**
|
|
@@ -865,21 +1015,23 @@ export class ServerAuthoritativeServer {
|
|
|
865
1015
|
* @private
|
|
866
1016
|
*/
|
|
867
1017
|
#record_carried() {
|
|
868
|
-
const
|
|
1018
|
+
const count = this.#carried_count;
|
|
869
1019
|
|
|
870
|
-
for (let i = 0; i <
|
|
871
|
-
const
|
|
1020
|
+
for (let i = 0; i < count; i++) {
|
|
1021
|
+
const type_id = this.#carried_type_ids[i];
|
|
1022
|
+
const payload = this.#carried_payloads[i];
|
|
1023
|
+
const length = this.#carried_lengths[i];
|
|
872
1024
|
|
|
873
1025
|
const klass = this.action_registry.klass_for(type_id);
|
|
874
1026
|
if (klass === undefined) continue;
|
|
875
1027
|
|
|
876
1028
|
const action = this.action_registry.acquire(klass);
|
|
877
1029
|
try {
|
|
878
|
-
if (this.#payload_buf.raw_bytes.length <
|
|
879
|
-
this.#payload_buf.setCapacity(
|
|
1030
|
+
if (this.#payload_buf.raw_bytes.length < length) {
|
|
1031
|
+
this.#payload_buf.setCapacity(length);
|
|
880
1032
|
}
|
|
881
1033
|
this.#payload_buf.position = 0;
|
|
882
|
-
this.#payload_buf.writeBytes(payload, 0,
|
|
1034
|
+
this.#payload_buf.writeBytes(payload, 0, length);
|
|
883
1035
|
this.#payload_buf.position = 0;
|
|
884
1036
|
action.deserialize(this.#payload_buf);
|
|
885
1037
|
this.executor.record(action);
|
|
@@ -888,7 +1040,21 @@ export class ServerAuthoritativeServer {
|
|
|
888
1040
|
}
|
|
889
1041
|
}
|
|
890
1042
|
|
|
891
|
-
|
|
1043
|
+
this.#carried_reset();
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* Empty the carried records, giving their payloads back.
|
|
1048
|
+
* @private
|
|
1049
|
+
*/
|
|
1050
|
+
#carried_reset() {
|
|
1051
|
+
const count = this.#carried_count;
|
|
1052
|
+
|
|
1053
|
+
for (let i = 0; i < count; i++) {
|
|
1054
|
+
this.#payload_release(this.#carried_payloads[i]);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
this.#carried_count = 0;
|
|
892
1058
|
}
|
|
893
1059
|
|
|
894
1060
|
/**
|
|
@@ -896,18 +1062,23 @@ export class ServerAuthoritativeServer {
|
|
|
896
1062
|
* — is reported and passed over: the executor leaves nothing of it behind, and the rest of the
|
|
897
1063
|
* frame's input, and the frame itself, go ahead. Letting it escape would leave the frame open
|
|
898
1064
|
* with nothing left to close it.
|
|
1065
|
+
*
|
|
1066
|
+
* @param {number} type_id
|
|
1067
|
+
* @param {number} sender_id
|
|
1068
|
+
* @param {Uint8Array} payload
|
|
1069
|
+
* @param {number} length how many of `payload`'s bytes are the record
|
|
899
1070
|
* @private
|
|
900
1071
|
*/
|
|
901
|
-
#apply_payload(type_id, sender_id, payload) {
|
|
1072
|
+
#apply_payload(type_id, sender_id, payload, length) {
|
|
902
1073
|
const klass = this.action_registry.klass_for(type_id);
|
|
903
1074
|
if (klass === undefined) return;
|
|
904
1075
|
const action = this.action_registry.acquire(klass);
|
|
905
1076
|
try {
|
|
906
|
-
if (this.#payload_buf.raw_bytes.length <
|
|
907
|
-
this.#payload_buf.setCapacity(
|
|
1077
|
+
if (this.#payload_buf.raw_bytes.length < length) {
|
|
1078
|
+
this.#payload_buf.setCapacity(length);
|
|
908
1079
|
}
|
|
909
1080
|
this.#payload_buf.position = 0;
|
|
910
|
-
this.#payload_buf.writeBytes(payload, 0,
|
|
1081
|
+
this.#payload_buf.writeBytes(payload, 0, length);
|
|
911
1082
|
this.#payload_buf.position = 0;
|
|
912
1083
|
action.deserialize(this.#payload_buf);
|
|
913
1084
|
this.executor.execute(action, sender_id);
|
|
@@ -918,10 +1089,17 @@ export class ServerAuthoritativeServer {
|
|
|
918
1089
|
}
|
|
919
1090
|
}
|
|
920
1091
|
|
|
921
|
-
/**
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
1092
|
+
/**
|
|
1093
|
+
* Read frame `frame_number`'s records out of the log, before the frame is reopened over them:
|
|
1094
|
+
* its input into the frame's input ({@link #sort_push}), what was recorded and not executed
|
|
1095
|
+
* into the carried records. Each payload is copied into an array from the pool.
|
|
1096
|
+
*
|
|
1097
|
+
* @param {number} frame_number
|
|
1098
|
+
* @private
|
|
1099
|
+
*/
|
|
1100
|
+
#read_historical(frame_number) {
|
|
1101
|
+
// also gives back what a frame that never recorded its carried records left behind
|
|
1102
|
+
this.#carried_reset();
|
|
925
1103
|
if (!this.action_log.has_frame(frame_number)) return;
|
|
926
1104
|
const cursor = this.#cursor;
|
|
927
1105
|
cursor.open(this.action_log, frame_number);
|
|
@@ -934,17 +1112,28 @@ export class ServerAuthoritativeServer {
|
|
|
934
1112
|
// effect twice, and the copies would accumulate one per replay.
|
|
935
1113
|
if (cursor.sender_id === SENDER_DERIVED) continue;
|
|
936
1114
|
|
|
937
|
-
const
|
|
938
|
-
|
|
1115
|
+
const length = cursor.payload_len;
|
|
1116
|
+
const start = cursor.payload_start;
|
|
1117
|
+
|
|
1118
|
+
const payload = this.#payload_acquire(length);
|
|
1119
|
+
|
|
1120
|
+
for (let i = 0; i < length; i++) {
|
|
1121
|
+
payload[i] = bytes[start + i];
|
|
1122
|
+
}
|
|
939
1123
|
|
|
940
1124
|
// A record of what the engine's systems produced — the host publishing its physics, say.
|
|
941
1125
|
// Neither input to reapply nor output the replay recomputes: carried over as it is.
|
|
942
1126
|
if (cursor.sender_id === SENDER_RECORDED) {
|
|
943
|
-
|
|
1127
|
+
const index = this.#carried_count++;
|
|
1128
|
+
|
|
1129
|
+
this.#carried_type_ids[index] = cursor.action_type_id;
|
|
1130
|
+
this.#carried_payloads[index] = payload;
|
|
1131
|
+
this.#carried_lengths[index] = length;
|
|
1132
|
+
|
|
944
1133
|
continue;
|
|
945
1134
|
}
|
|
946
1135
|
|
|
947
|
-
|
|
1136
|
+
this.#sort_push(cursor.sender_id, cursor.action_type_id, payload, length, true);
|
|
948
1137
|
}
|
|
949
1138
|
}
|
|
950
1139
|
|
|
@@ -980,10 +1169,12 @@ export class ServerAuthoritativeServer {
|
|
|
980
1169
|
* @param {number} ordinal the record's index in the sender's frame, from the wire
|
|
981
1170
|
* @param {number} sender_id
|
|
982
1171
|
* @param {number} type_id
|
|
983
|
-
* @param {Uint8Array}
|
|
1172
|
+
* @param {Uint8Array} bytes the buffer the record arrived in; copied only if the record is taken
|
|
1173
|
+
* @param {number} offset where the record's payload starts in `bytes`
|
|
1174
|
+
* @param {number} length the payload's length
|
|
984
1175
|
* @private
|
|
985
1176
|
*/
|
|
986
|
-
#pending_add(frame_number, ordinal, sender_id, type_id,
|
|
1177
|
+
#pending_add(frame_number, ordinal, sender_id, type_id, bytes, offset, length) {
|
|
987
1178
|
const ring = this.#arrival_ring_for(sender_id);
|
|
988
1179
|
|
|
989
1180
|
// A copy first — already pending, already in the log, or already folded into a later
|
|
@@ -1024,18 +1215,32 @@ export class ServerAuthoritativeServer {
|
|
|
1024
1215
|
}
|
|
1025
1216
|
// Absolute backstop on buffered entries: within the window and the
|
|
1026
1217
|
// ordinal bound a peer can still pile up distinct entries.
|
|
1027
|
-
if (this.#
|
|
1218
|
+
if (this.#pending_count >= this.max_pending_total) {
|
|
1028
1219
|
this.#drop_pending(sender_id, frame_number, 'capacity');
|
|
1029
1220
|
return;
|
|
1030
1221
|
}
|
|
1031
1222
|
|
|
1032
1223
|
ring.mark(frame_number, ordinal);
|
|
1033
1224
|
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
this.#
|
|
1037
|
-
|
|
1038
|
-
|
|
1225
|
+
// Taken: only now is the payload copied out of the receive buffer. Most of what arrives is
|
|
1226
|
+
// a copy of a record already taken, and costs nothing.
|
|
1227
|
+
const payload = this.#payload_acquire(length);
|
|
1228
|
+
|
|
1229
|
+
for (let i = 0; i < length; i++) {
|
|
1230
|
+
payload[i] = bytes[offset + i];
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
const index = this.#pending_count++;
|
|
1234
|
+
|
|
1235
|
+
this.#pending_frames[index] = frame_number;
|
|
1236
|
+
this.#pending_senders[index] = sender_id;
|
|
1237
|
+
this.#pending_type_ids[index] = type_id;
|
|
1238
|
+
this.#pending_payloads[index] = payload;
|
|
1239
|
+
this.#pending_lengths[index] = length;
|
|
1240
|
+
|
|
1241
|
+
if (frame_number < this.#pending_oldest_frame) {
|
|
1242
|
+
this.#pending_oldest_frame = frame_number;
|
|
1243
|
+
}
|
|
1039
1244
|
}
|
|
1040
1245
|
|
|
1041
1246
|
/**
|
|
@@ -1078,47 +1283,55 @@ export class ServerAuthoritativeServer {
|
|
|
1078
1283
|
}
|
|
1079
1284
|
|
|
1080
1285
|
/**
|
|
1081
|
-
*
|
|
1082
|
-
*
|
|
1083
|
-
*
|
|
1084
|
-
*
|
|
1085
|
-
*
|
|
1086
|
-
* @param {number} frame_number
|
|
1286
|
+
* Keep the pending entries tagged for a frame of at least `oldest_kept`, in their order, and
|
|
1287
|
+
* give the payloads of the rest back to the pool. {@link #pending_oldest_frame} follows.
|
|
1288
|
+
*
|
|
1289
|
+
* @param {number} oldest_kept
|
|
1290
|
+
* @param {boolean} report report each entry dropped (`'window'`)
|
|
1087
1291
|
* @private
|
|
1088
1292
|
*/
|
|
1089
|
-
#
|
|
1090
|
-
const
|
|
1091
|
-
const i = binarySearchHighIndex(arr, frame_number, number_compare_ascending);
|
|
1092
|
-
if (arr[i] !== frame_number) arr.splice(i, 0, frame_number);
|
|
1093
|
-
}
|
|
1293
|
+
#pending_keep_from(oldest_kept, report) {
|
|
1294
|
+
const count = this.#pending_count;
|
|
1094
1295
|
|
|
1095
|
-
/**
|
|
1096
|
-
* Drop every pending entry tagged below `window_oldest` — input that waited in pending while the
|
|
1097
|
-
* window moved past it — and report each (`'window'`).
|
|
1098
|
-
* @param {number} window_oldest
|
|
1099
|
-
* @private
|
|
1100
|
-
*/
|
|
1101
|
-
#pending_trim_to_window(window_oldest) {
|
|
1102
1296
|
let kept = 0;
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1297
|
+
let oldest = Infinity;
|
|
1298
|
+
|
|
1299
|
+
for (let i = 0; i < count; i++) {
|
|
1300
|
+
const frame = this.#pending_frames[i];
|
|
1301
|
+
|
|
1302
|
+
if (frame >= oldest_kept) {
|
|
1303
|
+
this.#pending_frames[kept] = frame;
|
|
1106
1304
|
this.#pending_senders[kept] = this.#pending_senders[i];
|
|
1107
1305
|
this.#pending_type_ids[kept] = this.#pending_type_ids[i];
|
|
1108
1306
|
this.#pending_payloads[kept] = this.#pending_payloads[i];
|
|
1307
|
+
this.#pending_lengths[kept] = this.#pending_lengths[i];
|
|
1109
1308
|
kept++;
|
|
1309
|
+
|
|
1310
|
+
if (frame < oldest) oldest = frame;
|
|
1110
1311
|
} else {
|
|
1111
|
-
|
|
1312
|
+
// read before the report: a listener must not find the entry half gone
|
|
1313
|
+
const sender = this.#pending_senders[i];
|
|
1314
|
+
|
|
1315
|
+
this.#payload_release(this.#pending_payloads[i]);
|
|
1316
|
+
|
|
1317
|
+
if (report) {
|
|
1318
|
+
this.#drop_pending(sender, frame, 'window');
|
|
1319
|
+
}
|
|
1112
1320
|
}
|
|
1113
1321
|
}
|
|
1114
|
-
|
|
1115
|
-
this.#
|
|
1116
|
-
this.#
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1322
|
+
|
|
1323
|
+
this.#pending_count = kept;
|
|
1324
|
+
this.#pending_oldest_frame = oldest;
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
/**
|
|
1328
|
+
* Drop every pending entry tagged below `window_oldest` — input that waited in pending while the
|
|
1329
|
+
* window moved past it — and report each (`'window'`).
|
|
1330
|
+
* @param {number} window_oldest
|
|
1331
|
+
* @private
|
|
1332
|
+
*/
|
|
1333
|
+
#pending_trim_to_window(window_oldest) {
|
|
1334
|
+
this.#pending_keep_from(window_oldest, true);
|
|
1122
1335
|
}
|
|
1123
1336
|
|
|
1124
1337
|
/**
|
|
@@ -1131,56 +1344,28 @@ export class ServerAuthoritativeServer {
|
|
|
1131
1344
|
*/
|
|
1132
1345
|
#pending_fold_late_into(sim_frame) {
|
|
1133
1346
|
const frames = this.#pending_frames;
|
|
1134
|
-
|
|
1347
|
+
const count = this.#pending_count;
|
|
1135
1348
|
|
|
1136
|
-
|
|
1137
|
-
if (frames[i] >= sim_frame) continue;
|
|
1138
|
-
frames[i] = sim_frame;
|
|
1139
|
-
folded_any = true;
|
|
1140
|
-
}
|
|
1349
|
+
let oldest = Infinity;
|
|
1141
1350
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
this.#track_referenced_frame(f);
|
|
1351
|
+
for (let i = 0; i < count; i++) {
|
|
1352
|
+
if (frames[i] < sim_frame) {
|
|
1353
|
+
frames[i] = sim_frame;
|
|
1146
1354
|
}
|
|
1355
|
+
|
|
1356
|
+
if (frames[i] < oldest) oldest = frames[i];
|
|
1147
1357
|
}
|
|
1148
|
-
}
|
|
1149
1358
|
|
|
1150
|
-
|
|
1151
|
-
#pending_clear() {
|
|
1152
|
-
this.#pending_frames.length = 0;
|
|
1153
|
-
this.#pending_senders.length = 0;
|
|
1154
|
-
this.#pending_type_ids.length = 0;
|
|
1155
|
-
this.#pending_payloads.length = 0;
|
|
1156
|
-
this.#pending_referenced_frames.length = 0;
|
|
1359
|
+
this.#pending_oldest_frame = oldest;
|
|
1157
1360
|
}
|
|
1158
1361
|
|
|
1159
1362
|
/**
|
|
1160
1363
|
* Drop pending entries with `frame <= keep_threshold`, keeping the
|
|
1161
|
-
* rest.
|
|
1162
|
-
* but with the inequality flipped — used at the end of {@link tick}
|
|
1364
|
+
* rest: they have been applied. Used at the end of {@link tick}
|
|
1163
1365
|
* to retain future-tagged inputs under `simulation_delay_ticks > 0`.
|
|
1164
1366
|
* @private
|
|
1165
1367
|
*/
|
|
1166
1368
|
#pending_filter_to_future(keep_threshold) {
|
|
1167
|
-
|
|
1168
|
-
for (let i = 0; i < this.#pending_frames.length; i++) {
|
|
1169
|
-
if (this.#pending_frames[i] > keep_threshold) {
|
|
1170
|
-
this.#pending_frames[kept] = this.#pending_frames[i];
|
|
1171
|
-
this.#pending_senders[kept] = this.#pending_senders[i];
|
|
1172
|
-
this.#pending_type_ids[kept] = this.#pending_type_ids[i];
|
|
1173
|
-
this.#pending_payloads[kept] = this.#pending_payloads[i];
|
|
1174
|
-
kept++;
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
this.#pending_frames.length = kept;
|
|
1178
|
-
this.#pending_senders.length = kept;
|
|
1179
|
-
this.#pending_type_ids.length = kept;
|
|
1180
|
-
this.#pending_payloads.length = kept;
|
|
1181
|
-
this.#pending_referenced_frames.length = 0;
|
|
1182
|
-
for (const f of this.#pending_frames) {
|
|
1183
|
-
this.#track_referenced_frame(f);
|
|
1184
|
-
}
|
|
1369
|
+
this.#pending_keep_from(keep_threshold + 1, false);
|
|
1185
1370
|
}
|
|
1186
1371
|
}
|
|
@@ -226,7 +226,10 @@ export class SimActionExecutor {
|
|
|
226
226
|
*
|
|
227
227
|
* Not re-entrant: calling `execute` or {@link record} from inside `affected_components`,
|
|
228
228
|
* {@link authorize}, `apply`, `announce` or {@link on_component_written} is illegal (the
|
|
229
|
-
* executor is passed to actions for `slot_table` / `current_sender_id` reads only)
|
|
229
|
+
* executor is passed to actions for `slot_table` / `current_sender_id` reads only), and
|
|
230
|
+
* asserted. Unchecked, the inner action takes over the outer one's list of affected components:
|
|
231
|
+
* started from `affected_components`, the outer action's prior state is captured for the inner
|
|
232
|
+
* action's entity and a rewind no longer restores its own.
|
|
230
233
|
*
|
|
231
234
|
* @param {SimAction} action
|
|
232
235
|
* @param {number} [sender_id] peer that originated this action.
|