rn-gamekit 0.1.0 → 0.2.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 +75 -0
- package/README.md +97 -16
- package/lib/module/assets/defineAssets.js +28 -3
- package/lib/module/assets/defineAssets.js.map +1 -1
- package/lib/module/assets.js +11 -0
- package/lib/module/assets.js.map +1 -0
- package/lib/module/audio/createGameAudio.js +784 -0
- package/lib/module/audio/createGameAudio.js.map +1 -0
- package/lib/module/audio/errors.js +12 -0
- package/lib/module/audio/errors.js.map +1 -0
- package/lib/module/audio/index.js +5 -0
- package/lib/module/audio/index.js.map +1 -0
- package/lib/module/audio/resolver.js +37 -0
- package/lib/module/audio/resolver.js.map +1 -0
- package/lib/module/audio/types.js +4 -0
- package/lib/module/audio/types.js.map +1 -0
- package/lib/module/audio.js +9 -0
- package/lib/module/audio.js.map +1 -0
- package/lib/module/camera2d/bounds.js +59 -0
- package/lib/module/camera2d/bounds.js.map +1 -0
- package/lib/module/camera2d/extents.js +25 -0
- package/lib/module/camera2d/extents.js.map +1 -0
- package/lib/module/camera2d/follow.js +138 -0
- package/lib/module/camera2d/follow.js.map +1 -0
- package/lib/module/camera2d/index.js +20 -0
- package/lib/module/camera2d/index.js.map +1 -0
- package/lib/module/camera2d/interpolation.js +98 -0
- package/lib/module/camera2d/interpolation.js.map +1 -0
- package/lib/module/camera2d/shake.js +85 -0
- package/lib/module/camera2d/shake.js.map +1 -0
- package/lib/module/camera2d/transform.js +151 -0
- package/lib/module/camera2d/transform.js.map +1 -0
- package/lib/module/camera2d/types.js +4 -0
- package/lib/module/camera2d/types.js.map +1 -0
- package/lib/module/camera2d/validation.js +98 -0
- package/lib/module/camera2d/validation.js.map +1 -0
- package/lib/module/camera2d/visibility.js +138 -0
- package/lib/module/camera2d/visibility.js.map +1 -0
- package/lib/module/camera2d.js +9 -0
- package/lib/module/camera2d.js.map +1 -0
- package/lib/module/collision2d/colliders.js +266 -0
- package/lib/module/collision2d/colliders.js.map +1 -0
- package/lib/module/collision2d/debug.js +105 -0
- package/lib/module/collision2d/debug.js.map +1 -0
- package/lib/module/collision2d/filters.js +40 -0
- package/lib/module/collision2d/filters.js.map +1 -0
- package/lib/module/collision2d/index.js +12 -0
- package/lib/module/collision2d/index.js.map +1 -0
- package/lib/module/collision2d/intersections.js +67 -0
- package/lib/module/collision2d/intersections.js.map +1 -0
- package/lib/module/collision2d/manifolds.js +218 -0
- package/lib/module/collision2d/manifolds.js.map +1 -0
- package/lib/module/collision2d/segments.js +187 -0
- package/lib/module/collision2d/segments.js.map +1 -0
- package/lib/module/collision2d/spatialHash.js +167 -0
- package/lib/module/collision2d/spatialHash.js.map +1 -0
- package/lib/module/collision2d/sweeps.js +255 -0
- package/lib/module/collision2d/sweeps.js.map +1 -0
- package/lib/module/collision2d.js +9 -0
- package/lib/module/collision2d.js.map +1 -0
- package/lib/module/core/input/buttonPad.js +214 -0
- package/lib/module/core/input/buttonPad.js.map +1 -0
- package/lib/module/core/input/createInputBuffer.js +66 -14
- package/lib/module/core/input/createInputBuffer.js.map +1 -1
- package/lib/module/core/session/createGameSession.js +454 -50
- package/lib/module/core/session/createGameSession.js.map +1 -1
- package/lib/module/core/session/deepFreeze.js +92 -2
- package/lib/module/core/session/deepFreeze.js.map +1 -1
- package/lib/module/core/session/types.js +12 -0
- package/lib/module/core/session/types.js.map +1 -1
- package/lib/module/definition/defineGame.js +23 -0
- package/lib/module/definition/defineGame.js.map +1 -1
- package/lib/module/events/defineGameEvents.js +46 -0
- package/lib/module/events/defineGameEvents.js.map +1 -0
- package/lib/module/events/errors.js +16 -0
- package/lib/module/events/errors.js.map +1 -0
- package/lib/module/events/index.js +7 -0
- package/lib/module/events/index.js.map +1 -0
- package/lib/module/events/payload.js +219 -0
- package/lib/module/events/payload.js.map +1 -0
- package/lib/module/events/seed.js +33 -0
- package/lib/module/events/seed.js.map +1 -0
- package/lib/module/events/types.js +4 -0
- package/lib/module/events/types.js.map +1 -0
- package/lib/module/events.js +13 -0
- package/lib/module/events.js.map +1 -0
- package/lib/module/geometry/helpers.js +140 -0
- package/lib/module/geometry/helpers.js.map +1 -0
- package/lib/module/geometry/index.js +5 -0
- package/lib/module/geometry/index.js.map +1 -0
- package/lib/module/geometry/validation.js +104 -0
- package/lib/module/geometry/validation.js.map +1 -0
- package/lib/module/geometry.js +9 -0
- package/lib/module/geometry.js.map +1 -0
- package/lib/module/haptics/createGameHaptics.js +214 -0
- package/lib/module/haptics/createGameHaptics.js.map +1 -0
- package/lib/module/haptics/errors.js +12 -0
- package/lib/module/haptics/errors.js.map +1 -0
- package/lib/module/haptics/index.js +5 -0
- package/lib/module/haptics/index.js.map +1 -0
- package/lib/module/haptics/resolver.js +37 -0
- package/lib/module/haptics/resolver.js.map +1 -0
- package/lib/module/haptics/types.js +4 -0
- package/lib/module/haptics/types.js.map +1 -0
- package/lib/module/haptics.js +9 -0
- package/lib/module/haptics.js.map +1 -0
- package/lib/module/index.js +8 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/particles/createParticleSystem.js +481 -0
- package/lib/module/particles/createParticleSystem.js.map +1 -0
- package/lib/module/particles/defineParticleEffect.js +178 -0
- package/lib/module/particles/defineParticleEffect.js.map +1 -0
- package/lib/module/particles/errors.js +9 -0
- package/lib/module/particles/errors.js.map +1 -0
- package/lib/module/particles/index.js +8 -0
- package/lib/module/particles/index.js.map +1 -0
- package/lib/module/particles/sampling.js +121 -0
- package/lib/module/particles/sampling.js.map +1 -0
- package/lib/module/particles/types.js +4 -0
- package/lib/module/particles/types.js.map +1 -0
- package/lib/module/particles.js +4 -0
- package/lib/module/particles.js.map +1 -0
- package/lib/module/react/GameButtonPad.js +344 -0
- package/lib/module/react/GameButtonPad.js.map +1 -0
- package/lib/module/react/GamePointerInput.js +74 -16
- package/lib/module/react/GamePointerInput.js.map +1 -1
- package/lib/module/react/GameView.js +139 -60
- package/lib/module/react/GameView.js.map +1 -1
- package/lib/module/react/assets/createGameAssetStore.js +145 -95
- package/lib/module/react/assets/createGameAssetStore.js.map +1 -1
- package/lib/module/react/assets/useGameAssets.js +60 -35
- package/lib/module/react/assets/useGameAssets.js.map +1 -1
- package/lib/module/react/bindAppLifecycle.js +46 -17
- package/lib/module/react/bindAppLifecycle.js.map +1 -1
- package/lib/module/react/bindGameSession.js +13 -2
- package/lib/module/react/bindGameSession.js.map +1 -1
- package/lib/module/react/camera2d/GameLayer2D.js +50 -0
- package/lib/module/react/camera2d/GameLayer2D.js.map +1 -0
- package/lib/module/react/camera2d/defineGameCamera2D.js +30 -0
- package/lib/module/react/camera2d/defineGameCamera2D.js.map +1 -0
- package/lib/module/react/camera2d/usePresentedCameraBinding.js +177 -0
- package/lib/module/react/camera2d/usePresentedCameraBinding.js.map +1 -0
- package/lib/module/react/cleanupList.js +38 -0
- package/lib/module/react/cleanupList.js.map +1 -0
- package/lib/module/react/lifecycleSource.js +49 -0
- package/lib/module/react/lifecycleSource.js.map +1 -0
- package/lib/module/react/particles/ParticleView.js +308 -0
- package/lib/module/react/particles/ParticleView.js.map +1 -0
- package/lib/module/react/particles/culling.js +115 -0
- package/lib/module/react/particles/culling.js.map +1 -0
- package/lib/module/react/particles/index.js +7 -0
- package/lib/module/react/particles/index.js.map +1 -0
- package/lib/module/react/particles/spriteXForm.js +45 -0
- package/lib/module/react/particles/spriteXForm.js.map +1 -0
- package/lib/module/react/particles/useParticlePresentation.js +204 -0
- package/lib/module/react/particles/useParticlePresentation.js.map +1 -0
- package/lib/module/react/pointerBinding.js +55 -17
- package/lib/module/react/pointerBinding.js.map +1 -1
- package/lib/module/react/pointerCamera.js +28 -0
- package/lib/module/react/pointerCamera.js.map +1 -0
- package/lib/module/react/pointerCoalescer.js +16 -9
- package/lib/module/react/pointerCoalescer.js.map +1 -1
- package/lib/module/react/sprites/GameSprite.js +5 -17
- package/lib/module/react/sprites/GameSprite.js.map +1 -1
- package/lib/module/react/sprites/GameWorld2D.js +112 -9
- package/lib/module/react/sprites/GameWorld2D.js.map +1 -1
- package/lib/module/react/sprites/Sprite.js +48 -63
- package/lib/module/react/sprites/Sprite.js.map +1 -1
- package/lib/module/react/sprites/SpriteBatch.js +53 -28
- package/lib/module/react/sprites/SpriteBatch.js.map +1 -1
- package/lib/module/react/sprites/batchVisibility.js +58 -0
- package/lib/module/react/sprites/batchVisibility.js.map +1 -0
- package/lib/module/react/sprites/spriteSelection.js +103 -0
- package/lib/module/react/sprites/spriteSelection.js.map +1 -0
- package/lib/module/react/sprites/spriteTransform.js +46 -25
- package/lib/module/react/sprites/spriteTransform.js.map +1 -1
- package/lib/module/react/tilemap/TileMapLayer2D.js +217 -0
- package/lib/module/react/tilemap/TileMapLayer2D.js.map +1 -0
- package/lib/module/react/tilemap/tilePresentation.js +374 -0
- package/lib/module/react/tilemap/tilePresentation.js.map +1 -0
- package/lib/module/react/useGameSession.js +70 -0
- package/lib/module/react/useGameSession.js.map +1 -0
- package/lib/module/react/useGameSessionStatus.js +46 -0
- package/lib/module/react/useGameSessionStatus.js.map +1 -0
- package/lib/module/react/viewportBinding.js +5 -1
- package/lib/module/react/viewportBinding.js.map +1 -1
- package/lib/module/react.js +12 -1
- package/lib/module/react.js.map +1 -1
- package/lib/module/scene/defineScene.js +17 -0
- package/lib/module/scene/defineScene.js.map +1 -1
- package/lib/module/sprites/sampleSpriteClip.js +66 -6
- package/lib/module/sprites/sampleSpriteClip.js.map +1 -1
- package/lib/module/sprites/spriteAnimationState.js +10 -20
- package/lib/module/sprites/spriteAnimationState.js.map +1 -1
- package/lib/module/sprites.js +11 -0
- package/lib/module/sprites.js.map +1 -0
- package/lib/module/storage/adapters/asyncStorage.js +57 -0
- package/lib/module/storage/adapters/asyncStorage.js.map +1 -0
- package/lib/module/storage/adapters/memory.js +50 -0
- package/lib/module/storage/adapters/memory.js.map +1 -0
- package/lib/module/storage/errors.js +34 -0
- package/lib/module/storage/errors.js.map +1 -0
- package/lib/module/storage/index.js +11 -0
- package/lib/module/storage/index.js.map +1 -0
- package/lib/module/storage/schema.js +151 -0
- package/lib/module/storage/schema.js.map +1 -0
- package/lib/module/storage/serialization.js +249 -0
- package/lib/module/storage/serialization.js.map +1 -0
- package/lib/module/storage/store.js +387 -0
- package/lib/module/storage/store.js.map +1 -0
- package/lib/module/storage/types.js +16 -0
- package/lib/module/storage/types.js.map +1 -0
- package/lib/module/storage/validation.js +111 -0
- package/lib/module/storage/validation.js.map +1 -0
- package/lib/module/storage.js +4 -0
- package/lib/module/storage.js.map +1 -0
- package/lib/module/testing.js +4 -0
- package/lib/module/testing.js.map +1 -1
- package/lib/module/tilemap/chunkStats.js +27 -0
- package/lib/module/tilemap/chunkStats.js.map +1 -0
- package/lib/module/tilemap/definitions.js +308 -0
- package/lib/module/tilemap/definitions.js.map +1 -0
- package/lib/module/tilemap/errors.js +13 -0
- package/lib/module/tilemap/errors.js.map +1 -0
- package/lib/module/tilemap/index.js +10 -0
- package/lib/module/tilemap/index.js.map +1 -0
- package/lib/module/tilemap/movement.js +379 -0
- package/lib/module/tilemap/movement.js.map +1 -0
- package/lib/module/tilemap/queries.js +114 -0
- package/lib/module/tilemap/queries.js.map +1 -0
- package/lib/module/tilemap/tiledAdapter.js +141 -0
- package/lib/module/tilemap/tiledAdapter.js.map +1 -0
- package/lib/module/tilemap/types.js +4 -0
- package/lib/module/tilemap/types.js.map +1 -0
- package/lib/module/tilemap.js +4 -0
- package/lib/module/tilemap.js.map +1 -0
- package/lib/typescript/src/assets/defineAssets.d.ts +1 -1
- package/lib/typescript/src/assets/defineAssets.d.ts.map +1 -1
- package/lib/typescript/src/assets.d.ts +11 -0
- package/lib/typescript/src/assets.d.ts.map +1 -0
- package/lib/typescript/src/audio/createGameAudio.d.ts +5 -0
- package/lib/typescript/src/audio/createGameAudio.d.ts.map +1 -0
- package/lib/typescript/src/audio/errors.d.ts +6 -0
- package/lib/typescript/src/audio/errors.d.ts.map +1 -0
- package/lib/typescript/src/audio/index.d.ts +4 -0
- package/lib/typescript/src/audio/index.d.ts.map +1 -0
- package/lib/typescript/src/audio/resolver.d.ts +44 -0
- package/lib/typescript/src/audio/resolver.d.ts.map +1 -0
- package/lib/typescript/src/audio/types.d.ts +42 -0
- package/lib/typescript/src/audio/types.d.ts.map +1 -0
- package/lib/typescript/src/audio.d.ts +8 -0
- package/lib/typescript/src/audio.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/bounds.d.ts +25 -0
- package/lib/typescript/src/camera2d/bounds.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/extents.d.ts +17 -0
- package/lib/typescript/src/camera2d/extents.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/follow.d.ts +24 -0
- package/lib/typescript/src/camera2d/follow.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/index.d.ts +19 -0
- package/lib/typescript/src/camera2d/index.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/interpolation.d.ts +17 -0
- package/lib/typescript/src/camera2d/interpolation.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/shake.d.ts +20 -0
- package/lib/typescript/src/camera2d/shake.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/transform.d.ts +44 -0
- package/lib/typescript/src/camera2d/transform.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/types.d.ts +74 -0
- package/lib/typescript/src/camera2d/types.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/validation.d.ts +30 -0
- package/lib/typescript/src/camera2d/validation.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/visibility.d.ts +47 -0
- package/lib/typescript/src/camera2d/visibility.d.ts.map +1 -0
- package/lib/typescript/src/camera2d.d.ts +7 -0
- package/lib/typescript/src/camera2d.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/colliders.d.ts +120 -0
- package/lib/typescript/src/collision2d/colliders.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/debug.d.ts +67 -0
- package/lib/typescript/src/collision2d/debug.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/filters.d.ts +28 -0
- package/lib/typescript/src/collision2d/filters.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/index.d.ts +17 -0
- package/lib/typescript/src/collision2d/index.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/intersections.d.ts +24 -0
- package/lib/typescript/src/collision2d/intersections.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/manifolds.d.ts +39 -0
- package/lib/typescript/src/collision2d/manifolds.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/segments.d.ts +24 -0
- package/lib/typescript/src/collision2d/segments.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/spatialHash.d.ts +50 -0
- package/lib/typescript/src/collision2d/spatialHash.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/sweeps.d.ts +60 -0
- package/lib/typescript/src/collision2d/sweeps.d.ts.map +1 -0
- package/lib/typescript/src/collision2d.d.ts +7 -0
- package/lib/typescript/src/collision2d.d.ts.map +1 -0
- package/lib/typescript/src/core/input/buttonPad.d.ts +59 -0
- package/lib/typescript/src/core/input/buttonPad.d.ts.map +1 -0
- package/lib/typescript/src/core/input/createInputBuffer.d.ts +1 -1
- package/lib/typescript/src/core/input/createInputBuffer.d.ts.map +1 -1
- package/lib/typescript/src/core/input/types.d.ts +7 -0
- package/lib/typescript/src/core/input/types.d.ts.map +1 -1
- package/lib/typescript/src/core/session/createGameSession.d.ts +4 -2
- package/lib/typescript/src/core/session/createGameSession.d.ts.map +1 -1
- package/lib/typescript/src/core/session/deepFreeze.d.ts +21 -1
- package/lib/typescript/src/core/session/deepFreeze.d.ts.map +1 -1
- package/lib/typescript/src/core/session/diagnostics.d.ts +2 -0
- package/lib/typescript/src/core/session/diagnostics.d.ts.map +1 -1
- package/lib/typescript/src/core/session/types.d.ts +69 -4
- package/lib/typescript/src/core/session/types.d.ts.map +1 -1
- package/lib/typescript/src/definition/defineGame.d.ts +12 -1
- package/lib/typescript/src/definition/defineGame.d.ts.map +1 -1
- package/lib/typescript/src/definition/types.d.ts +10 -1
- package/lib/typescript/src/definition/types.d.ts.map +1 -1
- package/lib/typescript/src/events/defineGameEvents.d.ts +26 -0
- package/lib/typescript/src/events/defineGameEvents.d.ts.map +1 -0
- package/lib/typescript/src/events/errors.d.ts +12 -0
- package/lib/typescript/src/events/errors.d.ts.map +1 -0
- package/lib/typescript/src/events/index.d.ts +6 -0
- package/lib/typescript/src/events/index.d.ts.map +1 -0
- package/lib/typescript/src/events/payload.d.ts +21 -0
- package/lib/typescript/src/events/payload.d.ts.map +1 -0
- package/lib/typescript/src/events/seed.d.ts +3 -0
- package/lib/typescript/src/events/seed.d.ts.map +1 -0
- package/lib/typescript/src/events/types.d.ts +42 -0
- package/lib/typescript/src/events/types.d.ts.map +1 -0
- package/lib/typescript/src/events.d.ts +12 -0
- package/lib/typescript/src/events.d.ts.map +1 -0
- package/lib/typescript/src/geometry/helpers.d.ts +35 -0
- package/lib/typescript/src/geometry/helpers.d.ts.map +1 -0
- package/lib/typescript/src/geometry/index.d.ts +4 -0
- package/lib/typescript/src/geometry/index.d.ts.map +1 -0
- package/lib/typescript/src/geometry/types.d.ts +49 -0
- package/lib/typescript/src/geometry/types.d.ts.map +1 -1
- package/lib/typescript/src/geometry/validation.d.ts +44 -0
- package/lib/typescript/src/geometry/validation.d.ts.map +1 -0
- package/lib/typescript/src/geometry.d.ts +7 -0
- package/lib/typescript/src/geometry.d.ts.map +1 -0
- package/lib/typescript/src/haptics/createGameHaptics.d.ts +3 -0
- package/lib/typescript/src/haptics/createGameHaptics.d.ts.map +1 -0
- package/lib/typescript/src/haptics/errors.d.ts +6 -0
- package/lib/typescript/src/haptics/errors.d.ts.map +1 -0
- package/lib/typescript/src/haptics/index.d.ts +4 -0
- package/lib/typescript/src/haptics/index.d.ts.map +1 -0
- package/lib/typescript/src/haptics/resolver.d.ts +22 -0
- package/lib/typescript/src/haptics/resolver.d.ts.map +1 -0
- package/lib/typescript/src/haptics/types.d.ts +37 -0
- package/lib/typescript/src/haptics/types.d.ts.map +1 -0
- package/lib/typescript/src/haptics.d.ts +8 -0
- package/lib/typescript/src/haptics.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +10 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/particles/createParticleSystem.d.ts +5 -0
- package/lib/typescript/src/particles/createParticleSystem.d.ts.map +1 -0
- package/lib/typescript/src/particles/defineParticleEffect.d.ts +3 -0
- package/lib/typescript/src/particles/defineParticleEffect.d.ts.map +1 -0
- package/lib/typescript/src/particles/errors.d.ts +5 -0
- package/lib/typescript/src/particles/errors.d.ts.map +1 -0
- package/lib/typescript/src/particles/index.d.ts +6 -0
- package/lib/typescript/src/particles/index.d.ts.map +1 -0
- package/lib/typescript/src/particles/sampling.d.ts +54 -0
- package/lib/typescript/src/particles/sampling.d.ts.map +1 -0
- package/lib/typescript/src/particles/types.d.ts +292 -0
- package/lib/typescript/src/particles/types.d.ts.map +1 -0
- package/lib/typescript/src/particles.d.ts +2 -0
- package/lib/typescript/src/particles.d.ts.map +1 -0
- package/lib/typescript/src/react/GameButtonPad.d.ts +84 -0
- package/lib/typescript/src/react/GameButtonPad.d.ts.map +1 -0
- package/lib/typescript/src/react/GamePointerInput.d.ts.map +1 -1
- package/lib/typescript/src/react/GameView.d.ts +27 -1
- package/lib/typescript/src/react/GameView.d.ts.map +1 -1
- package/lib/typescript/src/react/assets/createGameAssetStore.d.ts.map +1 -1
- package/lib/typescript/src/react/assets/useGameAssets.d.ts.map +1 -1
- package/lib/typescript/src/react/bindAppLifecycle.d.ts +7 -1
- package/lib/typescript/src/react/bindAppLifecycle.d.ts.map +1 -1
- package/lib/typescript/src/react/bindGameSession.d.ts.map +1 -1
- package/lib/typescript/src/react/camera2d/GameLayer2D.d.ts +24 -0
- package/lib/typescript/src/react/camera2d/GameLayer2D.d.ts.map +1 -0
- package/lib/typescript/src/react/camera2d/defineGameCamera2D.d.ts +44 -0
- package/lib/typescript/src/react/camera2d/defineGameCamera2D.d.ts.map +1 -0
- package/lib/typescript/src/react/camera2d/usePresentedCameraBinding.d.ts +22 -0
- package/lib/typescript/src/react/camera2d/usePresentedCameraBinding.d.ts.map +1 -0
- package/lib/typescript/src/react/cleanupList.d.ts +21 -0
- package/lib/typescript/src/react/cleanupList.d.ts.map +1 -0
- package/lib/typescript/src/react/instrumentation.d.ts +33 -3
- package/lib/typescript/src/react/instrumentation.d.ts.map +1 -1
- package/lib/typescript/src/react/lifecycleSource.d.ts +21 -0
- package/lib/typescript/src/react/lifecycleSource.d.ts.map +1 -0
- package/lib/typescript/src/react/particles/ParticleView.d.ts +65 -0
- package/lib/typescript/src/react/particles/ParticleView.d.ts.map +1 -0
- package/lib/typescript/src/react/particles/culling.d.ts +70 -0
- package/lib/typescript/src/react/particles/culling.d.ts.map +1 -0
- package/lib/typescript/src/react/particles/index.d.ts +7 -0
- package/lib/typescript/src/react/particles/index.d.ts.map +1 -0
- package/lib/typescript/src/react/particles/spriteXForm.d.ts +28 -0
- package/lib/typescript/src/react/particles/spriteXForm.d.ts.map +1 -0
- package/lib/typescript/src/react/particles/useParticlePresentation.d.ts +48 -0
- package/lib/typescript/src/react/particles/useParticlePresentation.d.ts.map +1 -0
- package/lib/typescript/src/react/pointerBinding.d.ts +38 -8
- package/lib/typescript/src/react/pointerBinding.d.ts.map +1 -1
- package/lib/typescript/src/react/pointerCamera.d.ts +20 -0
- package/lib/typescript/src/react/pointerCamera.d.ts.map +1 -0
- package/lib/typescript/src/react/pointerCoalescer.d.ts +17 -1
- package/lib/typescript/src/react/pointerCoalescer.d.ts.map +1 -1
- package/lib/typescript/src/react/sprites/GameSprite.d.ts +3 -10
- package/lib/typescript/src/react/sprites/GameSprite.d.ts.map +1 -1
- package/lib/typescript/src/react/sprites/GameWorld2D.d.ts +51 -6
- package/lib/typescript/src/react/sprites/GameWorld2D.d.ts.map +1 -1
- package/lib/typescript/src/react/sprites/Sprite.d.ts.map +1 -1
- package/lib/typescript/src/react/sprites/SpriteBatch.d.ts +22 -1
- package/lib/typescript/src/react/sprites/SpriteBatch.d.ts.map +1 -1
- package/lib/typescript/src/react/sprites/batchVisibility.d.ts +28 -0
- package/lib/typescript/src/react/sprites/batchVisibility.d.ts.map +1 -0
- package/lib/typescript/src/react/sprites/spriteSelection.d.ts +58 -0
- package/lib/typescript/src/react/sprites/spriteSelection.d.ts.map +1 -0
- package/lib/typescript/src/react/sprites/spriteTransform.d.ts +27 -12
- package/lib/typescript/src/react/sprites/spriteTransform.d.ts.map +1 -1
- package/lib/typescript/src/react/tilemap/TileMapLayer2D.d.ts +69 -0
- package/lib/typescript/src/react/tilemap/TileMapLayer2D.d.ts.map +1 -0
- package/lib/typescript/src/react/tilemap/tilePresentation.d.ts +217 -0
- package/lib/typescript/src/react/tilemap/tilePresentation.d.ts.map +1 -0
- package/lib/typescript/src/react/useGameSession.d.ts +48 -0
- package/lib/typescript/src/react/useGameSession.d.ts.map +1 -0
- package/lib/typescript/src/react/useGameSessionStatus.d.ts +23 -0
- package/lib/typescript/src/react/useGameSessionStatus.d.ts.map +1 -0
- package/lib/typescript/src/react/viewportBinding.d.ts +5 -1
- package/lib/typescript/src/react/viewportBinding.d.ts.map +1 -1
- package/lib/typescript/src/react.d.ts +18 -1
- package/lib/typescript/src/react.d.ts.map +1 -1
- package/lib/typescript/src/scene/defineScene.d.ts +22 -2
- package/lib/typescript/src/scene/defineScene.d.ts.map +1 -1
- package/lib/typescript/src/scene/types.d.ts +24 -4
- package/lib/typescript/src/scene/types.d.ts.map +1 -1
- package/lib/typescript/src/sprites/sampleSpriteClip.d.ts +26 -2
- package/lib/typescript/src/sprites/sampleSpriteClip.d.ts.map +1 -1
- package/lib/typescript/src/sprites/spriteAnimationState.d.ts +6 -7
- package/lib/typescript/src/sprites/spriteAnimationState.d.ts.map +1 -1
- package/lib/typescript/src/sprites.d.ts +10 -0
- package/lib/typescript/src/sprites.d.ts.map +1 -0
- package/lib/typescript/src/storage/adapters/asyncStorage.d.ts +18 -0
- package/lib/typescript/src/storage/adapters/asyncStorage.d.ts.map +1 -0
- package/lib/typescript/src/storage/adapters/memory.d.ts +16 -0
- package/lib/typescript/src/storage/adapters/memory.d.ts.map +1 -0
- package/lib/typescript/src/storage/errors.d.ts +37 -0
- package/lib/typescript/src/storage/errors.d.ts.map +1 -0
- package/lib/typescript/src/storage/index.d.ts +11 -0
- package/lib/typescript/src/storage/index.d.ts.map +1 -0
- package/lib/typescript/src/storage/schema.d.ts +22 -0
- package/lib/typescript/src/storage/schema.d.ts.map +1 -0
- package/lib/typescript/src/storage/serialization.d.ts +23 -0
- package/lib/typescript/src/storage/serialization.d.ts.map +1 -0
- package/lib/typescript/src/storage/store.d.ts +3 -0
- package/lib/typescript/src/storage/store.d.ts.map +1 -0
- package/lib/typescript/src/storage/types.d.ts +69 -0
- package/lib/typescript/src/storage/types.d.ts.map +1 -0
- package/lib/typescript/src/storage/validation.d.ts +24 -0
- package/lib/typescript/src/storage/validation.d.ts.map +1 -0
- package/lib/typescript/src/storage.d.ts +2 -0
- package/lib/typescript/src/storage.d.ts.map +1 -0
- package/lib/typescript/src/testing.d.ts +1 -0
- package/lib/typescript/src/testing.d.ts.map +1 -1
- package/lib/typescript/src/tilemap/chunkStats.d.ts +14 -0
- package/lib/typescript/src/tilemap/chunkStats.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/definitions.d.ts +38 -0
- package/lib/typescript/src/tilemap/definitions.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/errors.d.ts +7 -0
- package/lib/typescript/src/tilemap/errors.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/index.d.ts +8 -0
- package/lib/typescript/src/tilemap/index.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/movement.d.ts +52 -0
- package/lib/typescript/src/tilemap/movement.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/queries.d.ts +21 -0
- package/lib/typescript/src/tilemap/queries.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/tiledAdapter.d.ts +32 -0
- package/lib/typescript/src/tilemap/tiledAdapter.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/types.d.ts +127 -0
- package/lib/typescript/src/tilemap/types.d.ts.map +1 -0
- package/lib/typescript/src/tilemap.d.ts +2 -0
- package/lib/typescript/src/tilemap.d.ts.map +1 -0
- package/package.json +100 -10
- package/src/assets/defineAssets.ts +31 -5
- package/src/assets.ts +27 -0
- package/src/audio/createGameAudio.ts +749 -0
- package/src/audio/errors.ts +12 -0
- package/src/audio/index.ts +9 -0
- package/src/audio/resolver.ts +74 -0
- package/src/audio/types.ts +47 -0
- package/src/audio.ts +13 -0
- package/src/camera2d/bounds.ts +69 -0
- package/src/camera2d/extents.ts +25 -0
- package/src/camera2d/follow.ts +165 -0
- package/src/camera2d/index.ts +29 -0
- package/src/camera2d/interpolation.ts +113 -0
- package/src/camera2d/shake.ts +90 -0
- package/src/camera2d/transform.ts +148 -0
- package/src/camera2d/types.ts +73 -0
- package/src/camera2d/validation.ts +126 -0
- package/src/camera2d/visibility.ts +181 -0
- package/src/camera2d.ts +6 -0
- package/src/collision2d/colliders.ts +292 -0
- package/src/collision2d/debug.ts +133 -0
- package/src/collision2d/filters.ts +48 -0
- package/src/collision2d/index.ts +74 -0
- package/src/collision2d/intersections.ts +82 -0
- package/src/collision2d/manifolds.ts +191 -0
- package/src/collision2d/segments.ts +176 -0
- package/src/collision2d/spatialHash.ts +211 -0
- package/src/collision2d/sweeps.ts +269 -0
- package/src/collision2d.ts +6 -0
- package/src/core/input/buttonPad.ts +235 -0
- package/src/core/input/createInputBuffer.ts +95 -14
- package/src/core/input/types.ts +7 -0
- package/src/core/session/createGameSession.ts +480 -53
- package/src/core/session/deepFreeze.ts +104 -3
- package/src/core/session/diagnostics.ts +2 -0
- package/src/core/session/types.ts +77 -4
- package/src/definition/defineGame.ts +61 -3
- package/src/definition/types.ts +10 -0
- package/src/events/defineGameEvents.ts +46 -0
- package/src/events/errors.ts +14 -0
- package/src/events/index.ts +14 -0
- package/src/events/payload.ts +234 -0
- package/src/events/seed.ts +33 -0
- package/src/events/types.ts +53 -0
- package/src/events.ts +20 -0
- package/src/geometry/helpers.ts +136 -0
- package/src/geometry/index.ts +14 -0
- package/src/geometry/types.ts +54 -0
- package/src/geometry/validation.ts +131 -0
- package/src/geometry.ts +6 -0
- package/src/haptics/createGameHaptics.ts +214 -0
- package/src/haptics/errors.ts +12 -0
- package/src/haptics/index.ts +3 -0
- package/src/haptics/resolver.ts +58 -0
- package/src/haptics/types.ts +48 -0
- package/src/haptics.ts +7 -0
- package/src/index.ts +37 -1
- package/src/particles/createParticleSystem.ts +505 -0
- package/src/particles/defineParticleEffect.ts +164 -0
- package/src/particles/errors.ts +6 -0
- package/src/particles/index.ts +5 -0
- package/src/particles/sampling.ts +141 -0
- package/src/particles/types.ts +327 -0
- package/src/particles.ts +1 -0
- package/src/react/GameButtonPad.tsx +436 -0
- package/src/react/GamePointerInput.tsx +73 -8
- package/src/react/GameView.tsx +160 -61
- package/src/react/assets/createGameAssetStore.ts +140 -107
- package/src/react/assets/useGameAssets.ts +63 -31
- package/src/react/bindAppLifecycle.ts +55 -19
- package/src/react/bindGameSession.ts +12 -2
- package/src/react/camera2d/GameLayer2D.tsx +43 -0
- package/src/react/camera2d/defineGameCamera2D.ts +59 -0
- package/src/react/camera2d/usePresentedCameraBinding.ts +185 -0
- package/src/react/cleanupList.ts +48 -0
- package/src/react/instrumentation.ts +31 -3
- package/src/react/lifecycleSource.ts +58 -0
- package/src/react/particles/ParticleView.tsx +358 -0
- package/src/react/particles/culling.ts +145 -0
- package/src/react/particles/index.ts +6 -0
- package/src/react/particles/spriteXForm.ts +72 -0
- package/src/react/particles/useParticlePresentation.ts +261 -0
- package/src/react/pointerBinding.ts +74 -16
- package/src/react/pointerCamera.ts +33 -0
- package/src/react/pointerCoalescer.ts +36 -10
- package/src/react/sprites/GameSprite.tsx +4 -33
- package/src/react/sprites/GameWorld2D.tsx +113 -7
- package/src/react/sprites/Sprite.tsx +51 -72
- package/src/react/sprites/SpriteBatch.tsx +74 -22
- package/src/react/sprites/batchVisibility.ts +76 -0
- package/src/react/sprites/spriteSelection.ts +133 -0
- package/src/react/sprites/spriteTransform.ts +46 -26
- package/src/react/tilemap/TileMapLayer2D.tsx +274 -0
- package/src/react/tilemap/tilePresentation.ts +491 -0
- package/src/react/useGameSession.ts +90 -0
- package/src/react/useGameSessionStatus.ts +53 -0
- package/src/react/viewportBinding.ts +5 -1
- package/src/react.ts +18 -1
- package/src/scene/defineScene.ts +47 -5
- package/src/scene/types.ts +37 -3
- package/src/sprites/sampleSpriteClip.ts +82 -14
- package/src/sprites/spriteAnimationState.ts +29 -25
- package/src/sprites.ts +22 -0
- package/src/storage/adapters/asyncStorage.ts +77 -0
- package/src/storage/adapters/memory.ts +58 -0
- package/src/storage/errors.ts +88 -0
- package/src/storage/index.ts +18 -0
- package/src/storage/schema.ts +147 -0
- package/src/storage/serialization.ts +248 -0
- package/src/storage/store.ts +380 -0
- package/src/storage/types.ts +76 -0
- package/src/storage/validation.ts +102 -0
- package/src/storage.ts +1 -0
- package/src/testing.ts +4 -0
- package/src/tilemap/chunkStats.ts +24 -0
- package/src/tilemap/definitions.ts +327 -0
- package/src/tilemap/errors.ts +11 -0
- package/src/tilemap/index.ts +10 -0
- package/src/tilemap/movement.ts +368 -0
- package/src/tilemap/queries.ts +136 -0
- package/src/tilemap/tiledAdapter.ts +165 -0
- package/src/tilemap/types.ts +119 -0
- package/src/tilemap.ts +1 -0
|
@@ -22,6 +22,39 @@
|
|
|
22
22
|
|
|
23
23
|
import type { DeepReadonly } from './types';
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Supported snapshot domain (GS-SCENE-03): plain records
|
|
27
|
+
* (`Object.prototype` or `null` prototype), arrays, and scalar values.
|
|
28
|
+
* Everything else — functions, symbols, bigints, and class instances
|
|
29
|
+
* (Map, Set, Date, typed arrays, custom classes, …) — is rejected at the
|
|
30
|
+
* publication boundary because freezing cannot secure it (`Object.freeze`
|
|
31
|
+
* on a Map does not freeze its entries; a frozen function stays callable).
|
|
32
|
+
*/
|
|
33
|
+
export class SnapshotDomainError extends Error {
|
|
34
|
+
/** Dot/bracket path from the snapshot root to the offending value. */
|
|
35
|
+
readonly path: string;
|
|
36
|
+
/** The scene whose snapshot was rejected, when the session supplied it. */
|
|
37
|
+
readonly scene?: string;
|
|
38
|
+
constructor(path: string, detail: string, scene?: string) {
|
|
39
|
+
super(
|
|
40
|
+
`Unsupported snapshot value at ${path}: ${detail}${
|
|
41
|
+
scene === undefined ? '' : ` (scene "${scene}")`
|
|
42
|
+
}. Snapshots must contain only plain records, arrays, and scalar values.`,
|
|
43
|
+
);
|
|
44
|
+
this.name = 'SnapshotDomainError';
|
|
45
|
+
this.path = path;
|
|
46
|
+
if (scene !== undefined) {
|
|
47
|
+
this.scene = scene;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Context the session attaches so rejections name the offending scene. */
|
|
53
|
+
export interface SnapshotFreezeContext {
|
|
54
|
+
readonly scene?: string;
|
|
55
|
+
readonly tick?: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
25
58
|
/** Whether a string is a canonical array index (`0 <= i < 2^32 - 1`). */
|
|
26
59
|
/** Decimal digit count of a non-negative integer (0 <= value < 1e11). */
|
|
27
60
|
function digitLength(value: number): number {
|
|
@@ -80,19 +113,77 @@ function isArrayIndexKey(key: string): boolean {
|
|
|
80
113
|
return value <= 0xffffffff - 1;
|
|
81
114
|
}
|
|
82
115
|
|
|
116
|
+
/** Whether a value is a plain record (`Object.prototype` or `null` prototype). */
|
|
117
|
+
function isPlainRecord(node: object): boolean {
|
|
118
|
+
const prototype = Object.getPrototypeOf(node);
|
|
119
|
+
return prototype === Object.prototype || prototype === null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Name an unsupported value for an actionable rejection message. */
|
|
123
|
+
function describeUnsupported(node: unknown): string {
|
|
124
|
+
if (typeof node === 'function') {
|
|
125
|
+
return 'functions are not part of the snapshot domain';
|
|
126
|
+
}
|
|
127
|
+
if (typeof node === 'symbol') {
|
|
128
|
+
return 'symbols are not part of the snapshot domain';
|
|
129
|
+
}
|
|
130
|
+
if (typeof node === 'bigint') {
|
|
131
|
+
return 'bigints are not part of the snapshot domain';
|
|
132
|
+
}
|
|
133
|
+
const name =
|
|
134
|
+
typeof node === 'object' && node !== null
|
|
135
|
+
? (node as { constructor?: { name?: unknown } }).constructor?.name
|
|
136
|
+
: undefined;
|
|
137
|
+
const label = typeof name === 'string' && name !== '' ? `${name} instances` : 'class instances';
|
|
138
|
+
return `${label} are not part of the snapshot domain (only plain records and arrays are supported)`;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Format a key-path segment stack as `a.b[0]` (root renders `<root>`). */
|
|
142
|
+
function formatPath(path: readonly (string | number | symbol)[]): string {
|
|
143
|
+
if (path.length === 0) {
|
|
144
|
+
return '<root>';
|
|
145
|
+
}
|
|
146
|
+
let out = '';
|
|
147
|
+
for (const segment of path) {
|
|
148
|
+
if (typeof segment === 'number') {
|
|
149
|
+
out += `[${segment}]`;
|
|
150
|
+
} else if (typeof segment === 'symbol') {
|
|
151
|
+
out += `[${String(segment)}]`;
|
|
152
|
+
} else if (out === '') {
|
|
153
|
+
out = segment;
|
|
154
|
+
} else {
|
|
155
|
+
out += `.${segment}`;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return out;
|
|
159
|
+
}
|
|
160
|
+
|
|
83
161
|
export interface DeepFreezer {
|
|
84
|
-
<T>(value: T): DeepReadonly<T>;
|
|
162
|
+
<T>(value: T, context?: SnapshotFreezeContext): DeepReadonly<T>;
|
|
85
163
|
}
|
|
86
164
|
|
|
87
165
|
export function createDeepFreeze(): DeepFreezer { const trusted = new WeakSet<object>();
|
|
88
166
|
|
|
89
|
-
return function deepFreeze<T>(value: T): DeepReadonly<T> {
|
|
167
|
+
return function deepFreeze<T>(value: T, context?: SnapshotFreezeContext): DeepReadonly<T> {
|
|
168
|
+
// Key path from the snapshot root, maintained as a segment stack and
|
|
169
|
+
// formatted only when a rejection needs it. try/finally is unnecessary:
|
|
170
|
+
// a throw abandons the traversal, and the stack is per call.
|
|
171
|
+
const path: (string | number | symbol)[] = [];
|
|
172
|
+
const reject = (node: unknown): never => {
|
|
173
|
+
throw new SnapshotDomainError(formatPath(path), describeUnsupported(node), context?.scene);
|
|
174
|
+
};
|
|
90
175
|
if (typeof value !== 'object' || value === null) {
|
|
176
|
+
if (typeof value === 'function' || typeof value === 'symbol' || typeof value === 'bigint') {
|
|
177
|
+
reject(value);
|
|
178
|
+
}
|
|
91
179
|
return value as DeepReadonly<T>;
|
|
92
180
|
}
|
|
93
181
|
const visiting = new WeakSet<object>();
|
|
94
182
|
const freeze = (node: unknown): void => {
|
|
95
183
|
if (typeof node !== 'object' || node === null) {
|
|
184
|
+
if (typeof node === 'function' || typeof node === 'symbol' || typeof node === 'bigint') {
|
|
185
|
+
reject(node);
|
|
186
|
+
}
|
|
96
187
|
return;
|
|
97
188
|
}
|
|
98
189
|
if (trusted.has(node) || visiting.has(node)) {
|
|
@@ -102,7 +193,9 @@ export function createDeepFreeze(): DeepFreezer { const trusted = new WeakSet<o
|
|
|
102
193
|
if (Array.isArray(node)) {
|
|
103
194
|
// Index fast path: avoids materialising an index-key array per array.
|
|
104
195
|
for (let index = 0; index < node.length; index += 1) {
|
|
196
|
+
path.push(index);
|
|
105
197
|
freeze(node[index]);
|
|
198
|
+
path.pop();
|
|
106
199
|
}
|
|
107
200
|
// F5: legal JavaScript arrays may also carry values on non-index
|
|
108
201
|
// string keys and symbol keys. Only own keys are reachable snapshot
|
|
@@ -134,20 +227,28 @@ export function createDeepFreeze(): DeepFreezer { const trusted = new WeakSet<o
|
|
|
134
227
|
continue;
|
|
135
228
|
}
|
|
136
229
|
if (!isArrayIndexKey(name)) {
|
|
230
|
+
path.push(name);
|
|
137
231
|
freeze((node as unknown as Record<PropertyKey, unknown>)[name]);
|
|
232
|
+
path.pop();
|
|
138
233
|
}
|
|
139
234
|
}
|
|
140
235
|
const symbols = Object.getOwnPropertySymbols(node);
|
|
141
236
|
for (let index = 0; index < symbols.length; index += 1) {
|
|
142
237
|
const symbol = symbols[index];
|
|
143
238
|
if (symbol !== undefined) {
|
|
239
|
+
path.push(symbol);
|
|
144
240
|
freeze((node as unknown as Record<PropertyKey, unknown>)[symbol]);
|
|
241
|
+
path.pop();
|
|
145
242
|
}
|
|
146
243
|
}
|
|
147
|
-
} else {
|
|
244
|
+
} else if (isPlainRecord(node)) {
|
|
148
245
|
for (const key of Reflect.ownKeys(node)) {
|
|
246
|
+
path.push(key);
|
|
149
247
|
freeze((node as Record<PropertyKey, unknown>)[key]);
|
|
248
|
+
path.pop();
|
|
150
249
|
}
|
|
250
|
+
} else {
|
|
251
|
+
reject(node);
|
|
151
252
|
}
|
|
152
253
|
Object.freeze(node);
|
|
153
254
|
trusted.add(node);
|
|
@@ -32,4 +32,6 @@ export interface SessionDiagnostics {
|
|
|
32
32
|
onCommitNotification(): void;
|
|
33
33
|
/** Listener count at publish time. */
|
|
34
34
|
onListenerCount(count: number): void;
|
|
35
|
+
/** Status-listener count after registration or removal (T10 control plane). */
|
|
36
|
+
onStatusListenerCount?(count: number): void;
|
|
35
37
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { InputMap, SceneMap } from '../../definition/types';
|
|
2
|
+
import type { GameEventDescriptor, GameEventEnvelope, InferGameEventMap } from '../../events/types';
|
|
2
3
|
import type { SceneSnapshot } from '../../scene/types';
|
|
3
4
|
import type { Viewport } from '../../viewport2d/types';
|
|
4
5
|
import type { InputController } from '../input/types';
|
|
@@ -15,6 +16,29 @@ export type DeepReadonly<T> = T extends (...arguments_: never[]) => unknown
|
|
|
15
16
|
/** Lifecycle states of a headless game session. */
|
|
16
17
|
export type GameSessionStatus = 'idle' | 'running' | 'paused' | 'disposed';
|
|
17
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Minimal read-only lifecycle surface for presentation layers (T20.3).
|
|
21
|
+
*
|
|
22
|
+
* Exposes exactly what a renderer-side consumer needs to follow its owning
|
|
23
|
+
* session — the current status and a way to observe transitions — and
|
|
24
|
+
* nothing it must not have: no `start`, `pause`, `press`, `setScene`, event
|
|
25
|
+
* subscription, or other session internals. `GameView` owns one source per
|
|
26
|
+
* session and supplies it to its renderer subtree; haptics and particle
|
|
27
|
+
* presentation consume it instead of casting to private session methods or
|
|
28
|
+
* reaching for module-global coordinators.
|
|
29
|
+
*/
|
|
30
|
+
export interface GameLifecycleSource {
|
|
31
|
+
/** The owning session's current lifecycle status. */
|
|
32
|
+
getStatus(): GameSessionStatus;
|
|
33
|
+
/**
|
|
34
|
+
* Observe lifecycle transitions. Returns a detach function. Subscribing
|
|
35
|
+
* to a disposed session returns a no-op detach: the terminal notification
|
|
36
|
+
* was already delivered, and `addStatusListener` follows the
|
|
37
|
+
* disposed-error policy for new subscribers.
|
|
38
|
+
*/
|
|
39
|
+
subscribe(listener: (status: GameSessionStatus) => void): () => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
18
42
|
/** One renderer-neutral simulation commit produced by a game session. */
|
|
19
43
|
export interface CommitFrameBase<TSnapshot> {
|
|
20
44
|
/** Snapshot immediately before the latest simulation update. */
|
|
@@ -60,7 +84,11 @@ export interface GameSubscription {
|
|
|
60
84
|
}
|
|
61
85
|
|
|
62
86
|
/** A closure-backed, headless running instance of one game definition. */
|
|
63
|
-
export interface GameSession<
|
|
87
|
+
export interface GameSession<
|
|
88
|
+
TScenes extends SceneMap = SceneMap,
|
|
89
|
+
TInput extends InputMap = InputMap,
|
|
90
|
+
TEventDefs extends Record<string, GameEventDescriptor<unknown>> = Record<string, never>,
|
|
91
|
+
> {
|
|
64
92
|
/** Current lifecycle status. */
|
|
65
93
|
readonly status: GameSessionStatus;
|
|
66
94
|
/** The active scene name, updated by transitions and restarts. */
|
|
@@ -73,12 +101,28 @@ export interface GameSession<TScenes extends SceneMap = SceneMap, TInput extends
|
|
|
73
101
|
start(): void;
|
|
74
102
|
/** Pause simulation and discard suspended wall time. */
|
|
75
103
|
pause(): void;
|
|
104
|
+
/**
|
|
105
|
+
* Observe lifecycle transitions at control frequency.
|
|
106
|
+
*
|
|
107
|
+
* The listener receives each actual status transition after it becomes
|
|
108
|
+
* authoritative (`idle`, `running`, `paused`, `disposed`); idempotent
|
|
109
|
+
* commands emit nothing, and no initial value is emitted on subscribe —
|
|
110
|
+
* read `status` for the snapshot. `disposed` is delivered exactly once
|
|
111
|
+
* before listeners are released. Listeners are called from a snapshot and
|
|
112
|
+
* a listener that issues another lifecycle command observes complete
|
|
113
|
+
* states; a throwing listener does not abort delivery, and the first
|
|
114
|
+
* failure is rethrown from the command after the pass completes. Status
|
|
115
|
+
* notifications are not render commits.
|
|
116
|
+
*/
|
|
117
|
+
addStatusListener(listener: (status: GameSessionStatus) => void): GameSubscription;
|
|
76
118
|
/**
|
|
77
119
|
* Transition to a declared scene.
|
|
78
120
|
*
|
|
79
|
-
* While running, the transition commits at the next
|
|
80
|
-
*
|
|
81
|
-
*
|
|
121
|
+
* While running, the transition commits at the next frame-driver callback
|
|
122
|
+
* — even when no fixed step is due — without advancing simulation tick or
|
|
123
|
+
* time. The target scene first updates at the next due fixed step. While
|
|
124
|
+
* idle or paused, it commits synchronously and publishes the new frame.
|
|
125
|
+
* Setting the current scene is an idempotent no-op.
|
|
82
126
|
*/
|
|
83
127
|
setScene(name: keyof TScenes): void;
|
|
84
128
|
/** Recreate the active scene with fresh state. */
|
|
@@ -93,10 +137,39 @@ export interface GameSession<TScenes extends SceneMap = SceneMap, TInput extends
|
|
|
93
137
|
* accumulated timing fraction at call time and is only meaningful for
|
|
94
138
|
* headless inspection. Rendering uses the UI-owned alpha clock; the
|
|
95
139
|
* envelope fields never change between commits.
|
|
140
|
+
*
|
|
141
|
+
* Event-time authority (GS-EVENT-02): this frame is the most recently
|
|
142
|
+
* PUBLISHED presentation frame, which can lag the authoritative tick
|
|
143
|
+
* when several simulation ticks run in one driver callback. Inside a
|
|
144
|
+
* game-event listener, the envelope (tick, scene, ordinal, payload) is
|
|
145
|
+
* the authority for that event — never re-read this frame to place the
|
|
146
|
+
* event. Put the data an effect needs into its small payload.
|
|
96
147
|
*/
|
|
97
148
|
getRenderFrame(): GameRenderFrame<TScenes>;
|
|
98
149
|
/** Observe simulation commits at commit frequency (never per display frame). */
|
|
99
150
|
addCommitListener(listener: (frame: CommitFrame<TScenes>) => void): GameSubscription;
|
|
151
|
+
/**
|
|
152
|
+
* Observe deterministic game events after they commit (T13).
|
|
153
|
+
*
|
|
154
|
+
* Each listener receives committed envelopes for the subscribed name in
|
|
155
|
+
* deterministic `(tick, ordinal)` order. Delivery happens after the
|
|
156
|
+
* source tick's authoritative state commits and never during the update
|
|
157
|
+
* itself. Listeners run from a per-tick snapshot taken before the
|
|
158
|
+
* tick's first delivery (GS-EVENT-01): a listener added during delivery
|
|
159
|
+
* receives only later ticks, and a removal prevents only future ticks —
|
|
160
|
+
* neither affects the envelopes already staged for the running tick.
|
|
161
|
+
* Lifecycle calls during delivery (pause, setScene, dispose) take
|
|
162
|
+
* effect after the staged batch completes: every snapshotted listener
|
|
163
|
+
* still runs exactly once for the tick. Removing a listener is
|
|
164
|
+
* idempotent. A throwing listener does not suppress siblings or alter
|
|
165
|
+
* simulation; the error is reported via a visible non-recursive sink
|
|
166
|
+
* (`console.error`). Simulation never awaits an async effect started
|
|
167
|
+
* by a listener.
|
|
168
|
+
*/
|
|
169
|
+
addGameEventListener<TName extends keyof InferGameEventMap<TEventDefs> & string>(
|
|
170
|
+
name: TName,
|
|
171
|
+
listener: (event: GameEventEnvelope<TName, InferGameEventMap<TEventDefs>[TName]>) => void | Promise<void>,
|
|
172
|
+
): GameSubscription;
|
|
100
173
|
}
|
|
101
174
|
|
|
102
175
|
/** Error thrown when live work is requested from a disposed session. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AssetGroupMap } from '../assets/types';
|
|
2
|
+
import type { GameEventDescriptor } from '../events/types';
|
|
2
3
|
import type { GameDefinition, InputMap, SceneMap } from './types';
|
|
3
4
|
|
|
4
5
|
type SceneActions<TScene> = TScene extends { readonly __actionType?: infer TAction }
|
|
@@ -29,6 +30,33 @@ type ValidateSceneTransitions<TScenes extends SceneMap> =
|
|
|
29
30
|
? unknown
|
|
30
31
|
: { readonly __undeclaredSceneTransitions: UndeclaredSceneTransitions<TScenes> };
|
|
31
32
|
|
|
33
|
+
type SceneEmits<TScene> = TScene extends { readonly __emitType?: infer TEmits }
|
|
34
|
+
? Exclude<TEmits, undefined>
|
|
35
|
+
: never;
|
|
36
|
+
|
|
37
|
+
type UndeclaredSceneEmits<
|
|
38
|
+
TScenes extends SceneMap,
|
|
39
|
+
TEventDefs extends Record<string, GameEventDescriptor<unknown>>,
|
|
40
|
+
> = TEventDefs extends Record<string, never>
|
|
41
|
+
? SceneEmits<TScenes[keyof TScenes]>
|
|
42
|
+
: Exclude<SceneEmits<TScenes[keyof TScenes]>, keyof TEventDefs & string>;
|
|
43
|
+
|
|
44
|
+
type ValidateSceneEmits<
|
|
45
|
+
TScenes extends SceneMap,
|
|
46
|
+
TEventDefs extends Record<string, GameEventDescriptor<unknown>>,
|
|
47
|
+
> = UndeclaredSceneEmits<TScenes, TEventDefs> extends never
|
|
48
|
+
? unknown
|
|
49
|
+
: { readonly __undeclaredSceneEmits: UndeclaredSceneEmits<TScenes, TEventDefs> };
|
|
50
|
+
|
|
51
|
+
type ValidateEventsWhenScenesEmit<
|
|
52
|
+
TScenes extends SceneMap,
|
|
53
|
+
TEventDefs extends Record<string, GameEventDescriptor<unknown>>,
|
|
54
|
+
> = SceneEmits<TScenes[keyof TScenes]> extends never
|
|
55
|
+
? unknown
|
|
56
|
+
: TEventDefs extends Record<string, never>
|
|
57
|
+
? { readonly __eventsRequired: 'scenes declare emits but game has no events map' }
|
|
58
|
+
: unknown;
|
|
59
|
+
|
|
32
60
|
/**
|
|
33
61
|
* Declare a game.
|
|
34
62
|
*
|
|
@@ -81,14 +109,44 @@ export function defineGame<
|
|
|
81
109
|
const TInput extends InputMap = InputMap,
|
|
82
110
|
const TInitialScene extends keyof TScenes = keyof TScenes,
|
|
83
111
|
const TAssets extends AssetGroupMap = AssetGroupMap,
|
|
112
|
+
const TEventDefs extends Record<string, GameEventDescriptor<unknown>> = Record<string, never>,
|
|
84
113
|
>(
|
|
85
|
-
definition: GameDefinition<TScenes, TInput, TInitialScene, TAssets> &
|
|
114
|
+
definition: GameDefinition<TScenes, TInput, TInitialScene, TAssets, TEventDefs> &
|
|
86
115
|
ValidateSceneActions<TScenes, TInput> &
|
|
87
|
-
ValidateSceneTransitions<TScenes
|
|
88
|
-
|
|
116
|
+
ValidateSceneTransitions<TScenes> &
|
|
117
|
+
ValidateSceneEmits<TScenes, TEventDefs> &
|
|
118
|
+
ValidateEventsWhenScenesEmit<TScenes, TEventDefs>,
|
|
119
|
+
): GameDefinition<TScenes, TInput, TInitialScene, TAssets, TEventDefs> {
|
|
89
120
|
// The viewport config is part of the public session surface; freeze it so a
|
|
90
121
|
// caller cannot mutate a live game's coordinate authority.
|
|
91
122
|
Object.freeze(definition.viewport.logicalSize);
|
|
92
123
|
Object.freeze(definition.viewport);
|
|
124
|
+
if (definition.events !== undefined) {
|
|
125
|
+
Object.freeze(definition.events);
|
|
126
|
+
// Runtime identity check: every scene that declares `events` must reference
|
|
127
|
+
// the same object as the game's `events`. This catches two different
|
|
128
|
+
// `defineGameEvents` instances with compatible shapes that would otherwise
|
|
129
|
+
// be structurally compatible at the type level.
|
|
130
|
+
for (const [name, scene] of Object.entries(definition.scenes)) {
|
|
131
|
+
const s = scene as unknown as { events?: unknown; emits?: readonly string[] };
|
|
132
|
+
if (s.events !== undefined && s.events !== definition.events) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`Scene "${name}" is bound to a different events object than the game. Pass the same defineGameEvents() result to both defineScene({ events }) and defineGame({ events }).`,
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (s.events === undefined && s.emits !== undefined && s.emits.length > 0) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`Scene "${name}" declares emits but is not bound to the game's events. Pass \`events\` to defineScene.`,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
for (const [name, scene] of Object.entries(definition.scenes)) {
|
|
145
|
+
const s = scene as unknown as { events?: unknown; emits?: readonly string[] };
|
|
146
|
+
if (s.events !== undefined) {
|
|
147
|
+
throw new Error(`Scene "${name}" is bound to events but the game has no events map`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
93
151
|
return definition;
|
|
94
152
|
}
|
package/src/definition/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AssetGroupMap, GameAssetManifest } from '../assets/types';
|
|
2
|
+
import type { GameEventDescriptor } from '../events/types';
|
|
2
3
|
import type { Viewport } from '../viewport2d/types';
|
|
3
4
|
|
|
4
5
|
/** The button action supported by the runtime. */
|
|
@@ -37,6 +38,12 @@ export interface SceneDefinitionMarker {
|
|
|
37
38
|
readonly __actionType?: string;
|
|
38
39
|
/** @internal Type witness for transition targets declared by this scene. */
|
|
39
40
|
readonly __transitionType?: string;
|
|
41
|
+
/** @internal Type witness for emitted event names. */
|
|
42
|
+
readonly __emitType?: string;
|
|
43
|
+
/** @internal Type witness for the game event map. */
|
|
44
|
+
readonly __eventMapType?: Record<string, unknown>;
|
|
45
|
+
/** @internal Type witness for the branded event definitions identity. */
|
|
46
|
+
readonly __eventDefsType?: Record<string, GameEventDescriptor<unknown>>;
|
|
40
47
|
}
|
|
41
48
|
|
|
42
49
|
/** The collection of functional scenes declared by a game. */
|
|
@@ -53,6 +60,7 @@ export interface GameDefinition<
|
|
|
53
60
|
TInput extends InputMap = InputMap,
|
|
54
61
|
TInitialScene extends keyof TScenes = keyof TScenes,
|
|
55
62
|
TAssets extends AssetGroupMap = AssetGroupMap,
|
|
63
|
+
TEventDefs extends Record<string, GameEventDescriptor<unknown>> = Record<string, never>,
|
|
56
64
|
> {
|
|
57
65
|
/** The viewport configuration of the game. */
|
|
58
66
|
readonly viewport: Viewport;
|
|
@@ -64,4 +72,6 @@ export interface GameDefinition<
|
|
|
64
72
|
readonly scenes: TScenes;
|
|
65
73
|
/** The scene created first when a session starts. */
|
|
66
74
|
readonly initialScene: TInitialScene;
|
|
75
|
+
/** Typed game event declarations (T13). Absence keeps the no-event fast path. */
|
|
76
|
+
readonly events?: TEventDefs;
|
|
67
77
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BrandedGameEventDefs, GameEventDescriptor } from './types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create a type witness for one event payload.
|
|
5
|
+
*
|
|
6
|
+
* `gameEvent` owns no runtime resource — it returns a frozen empty
|
|
7
|
+
* descriptor whose generic preserves the payload type. Payload shapes are
|
|
8
|
+
* validated when events are staged, not when they are declared.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const events = defineGameEvents({
|
|
13
|
+
* 'brick-hit': gameEvent<{ brickId: string; point: Point2D }>(),
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export function gameEvent<TPayload>(): GameEventDescriptor<TPayload> {
|
|
18
|
+
return Object.freeze({}) as GameEventDescriptor<TPayload>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function isValidEventName(name: string): boolean {
|
|
22
|
+
return name.length > 0 && name.length <= 128 && !name.includes('\0');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Define and freeze a game event map.
|
|
27
|
+
*
|
|
28
|
+
* Validates every name, freezes the declaration map and its entries,
|
|
29
|
+
* and preserves literal inference so `keyof typeof events` and the
|
|
30
|
+
* payload types flow through `defineGame`, scenes, and subscriptions
|
|
31
|
+
* without duplicate author-written unions.
|
|
32
|
+
*/
|
|
33
|
+
export function defineGameEvents<const T extends Record<string, GameEventDescriptor<unknown>>>(
|
|
34
|
+
definitions: T,
|
|
35
|
+
): BrandedGameEventDefs<T> {
|
|
36
|
+
for (const [name, descriptor] of Object.entries(definitions)) {
|
|
37
|
+
if (!isValidEventName(name)) {
|
|
38
|
+
throw new Error(`Invalid game event name: "${name}"`);
|
|
39
|
+
}
|
|
40
|
+
if (descriptor === null || typeof descriptor !== 'object') {
|
|
41
|
+
throw new Error(`Game event "${name}" descriptor must be an object`);
|
|
42
|
+
}
|
|
43
|
+
Object.freeze(descriptor);
|
|
44
|
+
}
|
|
45
|
+
return Object.freeze({ ...definitions }) as BrandedGameEventDefs<T>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Game event payload validation errors (T13).
|
|
3
|
+
*
|
|
4
|
+
* Every rejection identifies the event name and the exact payload path
|
|
5
|
+
* that caused the failure. The payload never captures React or native
|
|
6
|
+
* handles, sparse holes, cycles, or non-finite numbers.
|
|
7
|
+
*/
|
|
8
|
+
export class GameEventError extends Error {
|
|
9
|
+
override readonly name = 'GameEventError';
|
|
10
|
+
|
|
11
|
+
constructor(message: string) {
|
|
12
|
+
super(message);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { GameEventError } from './errors';
|
|
2
|
+
export { cloneAndValidatePayload, PAYLOAD_LIMITS } from './payload';
|
|
3
|
+
export { defineGameEvents, gameEvent } from './defineGameEvents';
|
|
4
|
+
export { seedGameEvent } from './seed';
|
|
5
|
+
export type {
|
|
6
|
+
AnyGameEventEnvelope,
|
|
7
|
+
GameEventDefinitions,
|
|
8
|
+
GameEventDescriptor,
|
|
9
|
+
GameEventEmitter,
|
|
10
|
+
GameEventEnvelope,
|
|
11
|
+
GameEventListener,
|
|
12
|
+
GameEventMap,
|
|
13
|
+
InferGameEventMap,
|
|
14
|
+
} from './types';
|