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
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { tileError } from './errors';
|
|
2
|
+
import type {
|
|
3
|
+
TileCell2D,
|
|
4
|
+
TileLayer2D,
|
|
5
|
+
TileMap2D,
|
|
6
|
+
TileSet2D,
|
|
7
|
+
TileLayerInput2D,
|
|
8
|
+
TileMapInput2D,
|
|
9
|
+
} from './types';
|
|
10
|
+
import type { Aabb2D } from '../geometry/types';
|
|
11
|
+
import { recordChunkRead } from './chunkStats';
|
|
12
|
+
|
|
13
|
+
/** Frozen internal chunk size in cells (both axes). T16.0 contract. */
|
|
14
|
+
export const TILE_CHUNK_SIZE = 16;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Maximum cells per layer (GS-TILE-04). The per-axis bound alone permits
|
|
18
|
+
* 8192x8192 = 67M cells per layer (~0.5GB dense data plus index copies),
|
|
19
|
+
* so total authored cells are capped at 2048x2048 worth — far above real
|
|
20
|
+
* levels, far below the footgun.
|
|
21
|
+
*/
|
|
22
|
+
export const MAX_TILE_LAYER_CELLS = 4_194_304;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Floor division truncating toward negative infinity — REQUIRED for
|
|
26
|
+
* negative cell coordinates (T16.0 contract).
|
|
27
|
+
*/
|
|
28
|
+
export function floorDiv(a: number, b: number): number {
|
|
29
|
+
return Math.floor(a / b);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Private chunk index (T16-F1/F6)
|
|
34
|
+
//
|
|
35
|
+
// The index is stored in a module-private WeakMap keyed by the map value, so
|
|
36
|
+
// consumers can neither mutate it nor depend on it through the public map.
|
|
37
|
+
// Every runtime tile read flows through `tileAt`, which consults this index.
|
|
38
|
+
// Visit instrumentation lives in ./chunkStats and is re-exported only via
|
|
39
|
+
// rn-gamekit/testing (T16-RF4).
|
|
40
|
+
//
|
|
41
|
+
// Kept-read decision (GS-TILE-04, measured on desktop V8, Node 24):
|
|
42
|
+
// dense spans traverse identically with or without the index (~23us for a
|
|
43
|
+
// 40x24 window, ~2.1ms for a full 256x256 scan); sparse spans skip empty
|
|
44
|
+
// chunks 1.5-3.9x faster (platformer-shaped window 0.8us vs 3.1us direct).
|
|
45
|
+
// Absolute costs are microseconds per query, but the sparse win covers the
|
|
46
|
+
// representative game shape (mostly-empty finite maps), so the index stays
|
|
47
|
+
// with the total-cell cap above bounding its retained cost. See
|
|
48
|
+
// bench/tileQueries.bench.ts (`pnpm bench:tilequeries`).
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
type ChunkIndex = Map<string, Int32Array>;
|
|
52
|
+
|
|
53
|
+
const chunkIndexes = new WeakMap<TileMap2D, ChunkIndex>();
|
|
54
|
+
|
|
55
|
+
function buildChunkIndex(layers: readonly TileLayer2D[]): ChunkIndex {
|
|
56
|
+
const chunks: ChunkIndex = new Map<string, Int32Array>();
|
|
57
|
+
for (const layer of layers) {
|
|
58
|
+
for (let y = 0; y < layer.height; y++) {
|
|
59
|
+
for (let x = 0; x < layer.width; x++) {
|
|
60
|
+
const v = layer.data[y * layer.width + x]!;
|
|
61
|
+
if (v === 0) continue;
|
|
62
|
+
const ccx = floorDiv(x, TILE_CHUNK_SIZE);
|
|
63
|
+
const ccy = floorDiv(y, TILE_CHUNK_SIZE);
|
|
64
|
+
const key = `${layer.id}|${ccx},${ccy}`;
|
|
65
|
+
let chunk = chunks.get(key);
|
|
66
|
+
if (chunk === undefined) {
|
|
67
|
+
chunk = new Int32Array(TILE_CHUNK_SIZE * TILE_CHUNK_SIZE);
|
|
68
|
+
chunks.set(key, chunk);
|
|
69
|
+
}
|
|
70
|
+
const lx = x - ccx * TILE_CHUNK_SIZE;
|
|
71
|
+
const ly = y - ccy * TILE_CHUNK_SIZE;
|
|
72
|
+
chunk[ly * TILE_CHUNK_SIZE + lx] = v;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return chunks;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function defineTileSet2D(input: {
|
|
80
|
+
readonly tiles: Readonly<Record<string, { readonly frame: string; readonly collision?: 'solid' | 'one-way-up' }>>;
|
|
81
|
+
}): TileSet2D {
|
|
82
|
+
if (input === null || typeof input !== 'object' || input.tiles === null || typeof input.tiles !== 'object' || Array.isArray(input.tiles)) {
|
|
83
|
+
throw tileError('tiles', 'must be an object of named tile definitions');
|
|
84
|
+
}
|
|
85
|
+
const names: string[] = [];
|
|
86
|
+
const tiles: Record<string, { frame: string; collision?: 'solid' | 'one-way-up' }> = {};
|
|
87
|
+
const idOfName: Record<string, number> = {};
|
|
88
|
+
const nameOfId: Record<number, string> = {};
|
|
89
|
+
const collisionOfId: Record<number, 'solid' | 'one-way-up'> = {};
|
|
90
|
+
for (const [name, defUnknown] of Object.entries(input.tiles)) {
|
|
91
|
+
if (name.length === 0) throw tileError('tiles', 'tile name must be non-empty');
|
|
92
|
+
const def = defUnknown as { frame?: unknown; collision?: unknown } | null;
|
|
93
|
+
if (def === null || typeof def !== 'object') {
|
|
94
|
+
throw tileError(`tiles.${JSON.stringify(name)}`, 'must be a tile definition object');
|
|
95
|
+
}
|
|
96
|
+
if (typeof def.frame !== 'string' || def.frame.length === 0) {
|
|
97
|
+
throw tileError(`tiles.${JSON.stringify(name)}.frame`, 'must be a non-empty frame name');
|
|
98
|
+
}
|
|
99
|
+
if (def.collision !== undefined && def.collision !== 'solid' && def.collision !== 'one-way-up') {
|
|
100
|
+
throw tileError(`tiles.${JSON.stringify(name)}.collision`, `must be "solid", "one-way-up", or omitted; got ${JSON.stringify(def.collision)}`);
|
|
101
|
+
}
|
|
102
|
+
names.push(name);
|
|
103
|
+
const id = names.length;
|
|
104
|
+
tiles[name] = Object.freeze({ frame: def.frame, ...(def.collision !== undefined ? { collision: def.collision as 'solid' | 'one-way-up' } : {}) });
|
|
105
|
+
idOfName[name] = id;
|
|
106
|
+
nameOfId[id] = name;
|
|
107
|
+
if (def.collision !== undefined) collisionOfId[id] = def.collision as 'solid' | 'one-way-up';
|
|
108
|
+
}
|
|
109
|
+
if (names.length === 0) throw tileError('tiles', 'must declare at least one tile');
|
|
110
|
+
if (names.length > 0xffff) throw tileError('tiles', 'v1 supports at most 65535 distinct tiles');
|
|
111
|
+
return Object.freeze({
|
|
112
|
+
names: Object.freeze(names.slice()),
|
|
113
|
+
tiles: Object.freeze(tiles),
|
|
114
|
+
idOfName: Object.freeze(idOfName),
|
|
115
|
+
nameOfId: Object.freeze(nameOfId),
|
|
116
|
+
collisionOfId: Object.freeze(collisionOfId),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function assertSafeInt(value: unknown, path: string): asserts value is number {
|
|
121
|
+
if (typeof value !== 'number' || !Number.isSafeInteger(value)) {
|
|
122
|
+
throw tileError(path, `must be a safe integer; got ${String(value)}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function defineTileLayer2D(
|
|
127
|
+
input: TileLayerInput2D,
|
|
128
|
+
tileset: TileSet2D,
|
|
129
|
+
): TileLayer2D {
|
|
130
|
+
if (input === null || typeof input !== 'object' || Array.isArray(input)) {
|
|
131
|
+
throw tileError('layers[]', 'must be a layer object');
|
|
132
|
+
}
|
|
133
|
+
const p = `layers[${JSON.stringify(input?.id ?? '')}]`;
|
|
134
|
+
if (typeof input.id !== 'string' || input.id.length === 0) throw tileError(`${p}.id`, 'must be a non-empty string');
|
|
135
|
+
assertSafeInt(input.width, `${p}.width`);
|
|
136
|
+
assertSafeInt(input.height, `${p}.height`);
|
|
137
|
+
if (input.width <= 0 || input.width > 8192) throw tileError(`${p}.width`, `must be in 1..8192; got ${input.width}`);
|
|
138
|
+
if (input.height <= 0 || input.height > 8192) throw tileError(`${p}.height`, `must be in 1..8192; got ${input.height}`);
|
|
139
|
+
if (input.width * input.height > MAX_TILE_LAYER_CELLS) {
|
|
140
|
+
throw tileError(
|
|
141
|
+
`${p}`,
|
|
142
|
+
`width*height ${input.width * input.height} exceeds the maximum of ${MAX_TILE_LAYER_CELLS} cells per layer`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
if (!Array.isArray(input.data)) throw tileError(`${p}.data`, 'must be a row-major array of tile ids');
|
|
146
|
+
// T16-F1: collidable is validated at runtime, never trusted from types.
|
|
147
|
+
if (
|
|
148
|
+
input.collidable !== undefined &&
|
|
149
|
+
typeof input.collidable !== 'boolean'
|
|
150
|
+
) {
|
|
151
|
+
throw tileError(`${p}.collidable`, `must be a boolean or omitted; got ${typeof input.collidable}`);
|
|
152
|
+
}
|
|
153
|
+
const expected = input.width * input.height;
|
|
154
|
+
if (input.data.length !== expected) {
|
|
155
|
+
throw tileError(`${p}.data`, `length ${input.data.length} must equal width*height (${expected})`);
|
|
156
|
+
}
|
|
157
|
+
const data: number[] = new Array(expected).fill(0);
|
|
158
|
+
for (let i = 0; i < expected; i++) {
|
|
159
|
+
const v = input.data[i];
|
|
160
|
+
if (v === 0) continue;
|
|
161
|
+
if (typeof v !== 'number' || !Number.isSafeInteger(v) || v < 0 || tileset.nameOfId[v] === undefined) {
|
|
162
|
+
throw tileError(`${p}.data[${i}]`, `unknown tile id ${String(v)} for the bound tileset`);
|
|
163
|
+
}
|
|
164
|
+
data[i] = v;
|
|
165
|
+
}
|
|
166
|
+
return Object.freeze({
|
|
167
|
+
id: input.id,
|
|
168
|
+
width: input.width,
|
|
169
|
+
height: input.height,
|
|
170
|
+
collidable: input.collidable ?? true,
|
|
171
|
+
// T16-F1: owned frozen copy — mutation attempts throw and never stick.
|
|
172
|
+
data: Object.freeze(data),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function defineTileMap2D(input: TileMapInput2D): TileMap2D {
|
|
177
|
+
if (input === null || typeof input !== 'object' || Array.isArray(input)) throw tileError('map', 'must be an object');
|
|
178
|
+
if (input.tileset === undefined || input.tileset.names === undefined) {
|
|
179
|
+
throw tileError('tileset', 'must be a value produced by defineTileSet2D');
|
|
180
|
+
}
|
|
181
|
+
const cw = input.cellSize?.width;
|
|
182
|
+
const ch = input.cellSize?.height;
|
|
183
|
+
if (typeof cw !== 'number' || !Number.isFinite(cw) || cw <= 0) throw tileError('cellSize.width', 'must be finite and > 0');
|
|
184
|
+
if (typeof ch !== 'number' || !Number.isFinite(ch) || ch <= 0) throw tileError('cellSize.height', 'must be finite and > 0');
|
|
185
|
+
if (!Array.isArray(input.layers)) throw tileError('layers', 'must be an array of layer inputs');
|
|
186
|
+
const originX = input.origin?.x ?? 0;
|
|
187
|
+
const originY = input.origin?.y ?? 0;
|
|
188
|
+
if (typeof originX !== 'number' || !Number.isFinite(originX)) throw tileError('origin.x', 'must be a finite number');
|
|
189
|
+
if (typeof originY !== 'number' || !Number.isFinite(originY)) throw tileError('origin.y', 'must be a finite number');
|
|
190
|
+
const origin: Point2DFrozen = Object.freeze({ x: originX, y: originY });
|
|
191
|
+
|
|
192
|
+
const layers: TileLayer2D[] = [];
|
|
193
|
+
const layerById: Record<string, TileLayer2D> = {};
|
|
194
|
+
for (const layerInput of input.layers) {
|
|
195
|
+
const layer = defineTileLayer2D(layerInput, input.tileset);
|
|
196
|
+
if (layerById[layer.id] !== undefined) {
|
|
197
|
+
throw tileError('layers', `duplicate layer id ${JSON.stringify(layer.id)}`);
|
|
198
|
+
}
|
|
199
|
+
layers.push(layer);
|
|
200
|
+
layerById[layer.id] = layer;
|
|
201
|
+
}
|
|
202
|
+
if (layers.length === 0) throw tileError('layers', 'must declare at least one layer');
|
|
203
|
+
|
|
204
|
+
// World bounds cover every layer.
|
|
205
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
206
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
207
|
+
for (const layer of layers) {
|
|
208
|
+
maxX = Math.max(maxX, origin.x + layer.width * cw);
|
|
209
|
+
maxY = Math.max(maxY, origin.y + layer.height * ch);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const worldBounds: Aabb2D = Object.freeze({ x: origin.x, y: origin.y, width: maxX - origin.x, height: maxY - origin.y });
|
|
213
|
+
|
|
214
|
+
const map: TileMap2D = Object.freeze({
|
|
215
|
+
cellSize: Object.freeze({ width: cw, height: ch }),
|
|
216
|
+
// T16-F1: frozen public origin.
|
|
217
|
+
origin,
|
|
218
|
+
tileset: input.tileset,
|
|
219
|
+
layers: Object.freeze(layers.slice()),
|
|
220
|
+
layerById: Object.freeze(layerById),
|
|
221
|
+
worldBounds,
|
|
222
|
+
chunkSize: TILE_CHUNK_SIZE,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// T16-F6: the chunk index lives OUTSIDE the public value.
|
|
226
|
+
chunkIndexes.set(map, buildChunkIndex(layers));
|
|
227
|
+
return map;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
interface Point2DFrozen {
|
|
231
|
+
readonly x: number;
|
|
232
|
+
readonly y: number;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Internal: read one cell's tile id (0 when outside the finite map). */
|
|
236
|
+
export function tileAt(map: TileMap2D, layerId: string, cx: number, cy: number): number {
|
|
237
|
+
const layer = map.layerById[layerId];
|
|
238
|
+
if (layer === undefined) return 0;
|
|
239
|
+
if (cx < 0 || cy < 0 || cx >= layer.width || cy >= layer.height) return 0;
|
|
240
|
+
// T16-F6: every read flows through the private chunk index.
|
|
241
|
+
const chunks = chunkIndexes.get(map);
|
|
242
|
+
if (chunks === undefined) return 0;
|
|
243
|
+
const ccx = floorDiv(cx, TILE_CHUNK_SIZE);
|
|
244
|
+
const ccy = floorDiv(cy, TILE_CHUNK_SIZE);
|
|
245
|
+
recordChunkRead();
|
|
246
|
+
const chunk = chunks.get(`${layerId}|${ccx},${ccy}`);
|
|
247
|
+
if (chunk === undefined) return 0;
|
|
248
|
+
return chunk[(cy - ccy * TILE_CHUNK_SIZE) * TILE_CHUNK_SIZE + (cx - ccx * TILE_CHUNK_SIZE)]!;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Internal: iterate non-empty cells inside an inclusive cell span in
|
|
253
|
+
* global row-major order, fetching each overlapped chunk region once
|
|
254
|
+
* (T16-F6). `visit` receives (layerId, cx, cy, tileId); returning false
|
|
255
|
+
* from `visit` stops iteration early.
|
|
256
|
+
*/
|
|
257
|
+
export function forEachCellInSpan(
|
|
258
|
+
map: TileMap2D,
|
|
259
|
+
layerId: string,
|
|
260
|
+
x0: number, y0: number, x1: number, y1: number,
|
|
261
|
+
visit: (cx: number, cy: number, tileId: number) => boolean | void,
|
|
262
|
+
): void {
|
|
263
|
+
const chunks = chunkIndexes.get(map);
|
|
264
|
+
if (chunks === undefined) return;
|
|
265
|
+
const bandY0 = floorDiv(y0, TILE_CHUNK_SIZE);
|
|
266
|
+
const bandY1 = floorDiv(y1, TILE_CHUNK_SIZE);
|
|
267
|
+
const bandX0 = floorDiv(x0, TILE_CHUNK_SIZE);
|
|
268
|
+
const bandX1 = floorDiv(x1, TILE_CHUNK_SIZE);
|
|
269
|
+
// T16-RF4: GLOBAL row-major order. For each chunk-Y band we fetch the
|
|
270
|
+
// intersecting chunk references ONCE (one lookup per chunk), then iterate
|
|
271
|
+
// global rows; within a row we visit the chunk-X segments left to right.
|
|
272
|
+
// This is exactly global row-major while keeping lookups bounded by the
|
|
273
|
+
// overlapped chunk regions.
|
|
274
|
+
const bandRefs: (Int32Array | undefined)[] = [];
|
|
275
|
+
for (let bcy = bandY0; bcy <= bandY1; bcy++) {
|
|
276
|
+
const rowStart = Math.max(y0, bcy * TILE_CHUNK_SIZE);
|
|
277
|
+
const rowEnd = Math.min(y1, (bcy + 1) * TILE_CHUNK_SIZE - 1);
|
|
278
|
+
// Fetch every intersecting chunk reference once per band.
|
|
279
|
+
bandRefs.length = 0;
|
|
280
|
+
for (let bcx = bandX0; bcx <= bandX1; bcx++) {
|
|
281
|
+
recordChunkRead();
|
|
282
|
+
bandRefs.push(chunks.get(`${layerId}|${bcx},${bcy}`));
|
|
283
|
+
}
|
|
284
|
+
for (let cy = rowStart; cy <= rowEnd; cy++) {
|
|
285
|
+
const ly = cy - bcy * TILE_CHUNK_SIZE;
|
|
286
|
+
const rowBase = ly * TILE_CHUNK_SIZE;
|
|
287
|
+
for (let bcx = bandX0; bcx <= bandX1; bcx++) {
|
|
288
|
+
const chunk = bandRefs[bcx - bandX0];
|
|
289
|
+
if (chunk === undefined) continue;
|
|
290
|
+
const lxStart = Math.max(x0, bcx * TILE_CHUNK_SIZE) - bcx * TILE_CHUNK_SIZE;
|
|
291
|
+
const lxEnd = Math.min(x1, (bcx + 1) * TILE_CHUNK_SIZE - 1) - bcx * TILE_CHUNK_SIZE;
|
|
292
|
+
for (let lx = lxStart; lx <= lxEnd; lx++) {
|
|
293
|
+
const v = chunk[rowBase + lx]!;
|
|
294
|
+
if (v === 0) continue;
|
|
295
|
+
const stop = visit(bcx * TILE_CHUNK_SIZE + lx, cy, v);
|
|
296
|
+
if (stop === false) return;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** Convert a cell coordinate to its world AABB. */
|
|
304
|
+
export function cellAabb(map: TileMap2D, cx: number, cy: number): Aabb2D {
|
|
305
|
+
return Object.freeze({
|
|
306
|
+
x: map.origin.x + cx * map.cellSize.width,
|
|
307
|
+
y: map.origin.y + cy * map.cellSize.height,
|
|
308
|
+
width: map.cellSize.width,
|
|
309
|
+
height: map.cellSize.height,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/** Frozen immutable query result builder. */
|
|
314
|
+
export function makeCell(map: TileMap2D, layerId: string, cx: number, cy: number, tileId: number): TileCell2D {
|
|
315
|
+
// GS-TILE-02: the single eligibility authority — a decorative
|
|
316
|
+
// (collidable: false) layer reports no collision role even for solid
|
|
317
|
+
// tiles, so queries and movement agree that decoration never blocks.
|
|
318
|
+
const collidable = map.layerById[layerId]?.collidable ?? false;
|
|
319
|
+
return Object.freeze({
|
|
320
|
+
layerId,
|
|
321
|
+
tileId,
|
|
322
|
+
tileName: map.tileset.nameOfId[tileId]!,
|
|
323
|
+
collision: collidable ? map.tileset.collisionOfId[tileId] : undefined,
|
|
324
|
+
cell: Object.freeze({ x: cx, y: cy }),
|
|
325
|
+
aabb: cellAabb(map, cx, cy),
|
|
326
|
+
});
|
|
327
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Tilemap definition/query/movement errors with exact field paths. */
|
|
2
|
+
export class TileMapError extends Error {
|
|
3
|
+
override name = 'TileMapError';
|
|
4
|
+
constructor(message: string) {
|
|
5
|
+
super(message);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function tileError(path: string, message: string): TileMapError {
|
|
10
|
+
return new TileMapError(`${path}: ${message}`);
|
|
11
|
+
}
|