cubeforge 0.3.14 → 0.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +196 -11
  2. package/dist/index.js +1087 -308
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1,17 +1,18 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { CSSProperties, ReactNode } from 'react';
3
+ import React__default, { CSSProperties, ReactNode, ReactElement } from 'react';
4
4
  import { Plugin, EntityId, ECSWorld, ScriptUpdateFn, NavGrid, WorldSnapshot, EventBus } from '@cubeforge/core';
5
- export { AssetProgress, Component, ECSWorld, Ease, EntityId, GameTimer, HotReloadablePlugin, NavGrid, Plugin, PreloadManifest, ScriptUpdateFn, TransformComponent, TweenHandle, Vec2Like, WorldSnapshot, arrive, createTag, createTimer, createTransform, definePlugin, findByTag, flee, hotReloadPlugin, patrol, preloadManifest, seek, tween, wander } from '@cubeforge/core';
6
- import { Sampling } from '@cubeforge/renderer';
7
- export { AnimationStateComponent, MagFilterValue, NineSliceComponent, ParallaxLayerComponent, Particle, ParticlePoolComponent, RenderSystem, Sampling, SpriteComponent, SquashStretchComponent, TextComponent, TextureFilter, TextureFilterValue, TrailComponent, createNineSlice, createSprite } from '@cubeforge/renderer';
5
+ export { AssetProgress, Component, ECSWorld, Ease, EntityId, GameTimer, HotReloadablePlugin, MergedRect, NavGrid, Plugin, PreloadManifest, ScriptUpdateFn, TimelineEntry, TransformComponent, TweenHandle, TweenTimeline, Vec2Like, WorldSnapshot, arrive, createTag, createTimeline, createTimer, createTransform, definePlugin, findByTag, flee, hotReloadPlugin, mergeTileColliders, patrol, preloadManifest, seek, tween, wander } from '@cubeforge/core';
6
+ import { Sampling, BlendMode, PostProcessEffect } from '@cubeforge/renderer';
7
+ export { AnimationStateComponent, BlendMode, MagFilterValue, NineSliceComponent, ParallaxLayerComponent, Particle, ParticlePoolComponent, PostProcessEffect, PostProcessStack, RenderLayer, RenderLayerManager, RenderSystem, Sampling, SpriteComponent, SquashStretchComponent, TextComponent, TextureFilter, TextureFilterValue, TrailComponent, chromaticAberrationEffect, createNineSlice, createPostProcessStack, createRenderLayerManager, createSprite, defaultLayers, scanlineEffect, vignetteEffect } from '@cubeforge/renderer';
8
8
  import { ColliderShape } from '@cubeforge/physics';
9
9
  export { BoxColliderComponent, CapsuleColliderComponent, CircleColliderComponent, ColliderShape, CompoundColliderComponent, RaycastHit, RigidBodyComponent, createCompoundCollider, overlapBox, overlapCircle, raycast, raycastAll, sweepBox } from '@cubeforge/physics';
10
10
  import { InputManager, ActionBindings, InputContextName, PlayerInput, InputRecorderControls } from '@cubeforge/input';
11
11
  export { ActionBindings, AxisBinding, InputContextName, InputManager, InputMap, InputRecorderControls, InputRecording, InputRecording as InputRecordingData, PlayerInput, createInputMap, createInputRecorder, createPlayerInput, globalInputContext } from '@cubeforge/input';
12
+ import { AnimationClip } from '@cubeforge/gameplay';
13
+ export { AISteering, AnimationClip, AnimationControllerResult, BindingControls, CutsceneControls, CutsceneStep, DialogueControls, DialogueLine, DialogueScript, GameState as GameStateDefinition, GameStateMachineResult, HealthControls, HealthOptions, KinematicBodyControls, LevelTransitionControls, ObjectPool, PathfindingControls, PlatformerControllerOptions, RestartControls, SaveControls, SaveOptions, TopDownMovementOptions, TransitionOptions, TransitionType, TweenControls, useAISteering, useAnimationController, useCutscene, useDamageZone, useDialogue, useDropThrough, useGameStateMachine, useGameStore, useHealth, useKinematicBody, useLevelTransition, useObjectPool, usePathfinding, usePersistedBindings, usePlatformerController, useRestart, useSave, useTopDownMovement, useTween } from '@cubeforge/gameplay';
12
14
  import { EngineState } from '@cubeforge/context';
13
- export { EngineState, useCircleEnter, useCircleExit, useCircleStay, useCollisionEnter, useCollisionExit, useCollisionStay, useTriggerEnter, useTriggerExit, useTriggerStay } from '@cubeforge/context';
14
- export { AISteering, AnimationClip, AnimationControllerResult, BindingControls, CutsceneControls, CutsceneStep, DialogueControls, DialogueLine, DialogueScript, GameState as GameStateDefinition, GameStateMachineResult, HealthControls, HealthOptions, KinematicBodyControls, LevelTransitionControls, PathfindingControls, PlatformerControllerOptions, RestartControls, SaveControls, SaveOptions, TopDownMovementOptions, TransitionOptions, TransitionType, useAISteering, useAnimationController, useCutscene, useDamageZone, useDialogue, useDropThrough, useGameStateMachine, useGameStore, useHealth, useKinematicBody, useLevelTransition, usePathfinding, usePersistedBindings, usePlatformerController, useRestart, useSave, useTopDownMovement } from '@cubeforge/gameplay';
15
+ export { EngineState, useCircleEnter, useCircleExit, useCircleStay, useCollidingWith, useCollisionEnter, useCollisionExit, useCollisionStay, useTriggerEnter, useTriggerExit, useTriggerStay } from '@cubeforge/context';
15
16
  export { AudioGroup, SoundControls, duck, getGroupVolume, setGroupMute, setGroupVolume, setMasterVolume, stopGroup, useSound } from '@cubeforge/audio';
16
17
  export { DevToolsHandle } from '@cubeforge/devtools';
17
18
 
@@ -109,6 +110,7 @@ interface SpriteProps {
109
110
  zIndex?: number;
110
111
  visible?: boolean;
111
112
  flipX?: boolean;
113
+ flipY?: boolean;
112
114
  anchorX?: number;
113
115
  anchorY?: number;
114
116
  frameIndex?: number;
@@ -123,8 +125,12 @@ interface SpriteProps {
123
125
  tileSizeY?: number;
124
126
  /** Texture sampling mode — controls filtering when the sprite is scaled */
125
127
  sampling?: Sampling;
128
+ /** Blend mode used when drawing this sprite */
129
+ blendMode?: BlendMode;
130
+ /** Render layer name — sprites are sorted by layer order first, then zIndex */
131
+ layer?: string;
126
132
  }
127
- declare function Sprite({ width, height, color, src, offsetX, offsetY, zIndex, visible, flipX, anchorX, anchorY, frameIndex, frameWidth, frameHeight, frameColumns, atlas, frame, tileX, tileY, tileSizeX, tileSizeY, sampling, }: SpriteProps): null;
133
+ declare function Sprite({ width, height, color, src, offsetX, offsetY, zIndex, visible, flipX, flipY, anchorX, anchorY, frameIndex, frameWidth, frameHeight, frameColumns, atlas, frame, tileX, tileY, tileSizeX, tileSizeY, sampling, blendMode, layer, }: SpriteProps): null;
128
134
 
129
135
  interface TextProps {
130
136
  text: string;
@@ -155,8 +161,14 @@ interface RigidBodyProps {
155
161
  lockY?: boolean;
156
162
  /** Enable continuous collision detection to prevent tunneling through thin colliders */
157
163
  ccd?: boolean;
164
+ /** Angular velocity in radians per second */
165
+ angularVelocity?: number;
166
+ /** Angular damping (0–1): fraction of angular velocity removed each fixed step */
167
+ angularDamping?: number;
168
+ /** Linear damping (0–1): velocity reduction applied every fixed step (air resistance) */
169
+ linearDamping?: number;
158
170
  }
159
- declare function RigidBody({ mass, gravityScale, isStatic, bounce, friction, vx, vy, lockX, lockY, ccd, }: RigidBodyProps): null;
171
+ declare function RigidBody({ mass, gravityScale, isStatic, bounce, friction, vx, vy, lockX, lockY, ccd, angularVelocity, angularDamping, linearDamping, }: RigidBodyProps): null;
160
172
 
161
173
  interface BoxColliderProps {
162
174
  width: number;
@@ -263,6 +275,107 @@ interface AnimationProps {
263
275
  }
264
276
  declare function Animation({ frames, fps, loop, playing, onComplete, frameEvents }: AnimationProps): null;
265
277
 
278
+ /** Shared sprite props used by both API forms */
279
+ interface SpriteOptions {
280
+ width: number;
281
+ height: number;
282
+ src: string;
283
+ color?: string;
284
+ offsetX?: number;
285
+ offsetY?: number;
286
+ zIndex?: number;
287
+ visible?: boolean;
288
+ flipX?: boolean;
289
+ flipY?: boolean;
290
+ anchorX?: number;
291
+ anchorY?: number;
292
+ frameWidth?: number;
293
+ frameHeight?: number;
294
+ frameColumns?: number;
295
+ atlas?: SpriteAtlas;
296
+ frame?: string;
297
+ tileX?: boolean;
298
+ tileY?: boolean;
299
+ tileSizeX?: number;
300
+ tileSizeY?: number;
301
+ sampling?: Sampling;
302
+ blendMode?: BlendMode;
303
+ }
304
+ /** Simple form — single animation clip (like Sprite + Animation) */
305
+ interface SimpleAnimatedSpriteProps extends SpriteOptions {
306
+ frames: number[];
307
+ fps?: number;
308
+ loop?: boolean;
309
+ playing?: boolean;
310
+ onComplete?: () => void;
311
+ frameEvents?: Record<number, () => void>;
312
+ animations?: never;
313
+ current?: never;
314
+ }
315
+ /** Multi-clip form — named animation states with typed clip names */
316
+ interface MultiAnimatedSpriteProps<S extends string = string> extends SpriteOptions {
317
+ /** Map of named animation clips (use `defineAnimations()` for type-safe names) */
318
+ animations: AnimationSet<S>;
319
+ /** Which animation clip is currently playing — typed to the clip names */
320
+ current: S;
321
+ frames?: never;
322
+ fps?: never;
323
+ loop?: never;
324
+ playing?: never;
325
+ onComplete?: never;
326
+ frameEvents?: never;
327
+ }
328
+ type AnimatedSpriteProps<S extends string = string> = SimpleAnimatedSpriteProps | MultiAnimatedSpriteProps<S>;
329
+ /** A typed set of animation clips. Created by `defineAnimations()`. */
330
+ type AnimationSet<S extends string = string> = Record<S, AnimationClip>;
331
+ /**
332
+ * Define a reusable, type-safe set of animation clips.
333
+ *
334
+ * The returned object can be shared across components and provides
335
+ * autocomplete on `current` when used with `<AnimatedSprite>`.
336
+ *
337
+ * @example
338
+ * ```tsx
339
+ * const playerAnims = defineAnimations({
340
+ * idle: { frames: [0], fps: 1 },
341
+ * walk: { frames: [1, 2, 3, 4], fps: 10 },
342
+ * run: { frames: [5, 6, 7, 8], fps: 14 },
343
+ * jump: { frames: [9], fps: 1, loop: false },
344
+ * attack: { frames: [10, 11, 12], fps: 16, loop: false, next: 'idle' },
345
+ * })
346
+ *
347
+ * // `current` is typed as 'idle' | 'walk' | 'run' | 'jump' | 'attack'
348
+ * <AnimatedSprite animations={playerAnims} current={state} ... />
349
+ * ```
350
+ */
351
+ declare function defineAnimations<S extends string>(clips: Record<S, AnimationClip>): AnimationSet<S>;
352
+ /**
353
+ * Convenience wrapper that combines `<Sprite>` and `<Animation>` into a
354
+ * single component. Must be placed inside an `<Entity>`.
355
+ *
356
+ * Supports two API forms:
357
+ *
358
+ * **Simple** — single clip:
359
+ * ```tsx
360
+ * <AnimatedSprite src="/hero.png" width={32} height={32}
361
+ * frameWidth={32} frameHeight={32} frameColumns={8}
362
+ * frames={[0, 1, 2, 3]} fps={10} />
363
+ * ```
364
+ *
365
+ * **Multi-clip** — named animation states, switch via `current`:
366
+ * ```tsx
367
+ * const anims = defineAnimations({
368
+ * idle: { frames: [0], fps: 1 },
369
+ * walk: { frames: [1, 2, 3, 4], fps: 10 },
370
+ * })
371
+ *
372
+ * <AnimatedSprite src="/hero.png" width={32} height={48}
373
+ * frameWidth={32} frameHeight={48} frameColumns={8}
374
+ * animations={anims} current={state} />
375
+ * ```
376
+ */
377
+ declare function AnimatedSprite<S extends string>(props: AnimatedSpriteProps<S>): ReactElement;
378
+
266
379
  interface SquashStretchProps {
267
380
  /** How much to squash/stretch (default 0.2) */
268
381
  intensity?: number;
@@ -295,8 +408,18 @@ interface ParticleEmitterProps {
295
408
  gravity?: number;
296
409
  /** Maximum live particles, default 100 */
297
410
  maxParticles?: number;
411
+ /** Emit this many particles in one frame then deactivate (one-shot burst) */
412
+ burstCount?: number;
413
+ /** Emission shape: 'point' (default), 'circle', or 'box' */
414
+ emitShape?: 'point' | 'circle' | 'box';
415
+ /** Radius for 'circle' emission shape */
416
+ emitRadius?: number;
417
+ /** Width for 'box' emission shape */
418
+ emitWidth?: number;
419
+ /** Height for 'box' emission shape */
420
+ emitHeight?: number;
298
421
  }
299
- declare function ParticleEmitter({ active, preset, rate, speed, spread, angle, particleLife, particleSize, color, gravity, maxParticles, }: ParticleEmitterProps): null;
422
+ declare function ParticleEmitter({ active, preset, rate, speed, spread, angle, particleLife, particleSize, color, gravity, maxParticles, burstCount, emitShape, emitRadius, emitWidth, emitHeight, }: ParticleEmitterProps): null;
300
423
 
301
424
  interface VirtualJoystickProps {
302
425
  /** Diameter of the joystick base in pixels (default 120) */
@@ -437,8 +560,15 @@ interface TilemapProps {
437
560
  * can filter them by `layer.name === spawnLayer` inside the callback.
438
561
  */
439
562
  spawnLayer?: string;
563
+ /**
564
+ * When true (default), adjacent solid tiles in collision/trigger layers
565
+ * are merged into larger rectangles using a 2D greedy algorithm, reducing
566
+ * the number of collider entities. Set to false to create one collider per
567
+ * row-run (legacy behaviour).
568
+ */
569
+ mergeColliders?: boolean;
440
570
  }
441
- declare function Tilemap({ src, onSpawnObject, layerFilter, zIndex, collisionLayer, triggerLayer: triggerLayerName, onTileProperty, navGrid, }: TilemapProps): React__default.ReactElement | null;
571
+ declare function Tilemap({ src, onSpawnObject, layerFilter, zIndex, collisionLayer, triggerLayer: triggerLayerName, onTileProperty, navGrid, mergeColliders, }: TilemapProps): React__default.ReactElement | null;
442
572
 
443
573
  interface ParallaxLayerProps {
444
574
  /** Image URL to use as the background layer */
@@ -962,4 +1092,59 @@ interface PauseControls {
962
1092
  */
963
1093
  declare function usePause(): PauseControls;
964
1094
 
965
- export { Animation, AssetLoader, type BoundInputMap, BoxCollider, Camera2D, type CameraControls, CameraZone, CapsuleCollider, Checkpoint, CircleCollider, CompoundCollider, type CoordinateHelpers, Entity, Game, type GameControls, type GamepadState, type InputContextControls, MovingPlatform, NineSlice, ParallaxLayer, ParticleEmitter, type ParticlePreset, type PauseControls, type PreloadState, RigidBody, ScreenFlash, type ScreenFlashHandle, Script, type SnapshotControls, Sprite, type SpriteAtlas, SquashStretch, Text, type TiledLayer, type TiledObject, Tilemap, Trail, Transform, type VirtualInputState, VirtualJoystick, type VirtualJoystickProps, World, createAtlas, useCamera, useCoordinates, useDestroyEntity, useEntity, useEvent, useEvents, useGame, useGamepad, useInput, useInputContext, useInputMap, useInputRecorder, useLocalMultiplayer, usePause, usePlayerInput, usePreload, useSnapshot, useVirtualInput };
1095
+ interface ProfilerData {
1096
+ fps: number;
1097
+ frameTime: number;
1098
+ entityCount: number;
1099
+ systemTimings: Map<string, number>;
1100
+ }
1101
+ /**
1102
+ * Returns live performance data from the engine: FPS, frame time, entity count,
1103
+ * and per-system timings. Updates at most every 500 ms to avoid excessive re-renders.
1104
+ *
1105
+ * Must be used inside a `<Game>` component.
1106
+ */
1107
+ declare function useProfiler(): ProfilerData;
1108
+
1109
+ /**
1110
+ * Registers a post-processing effect for the lifetime of the component.
1111
+ * The effect runs in screen space after all scene rendering is complete.
1112
+ *
1113
+ * @example
1114
+ * ```tsx
1115
+ * import { vignetteEffect } from 'cubeforge'
1116
+ *
1117
+ * function Atmosphere() {
1118
+ * usePostProcess(vignetteEffect(0.5))
1119
+ * return null
1120
+ * }
1121
+ * ```
1122
+ */
1123
+ declare function usePostProcess(effect: PostProcessEffect): void;
1124
+
1125
+ /**
1126
+ * Define a reusable entity prefab with default props.
1127
+ *
1128
+ * Returns a memoized React component that merges caller-supplied props
1129
+ * over the provided defaults, so every prop becomes optional at the call site.
1130
+ *
1131
+ * @example
1132
+ * ```tsx
1133
+ * const Crate = definePrefab('Crate', {
1134
+ * width: 32, height: 32, color: '#8B4513', mass: 1,
1135
+ * }, (props) => (
1136
+ * <Entity tags={['crate']}>
1137
+ * <Transform x={0} y={0} />
1138
+ * <Sprite width={props.width} height={props.height} color={props.color} />
1139
+ * <RigidBody mass={props.mass} />
1140
+ * <BoxCollider width={props.width} height={props.height} />
1141
+ * </Entity>
1142
+ * ))
1143
+ *
1144
+ * // Usage — all defaults applied, override only what you need:
1145
+ * <Crate width={64} />
1146
+ * ```
1147
+ */
1148
+ declare function definePrefab<D extends Record<string, unknown>>(name: string, defaults: D, render: (props: D) => ReactElement): React__default.FC<Partial<D>>;
1149
+
1150
+ export { AnimatedSprite, type AnimatedSpriteProps, Animation, type AnimationSet, AssetLoader, type BoundInputMap, BoxCollider, Camera2D, type CameraControls, CameraZone, CapsuleCollider, Checkpoint, CircleCollider, CompoundCollider, type CoordinateHelpers, Entity, Game, type GameControls, type GamepadState, type InputContextControls, MovingPlatform, NineSlice, ParallaxLayer, ParticleEmitter, type ParticlePreset, type PauseControls, type PreloadState, type ProfilerData, RigidBody, ScreenFlash, type ScreenFlashHandle, Script, type SnapshotControls, Sprite, type SpriteAtlas, SquashStretch, Text, type TiledLayer, type TiledObject, Tilemap, Trail, Transform, type VirtualInputState, VirtualJoystick, type VirtualJoystickProps, World, createAtlas, defineAnimations, definePrefab, useCamera, useCoordinates, useDestroyEntity, useEntity, useEvent, useEvents, useGame, useGamepad, useInput, useInputContext, useInputMap, useInputRecorder, useLocalMultiplayer, usePause, usePlayerInput, usePostProcess, usePreload, useProfiler, useSnapshot, useVirtualInput };