ecspresso
Version:
A minimal Entity-Component-System library for typescript and javascript.
106 lines (69 loc) • 6.33 kB
Markdown
# Changelog
All notable changes to ECSpresso are documented here. Format loosely follows [Keep a Changelog](https://keepachangelog.com/).
## 0.20.0
### Changed
- **Live `withResources()` dependencies**: Declared resource values are refreshed before every system process call, so `setResource()` and `updateResource()` replacements are visible regardless of `onResourceChange()` subscribers. Systems that intentionally relied on first-call snapshots now receive the currently registered value; the injected `resources` object is still reused.
- **Optional dependency metadata**: TypeScript is now a development dependency rather than a peer dependency, and the unused `react-dom` peer requirement has been removed. Runtime integrations continue to declare only their optional package peers.
### Added
- **Installation guidance**: The getting-started guide now documents the optional packages required by the 2D, 3D, audio, and React entry points, along with the recommended TypeScript version.
- **System and screen ownership guidance**: The systems, plugins, screens, and mirrored AI skill documentation now cover explicit callback dependencies, plugin-wide system defaults, authoritative screen navigation, and pause/overlay group behavior.
## 0.19.2
### Added
- **Orthographic zoom bounds on `camera3D`**:
- `createCamera3DPlugin({ projection: 'orthographic', minZoom?, maxZoom? })` clamps `camera3DState.setZoom`, initial zoom, camera sync at init, and built-in wheel zoom (defaults `0.1`–`10`, matching the 2D camera plugin wheel limits).
## 0.19.1
### Added
- **Projection-aware `camera3D` wheel input**:
- Orthographic cameras now use wheel input to update `camera3DState.zoom` by default.
- `createCamera3DPlugin({ wheelMode })` supports `'auto'`, `'distance'`, `'zoom'`, and `'disabled'`.
## 0.19.0
### Breaking
- `addReactiveQuery(...)` callbacks now receive context objects:
- `onEnter({ entity, ecs })` instead of `onEnter(entity)`.
- `onExit({ entityId, ecs })` instead of `onExit(entityId)`.
### Added
- **Screen resume lifecycle hooks** for overlay stacks:
- `ScreenDefinition.onResume({ config, state, ecs })` runs after `popScreen()` restores a stacked screen as current.
- `screenResume` events and `game.onScreenResume(screen, handler)` expose the same resume point to centralized screen wiring.
## 0.18.0
### Breaking
ScreenDefinition<Config> now defaults State to Config instead of Record<string, never>.
That means code like this may now fail typecheck:
type Screens = {
playing: ScreenDefinition<{ level: number }>;
};
const playing: Screens['playing'] = {
initialState: () => ({}),
};
Before, omitted State meant empty state. Now omitted State means state mirrors config, so initialState must return { level: number }.
### Added
- **System callback helper types** for extracted system callbacks:
- `SystemProcessFn<Cfg, Queries, ResourceKeys?, Singletons?>` names the `.setProcess(...)` callback shape.
- `SystemLifecycleFn<Cfg>` names the `.setOnInitialize(...)` / `.setOnDetach(...)` callback shape.
- **Configurator callback helper types** for extracting builder callbacks:
- `AssetConfiguratorFn<Assets, AssetGroups?>` names the `.withAssets(...)` callback shape.
- `ScreenConfiguratorFn<Screens>` names the `.withScreens(...)` callback shape.
- **Slot-specific `WorldConfig` helper types** for plugin requirements:
- `ComponentsConfig<T>`, `EventsConfig<T>`, `ResourcesConfig<T>`, `AssetsConfig<T>`, and `ScreensConfig<T>` build single-slot configs without spelling empty `WorldConfigFrom` parameters.
- **Screen definitions now default state to config** when the state type parameter is omitted, reducing boilerplate for screens whose mutable state mirrors the entry config.
- **Spritesheet helpers in `ecspresso/plugins/rendering/sprite-animation`** for PixiJS atlases:
- `spritesheetLoader<S>(url)` — `AssetConfigurator`-compatible loader; lazy-loads `pixi.js` and runtime-shape-checks the resolved value so non-atlas URLs error at load time instead of deep in the play loop.
- `clipFromSheet(sheet, name, options?)` and `animationSetFromSheet(id, sheet, options?)` — build clips/sets from a loaded `Spritesheet<S>`. Animation-name union is inferred when `S` is declared as an `interface ... extends SpritesheetData`. Both throw on zero-frame animations.
- `clipFromGrid({ source, frameWidth, frameHeight, columns, rows?, count?, indices?, ... })` — slice a grid-arranged image without atlas JSON. **Async** (lazy-loads pixi) and validates inputs: exactly one of `rows`/`count`/`indices` is required, indices are integer- and bounds-checked when `rows` is given.
- New exported types: `SheetClipOverrides<A>`, `SheetAnimationKeys<S>`.
### Internal
- Materialized the Codex plugin wrapper files in-repo and included their plugin manifests in version sync.
## 0.17.0
No breaking changes from 0.16.3.
### Added
- **`builder.disableChangeTracking()`** — opt out of change tracking entirely for worlds with zero `changed:` filters (e.g. benchmarks). Auto-subscription from plugins still grows the bitmap correctly if a plugin with a `changed:` filter is added afterwards.
- **Auto-derived change-tracking subscriptions.** The framework walks `changed:` declarations during `_registerSystem` and subscribes only the components something actually consumes. Unsubscribed components skip the mark walk entirely.
### Performance
- Spatial-index `postUpdate` rebuild auto-skips in flat-hierarchy scenes when the `fixedUpdate` rebuild already ran (2D: −5.7%, 3D: −9.6% ms/frame in the physics bench).
- `EventBus.publish` switched from a conditional-tuple rest signature to two named overloads — empty fast-path is ~7× faster (5.7 → 0.8 ns/call); end-to-end bench −7–10% ms/frame.
- `markChanged` resolves component indices once and uses a flat `Uint32Array` for the per-component change generation.
- Query `_changedIdx` and `_mutatesIdx` are pre-resolved at system registration, removing per-frame name→idx Map lookups.
- Collision and spatial-index plugins replaced per-entity `getComponent` calls with split queries.
### Internal
- Added `bench/ecs-physics3D.bench.ts` and shared `mulberry32` PRNG with the 2D bench.
- Stress-test example gained Phaser and Bevy comparison modes; Bevy wasm builds in docs CI.