spoint 0.1.47 → 0.1.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/SKILL.md +17 -3
  2. package/package.json +1 -1
package/SKILL.md CHANGED
@@ -799,7 +799,13 @@ App reloads never happen mid-tick. Queue drains at end of each tick. After each
799
799
 
800
800
  ### GLB Shader Stall Prevention
801
801
 
802
- The engine automatically calls `renderer.compileAsync(object, camera)` immediately after adding any GLB or procedural mesh to the scene. This prevents first-draw GPU stall for dynamically loaded entities (environment models, physics crates, power crates, smart objects, drag-and-drop models). No action is needed from app code — warmup is handled in `loadEntityModel` and `loadQueuedModels`. VRM players use a separate one-time warmup path.
802
+ The engine handles GPU shader warmup in two phases no action is needed from app code:
803
+
804
+ 1. **Initial load**: After the loading screen gates pass (assets, environment, first snapshot, first-snapshot entities all loaded), the loading screen hides and `warmupShaders()` runs asynchronously. It calls `renderer.compileAsync(scene, camera)`, disables frustum culling, renders twice to upload GPU data, then restores culling. This covers all entities present at startup.
805
+
806
+ 2. **Post-load dynamic entities**: For GLBs added after the loading screen is hidden, `loadEntityModel` calls `renderer.compileAsync(scene, camera)` immediately after adding the mesh to the scene.
807
+
808
+ VRM players use a separate one-time warmup (`_vrmWarmupDone`) that fires `renderer.compileAsync(scene, camera)` after the first player model loads.
803
809
 
804
810
  ### render(ctx) Return Value
805
811
 
@@ -1097,9 +1103,9 @@ The engine manually applies `gravity[1] * dt` to Y velocity. This is already han
1097
1103
 
1098
1104
  Use `addConvexCollider(points)` or `addConvexFromModel()` for dynamic/kinematic bodies that need shape-accurate physics (vehicles, crates). Convex hulls support all motion types unlike trimesh. `addConvexFromModel()` reads vertices from the entity's GLB at setup time - call it after setting `entity.model`.
1099
1105
 
1100
- ### Animation library is cached globally
1106
+ ### Animation library uses two-phase cache
1101
1107
 
1102
- `loadAnimationLibrary()` loads `/anim-lib.glb` only once and caches the result. All subsequent calls return the cached result immediately. The library is also pre-fetched in parallel with the VRM download during initialization.
1108
+ `preloadAnimationLibrary()` kicks off the `/anim-lib.glb` fetch and caches the promise (`_gltfPromise`). `loadAnimationLibrary(vrmVersion, vrmHumanoid)` awaits that fetch and caches the normalized clip result (`_normalizedCache`). The engine calls `preloadAnimationLibrary()` early during asset init so the GLB is already fetching while the VRM downloads. Subsequent calls to `loadAnimationLibrary()` return the normalized cache immediately. Both functions are idempotent and safe to call concurrently.
1103
1109
 
1104
1110
  ### Tick drops under load
1105
1111
 
@@ -1121,6 +1127,14 @@ If any blocked string (including in comments) appears anywhere in the source, th
1121
1127
 
1122
1128
  All `import` statements in client app source are stripped by regex before evaluation. Use `engine.THREE`, `engine.scene`, etc. for all dependencies.
1123
1129
 
1130
+ ### GLB/VRM assets are cached in IndexedDB
1131
+
1132
+ On repeat page loads, `fetchCached()` in `client/ModelCache.js` validates cached GLB/VRM ArrayBuffers against the server ETag via a HEAD request. If the ETag matches, the cached bytes are returned without a network fetch. Cache misses or stale entries trigger a full fetch and re-store. Cache failures (quota, unavailable) fall back to normal fetch transparently. This is fully automatic — no app code needed.
1133
+
1134
+ ### Loading screen hides before shader warmup completes
1135
+
1136
+ After the four gate conditions pass, the loading screen hides immediately. `warmupShaders()` then runs asynchronously in the background. The very first rendered frame after the loading screen hides may have a brief GPU stall if shader compilation is not yet complete. This is a deliberate tradeoff to avoid the loading screen adding warmup time on top of actual asset loading.
1137
+
1124
1138
  ### setTimeout not cleared on hot reload
1125
1139
 
1126
1140
  `ctx.time.after/every` timers are cleared on teardown. `setTimeout` and `setInterval` are NOT. Use `ctx.time` for game logic. Use `setTimeout` only for external timing (e.g., reload cooldown) and manage cleanup in teardown manually.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spoint",
3
- "version": "0.1.47",
3
+ "version": "0.1.48",
4
4
  "description": "Physics and netcode SDK for multiplayer game servers",
5
5
  "type": "module",
6
6
  "main": "src/index.js",