Move docs/ package mirror into document-navigator plugin

Relocate the ~6k-file docs tree from the repo root into
plugins/document-navigator/docs/ so the plugin is self-contained and
portable. docs/superpowers/ (specs and plans) stays at the repo root.

Moved via cp+rm rather than git mv because directory rename() fails with
EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the
identical-content files at commit time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 01:10:00 +01:00
parent fe3fedf42e
commit 9bf56a806b
6022 changed files with 12437 additions and 0 deletions

View File

@@ -0,0 +1,145 @@
# @suaveplan/bitpacker-game - Bitpacker game plugin
## Summary
Game state utilities: quantization, prediction, interpolation, and client-server reconciliation.
<!-- begin:auto-docs -->
## Documentation tree
- [bitpacker](./src/bitpacker/bitpacker.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [bitpacker](./src/bitpacker/bitpacker.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [integration-manager](./src/integration-manager/integration-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [integration-manager](./src/integration-manager/integration-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [interpolation](./src/interpolation/interpolation.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [index](./src/interpolation/index.md) — **Path:** `src/interpolation/interpolation.ts` **Export:** `GameInterpolator`
- [interpolation](./src/interpolation/interpolation.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [otel](./src/otel/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [instruments](./src/otel/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [prediction](./src/prediction/prediction.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - rotation-predictor — **Path:** `bitpacker-game/src/…
- [index](./src/prediction/index.md) — **Path:** `src/prediction/` **Exports:** `PositionPredictor`, `RotationPredictor`, motion math, Kalman filter, predicti…
- [kalman-filter](./src/prediction/kalman-filter.md) — **Path:** `bitpacker-game/src/prediction/kalman-filter.ts` **Export:** See source for details.
- [motion-math](./src/prediction/motion-math.md) — **Path:** `bitpacker-game/src/prediction/motion-math.ts` **Export:** See source for details.
- [position-predictor](./src/prediction/position-predictor.md) — **Path:** `bitpacker-game/src/prediction/position-predictor.ts` **Export:** See source for details.
- [prediction-algorithms](./src/prediction/prediction-algorithms.md) — **Path:** `bitpacker-game/src/prediction/prediction-algorithms.ts` **Export:** See source for details.
- [prediction](./src/prediction/prediction.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - rotation-predictor — **Path:** `bitpacker-game/src/…
- [rotation-predictor](./src/prediction/rotation-predictor.md) — **Path:** `bitpacker-game/src/prediction/rotation-predictor.ts` **Export:** See source for details.
- [quantization](./src/quantization/quantization.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [quantization](./src/quantization/quantization.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [reconciliation](./src/reconciliation/reconciliation.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [index](./src/reconciliation/index.md) — **Path:** `src/reconciliation/reconciliation.ts` **Export:** `StateReconciliation`
- [reconciliation](./src/reconciliation/reconciliation.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [register-schemas](./src/register-schemas/register-schemas.md) — Idempotent integration with `@suaveplan/schema-registry` for the `@suaveplan/bitpacker-game` package. Exposes `register…
- [register-schemas](./src/register-schemas/register-schemas.md) — Idempotent integration with `@suaveplan/schema-registry` for the `@suaveplan/bitpacker-game` package. Exposes `register…
- [schema-factory](./src/schema-factory/schema-factory.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [schema-factory](./src/schema-factory/schema-factory.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [state-manager](./src/state-manager/state-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [state-manager](./src/state-manager/state-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [types.schema](./src/types.schema/types.schema.md) — Zod schemas for the public configuration types of `@suaveplan/bitpacker-game`: the three sub-options bundles (`Predicti…
- [types.schema](./src/types.schema/types.schema.md) — Zod schemas for the public configuration types of `@suaveplan/bitpacker-game`: the three sub-options bundles (`Predicti…
- [index](./src/index.md) — **Path:** `bitpacker-game/src/index.ts` **Export:** See source for details.
- [types](./src/types.md) — **Path:** `src/types.ts` **Export:** All game-related type definitions and enums
<!-- end:auto-docs --> - [bitpacker](./src/bitpacker/bitpacker.md) — <!-- begin:auto-docs --> _(no submodules)_- [integration-manager](./src/integration-manager/integration-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [integration-manager](./src/integration-manager/integration-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [interpolation](./src/interpolation/interpolation.md) — <!-- begin:auto-docs --> _(no submodules)_- [index](./src/interpolation/index.md) — **Path:** `src/interpolation/interpolation.ts` **Export:** `GameInterpolator`
- [interpolation](./src/interpolation/interpolation.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [instruments](./src/otel/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [prediction](./src/prediction/prediction.md) — <!-- begin:auto-docs --> _(no submodules)_- rotation-predictor — **Path:** `bitpacker-game/src/…
- [index](./src/prediction/index.md) — **Path:** `src/prediction/` **Exports:** `PositionPredictor`, `RotationPredictor`, motion math, Kalman filter, predicti…
- [kalman-filter](./src/prediction/kalman-filter.md) — **Path:** `bitpacker-game/src/prediction/kalman-filter.ts` **Export:** See source for details.
- [motion-math](./src/prediction/motion-math.md) — **Path:** `bitpacker-game/src/prediction/motion-math.ts` **Export:** See source for details.
- [position-predictor](./src/prediction/position-predictor.md) — **Path:** `bitpacker-game/src/prediction/position-predictor.ts` **Export:** See source for details.
- [prediction-algorithms](./src/prediction/prediction-algorithms.md) — **Path:** `bitpacker-game/src/prediction/prediction-algorithms.ts` **Export:** See source for details.
- [prediction](./src/prediction/prediction.md) — <!-- begin:auto-docs --> _(no submodules)_- rotation-predictor — **Path:** `bitpacker-game/src/…
- [rotation-predictor](./src/prediction/rotation-predictor.md) — **Path:** `bitpacker-game/src/prediction/rotation-predictor.ts` **Export:** See source for details.
- [quantization](./src/quantization/quantization.md) — <!-- begin:auto-docs --> _(no submodules)_- [quantization](./src/quantization/quantization.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconciliation](./src/reconciliation/reconciliation.md) — <!-- begin:auto-docs --> _(no submodules)_- [index](./src/reconciliation/index.md) — **Path:** `src/reconciliation/reconciliation.ts` **Export:** `StateReconciliation`
- [reconciliation](./src/reconciliation/reconciliation.md) — <!-- begin:auto-docs --> _(no submodules)_- [schema-factory](./src/schema-factory/schema-factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [schema-factory](./src/schema-factory/schema-factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [state-manager](./src/state-manager/state-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [state-manager](./src/state-manager/state-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [index](./src/index.md) — **Path:** `bitpacker-game/src/index.ts` **Export:** See source for details.
- [register-schemas](./src/register-schemas.md) — Idempotent integration with `@suaveplan/schema-registry` for the `@suaveplan/bitpacker-game` package. Exposes `register…
- [types](./src/types.md) — **Path:** `src/types.ts` **Export:** All game-related type definitions and enums
- [types.schema](./src/types.schema.md) — Zod schemas for the public configuration types of `@suaveplan/bitpacker-game`: the three sub-options bundles (`Predicti…
- [bitpacker](./src/bitpacker/bitpacker.md) — <!-- begin:auto-docs --> _(no submodules)_- [integration-manager](./src/integration-manager/integration-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [integration-manager](./src/integration-manager/integration-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [interpolation](./src/interpolation/interpolation.md) — <!-- begin:auto-docs --> _(no submodules)_- [index](./src/interpolation/index.md) — **Path:** `src/interpolation/interpolation.ts` **Export:** `GameInterpolator`
- [interpolation](./src/interpolation/interpolation.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [instruments](./src/otel/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [prediction](./src/prediction/prediction.md) — <!-- begin:auto-docs --> _(no submodules)_- rotation-predictor — **Path:** `bitpacker-game/src/…
- [index](./src/prediction/index.md) — **Path:** `src/prediction/` **Exports:** `PositionPredictor`, `RotationPredictor`, motion math, Kalman filter, predicti…
- [kalman-filter](./src/prediction/kalman-filter.md) — **Path:** `bitpacker-game/src/prediction/kalman-filter.ts` **Export:** See source for details.
- [motion-math](./src/prediction/motion-math.md) — **Path:** `bitpacker-game/src/prediction/motion-math.ts` **Export:** See source for details.
- [position-predictor](./src/prediction/position-predictor.md) — **Path:** `bitpacker-game/src/prediction/position-predictor.ts` **Export:** See source for details.
- [prediction-algorithms](./src/prediction/prediction-algorithms.md) — **Path:** `bitpacker-game/src/prediction/prediction-algorithms.ts` **Export:** See source for details.
- [prediction](./src/prediction/prediction.md) — <!-- begin:auto-docs --> _(no submodules)_- rotation-predictor — **Path:** `bitpacker-game/src/…
- [rotation-predictor](./src/prediction/rotation-predictor.md) — **Path:** `bitpacker-game/src/prediction/rotation-predictor.ts` **Export:** See source for details.
- [quantization](./src/quantization/quantization.md) — <!-- begin:auto-docs --> _(no submodules)_- [quantization](./src/quantization/quantization.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconciliation](./src/reconciliation/reconciliation.md) — <!-- begin:auto-docs --> _(no submodules)_- [index](./src/reconciliation/index.md) — **Path:** `src/reconciliation/reconciliation.ts` **Export:** `StateReconciliation`
- [reconciliation](./src/reconciliation/reconciliation.md) — <!-- begin:auto-docs --> _(no submodules)_- [schema-factory](./src/schema-factory/schema-factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [schema-factory](./src/schema-factory/schema-factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [state-manager](./src/state-manager/state-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [state-manager](./src/state-manager/state-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [index](./src/index.md) — **Path:** `bitpacker-game/src/index.ts` **Export:** See source for details.
- [register-schemas](./src/register-schemas.md) — Idempotent integration with `@suaveplan/schema-registry` for the `@suaveplan/bitpacker-game` package. Exposes `register…
- [types](./src/types.md) — **Path:** `src/types.ts` **Export:** All game-related type definitions and enums
- [types.schema](./src/types.schema.md) — Zod schemas for the public configuration types of `@suaveplan/bitpacker-game`: the three sub-options bundles (`Predicti…
- [bitpacker](./src/bitpacker/bitpacker.md) — <!-- begin:auto-docs --> _(no submodules)_- [integration-manager](./src/integration-manager/integration-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [integration-manager](./src/integration-manager/integration-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [interpolation](./src/interpolation/interpolation.md) — <!-- begin:auto-docs --> _(no submodules)_- [index](./src/interpolation/index.md) — **Path:** `src/interpolation/interpolation.ts` **Export:** `GameInterpolator`
- [interpolation](./src/interpolation/interpolation.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [instruments](./src/otel/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [prediction](./src/prediction/prediction.md) — <!-- begin:auto-docs --> _(no submodules)_- rotation-predictor — **Path:** `bitpacker-game/src/…
- [index](./src/prediction/index.md) — **Path:** `src/prediction/` **Exports:** `PositionPredictor`, `RotationPredictor`, motion math, Kalman filter, predicti…
- [kalman-filter](./src/prediction/kalman-filter.md) — **Path:** `bitpacker-game/src/prediction/kalman-filter.ts` **Export:** See source for details.
- [motion-math](./src/prediction/motion-math.md) — **Path:** `bitpacker-game/src/prediction/motion-math.ts` **Export:** See source for details.
- [position-predictor](./src/prediction/position-predictor.md) — **Path:** `bitpacker-game/src/prediction/position-predictor.ts` **Export:** See source for details.
- [prediction-algorithms](./src/prediction/prediction-algorithms.md) — **Path:** `bitpacker-game/src/prediction/prediction-algorithms.ts` **Export:** See source for details.
- [prediction](./src/prediction/prediction.md) — <!-- begin:auto-docs --> _(no submodules)_- rotation-predictor — **Path:** `bitpacker-game/src/…
- [rotation-predictor](./src/prediction/rotation-predictor.md) — **Path:** `bitpacker-game/src/prediction/rotation-predictor.ts` **Export:** See source for details.
- [quantization](./src/quantization/quantization.md) — <!-- begin:auto-docs --> _(no submodules)_- [quantization](./src/quantization/quantization.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconciliation](./src/reconciliation/reconciliation.md) — <!-- begin:auto-docs --> _(no submodules)_- [index](./src/reconciliation/index.md) — **Path:** `src/reconciliation/reconciliation.ts` **Export:** `StateReconciliation`
- [reconciliation](./src/reconciliation/reconciliation.md) — <!-- begin:auto-docs --> _(no submodules)_- [schema-factory](./src/schema-factory/schema-factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [schema-factory](./src/schema-factory/schema-factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [state-manager](./src/state-manager/state-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [state-manager](./src/state-manager/state-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [index](./src/index.md) — **Path:** `bitpacker-game/src/index.ts` **Export:** See source for details.
- [register-schemas](./src/register-schemas.md) — Idempotent integration with `@suaveplan/schema-registry` for the `@suaveplan/bitpacker-game` package. Exposes `register…
- [types](./src/types.md) — **Path:** `src/types.ts` **Export:** All game-related type definitions and enums
- [types.schema](./src/types.schema.md) — Zod schemas for the public configuration types of `@suaveplan/bitpacker-game`: the three sub-options bundles (`Predicti…
- [bitpacker](./src/bitpacker/bitpacker.md) — <!-- begin:auto-docs --> _(no submodules)_- [integration-manager](./src/integration-manager/integration-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ - [integration-manager](./src/integration-manager/integration-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [interpolation](./src/interpolation/interpolation.md) — <!-- begin:auto-docs --> _(no submodules)_ - [index](./src/interpolation/index.md) — **Path:** `src/interpolation/interpolation.ts` **Export:** `GameInterpolator`
- [interpolation](./src/interpolation/interpolation.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_ - [instruments](./src/otel/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [prediction](./src/prediction/prediction.md) — <!-- begin:auto-docs --> _(no submodules)_ - [index](./src/prediction/index.md) — **Path:** `src/prediction/` **Exports:** `PositionPredictor`, `RotationPredictor`, motion math, Kalman filter, predicti…
- [kalman-filter](./src/prediction/kalman-filter.md) — **Path:** `bitpacker-game/src/prediction/kalman-filter.ts` **Export:** See source for details.
- [motion-math](./src/prediction/motion-math.md) — **Path:** `bitpacker-game/src/prediction/motion-math.ts` **Export:** See source for details.
- [position-predictor](./src/prediction/position-predictor.md) — **Path:** `bitpacker-game/src/prediction/position-predictor.ts` **Export:** See source for details.
- [prediction-algorithms](./src/prediction/prediction-algorithms.md) — **Path:** `bitpacker-game/src/prediction/prediction-algorithms.ts` **Export:** See source for details.
- [prediction](./src/prediction/prediction.md) — <!-- begin:auto-docs --> _(no submodules)_ - [rotation-predictor](./src/prediction/rotation-predictor.md) — **Path:** `bitpacker-game/src/prediction/rotation-predictor.ts` **Export:** See source for details.
- [quantization](./src/quantization/quantization.md) — <!-- begin:auto-docs --> _(no submodules)_ - [quantization](./src/quantization/quantization.md) — <!-- begin:auto-docs --> _(no submodules)_- [reconciliation](./src/reconciliation/reconciliation.md) — <!-- begin:auto-docs --> _(no submodules)_ - [index](./src/reconciliation/index.md) — **Path:** `src/reconciliation/reconciliation.ts` **Export:** `StateReconciliation`
- [reconciliation](./src/reconciliation/reconciliation.md) — <!-- begin:auto-docs --> _(no submodules)_- [schema-factory](./src/schema-factory/schema-factory.md) — <!-- begin:auto-docs --> _(no submodules)_ - [schema-factory](./src/schema-factory/schema-factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_ - [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [state-manager](./src/state-manager/state-manager.md) — <!-- begin:auto-docs --> _(no submodules)_ - [state-manager](./src/state-manager/state-manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [index](./src/index.md) — **Path:** `bitpacker-game/src/index.ts` **Export:** See source for details.
- [register-schemas](./src/register-schemas.md) — Idempotent integration with `@suaveplan/schema-registry` for the `@suaveplan/bitpacker-game` package. Exposes `register…
- [types](./src/types.md) — **Path:** `src/types.ts` **Export:** All game-related type definitions and enums
- [types.schema](./src/types.schema.md) — Zod schemas for the public configuration types of `@suaveplan/bitpacker-game`: the three sub-options bundles (`Predicti…
## Install
```bash
bun add @suaveplan/bitpacker-game
```
## Usage
```typescript
import {
GameStateManager,
quantizeVector,
dequantizeVector,
PositionPredictor,
RotationPredictor,
GameInterpolator,
StateReconciliation,
PredictionAlgorithm,
InterpolationMethod,
} from "@suaveplan/bitpacker-game";
// Quantization for network compression
const quantized = quantizeVector({ x: 0.5, y: -0.25, z: 0.75 }, 16);
const restored = dequantizeVector(quantized, 16);
// Position prediction
const predictor = new PositionPredictor({ algorithm: PredictionAlgorithm.ADAPTIVE });
predictor.addPosition({ x: 0, y: 0, z: 0 }, 0);
predictor.addPosition({ x: 10, y: 0, z: 0 }, 1000);
const futurePos = predictor.predictPosition(100); // predicted position at t=100ms
// Interpolation
const interp = new GameInterpolator({ method: InterpolationMethod.HERMITE });
const midPos = interp.interpolatePosition({ x: 0, y: 0, z: 0 }, { x: 10, y: 0, z: 0 }, 0.5);
// Client-server reconciliation
const reconciliation = new StateReconciliation();
const seq = reconciliation.processInput({ moveX: 1, moveY: 0, rotateYaw: 0, rotatePitch: 0, actions: [] }, Date.now());
```
## Modules
- `src/index.ts` — `GameStateManager`, `quantizeVector`, `dequantizeVector`
- `src/types.ts` — `Vector3`, `Rotation`, `PlayerState`, `PredictionAlgorithm`, `InterpolationMethod`, etc.
- `src/prediction/` — `PositionPredictor`, `RotationPredictor`, motion math, Kalman filter, prediction algorithms
- `src/interpolation/` — `GameInterpolator` with 9 interpolation methods
- `src/reconciliation/` — `StateReconciliation` for client prediction + server reconciliation

View File

@@ -0,0 +1,82 @@
# GameBitPacker
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`GameBitPacker` is the top-level facade for the `@suaveplan/bitpacker-game` package: a `BitPacker` subclass that composes prediction, interpolation, reconciliation, network simulation, and quantization helpers into one game-ready binary serializer. Most consumers construct one `GameBitPacker` per game session and route every state pack/unpack through it; the four subsystems are wired up internally based on the constructor's `enable*` flags so a consumer doesn't have to chain managers manually.
The class is generic on the schema type (`T extends BitPackerSchema`), so a game's player schema, world schema, and input schema can each have their own typed `GameBitPacker<PlayerSchema>` / `GameBitPacker<WorldSchema>` instance. Internally the class delegates to `GameStateManager` for state ownership, `GameIntegrationManager` for the cross-subsystem orchestration, and the `GameQuantization` namespace for vector/rotation rounding.
## Features
- Inherits everything from `BitPacker` (pack, unpack, schema registry, strategy chain)
- `enablePrediction` / `enableInterpolation` / `enableReconciliation` / `enableNetworkSimulation` toggles
- Composes `PositionPredictor` + `RotationPredictor` + `GameInterpolator` + `StateReconciliation` + `NetworkSimulator`
- Quantization helpers for position, rotation, and 2-D / 3-D vectors via the `GameQuantization` namespace
- Input/state sequence tracking via `GameStateManager` (4-bit sequence wraps at `MAX_SEQUENCE = 15`)
## Usage: Basic Example
```ts
import { GameBitPacker, PLAYER_STATE_SCHEMA } from "@suaveplan/bitpacker-game";
const bp = new GameBitPacker(PLAYER_STATE_SCHEMA, {
enablePrediction: true,
enableInterpolation: true,
});
const packed = bp.pack(playerState);
const restored = bp.unpack(packed);
```
## Usage: Advanced Example
```ts
import {
GameBitPacker,
PLAYER_STATE_SCHEMA,
PredictionAlgorithm,
} from "@suaveplan/bitpacker-game";
const bp = new GameBitPacker(PLAYER_STATE_SCHEMA, {
enablePrediction: true,
enableInterpolation: true,
enableReconciliation: true,
enableNetworkSimulation: true,
predictionOptions: {
algorithm: PredictionAlgorithm.KALMAN,
historySize: 8,
},
reconciliationOptions: {
inputBufferSize: 60,
stateBufferSize: 120,
enableExtrapolation: true,
},
networkSimulationOptions: {
latencyMin: 30,
latencyMax: 80,
packetLoss: 1,
},
});
bp.pushState(serverFrame);
bp.applyPhysics((state, input, dt) => /* simulate */ state, currentInput, 1 / 60);
const interpolated = bp.interpolate(prev, next, 0.5);
```
## API Reference
### `class GameBitPacker<T extends BitPackerSchema> extends BitPacker<T>`
Constructed with `new GameBitPacker<T>(schema, options?)`. `options` defaults to `DEFAULT_GAME_BITPACKER_OPTIONS` (every subsystem disabled). Every method inherited from `BitPacker` (`pack`, `unpack`, `registerSchema`, `registerStrategy`) works without modification.
Subsystem-specific methods include `pushState`, `getLatestState`, `applyPhysics`, `predictPosition`, `interpolate`, `reconcile`, and `quantizePosition` — see the corresponding subsystem `.md` files for detailed semantics.
## Implementation Notes
- **Composition over inheritance for subsystems.** Although `GameBitPacker extends BitPacker`, the four subsystems (`Predictor`, `Interpolator`, `Reconciliation`, `NetworkSimulator`) are composed members, not inherited classes. This keeps each subsystem testable in isolation and lets a consumer construct a `GameBitPacker` with only the subsystems they need.
- **`enable*` flags gate construction, not pack/unpack.** Disabled subsystems are not constructed at all (saves memory in lightweight server pipelines that just pack/unpack); their methods throw if called when the corresponding flag is `false`.
- **No global state.** Every internal manager is instance-scoped — multiple `GameBitPacker` instances coexist without cross-talk.
- **Sequence wrapping at 4 bits.** `GameStateManager.MAX_SEQUENCE = 15` enforces the 4-bit wire-format constraint inherited from upstream. Consumers serializing sequence numbers across the wire must respect this cap.

View File

@@ -0,0 +1,8 @@
## index
**Path:** `bitpacker-game/src/index.ts`
**Export:** See source for details.
### What it does
Part of the @suaveplan/ package.

View File

@@ -0,0 +1,77 @@
# GameIntegrationManager
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Cross-subsystem orchestration for the `GameBitPacker`. `GameIntegrationManager<T>` owns the four optional subsystems (`PositionPredictor`, `RotationPredictor`, `GameInterpolator`, `StateReconciliation`, `NetworkSimulator`) and routes calls between them so the `GameBitPacker` facade exposes a single high-level API instead of a five-way junction. Constructing a manager with `enable*: false` flags omits the corresponding subsystem entirely — the manager allocates only what's enabled.
The integration manager is the right home for cross-subsystem invariants: e.g. when a reconciliation rollback fires, the predictor's history needs to be rewound by the same number of frames, and the interpolator's smoothing buffer needs to be flushed. Centralizing those rules here keeps each subsystem free of cross-knowledge.
## Features
- Optional construction of `PositionPredictor`, `RotationPredictor`, `GameInterpolator`, `StateReconciliation`, `NetworkSimulator`
- Routes `applyPhysics`, `predictPosition`, `interpolate`, `reconcile`, `simulateSend`, `simulateReceive` to the corresponding subsystem
- Flushes / rewinds dependent subsystems atomically on reconciliation rollback
- Exposes `getNetworkStats(): NetworkSimulationStats` to surface aggregate counters
- All subsystems are accessible via their typed getters for advanced use
## Usage: Basic Example
```ts
import { GameIntegrationManager, PLAYER_STATE_SCHEMA } from "@suaveplan/bitpacker-game";
const mgr = new GameIntegrationManager(PLAYER_STATE_SCHEMA, {
enablePrediction: true,
enableInterpolation: true,
});
const predicted = mgr.predictPosition(currentPos, /*dt*/ 16);
const smooth = mgr.interpolate(prev, next, 0.5);
```
## Usage: Advanced Example
```ts
import {
GameIntegrationManager,
PLAYER_STATE_SCHEMA,
PredictionAlgorithm,
PacketStatus,
} from "@suaveplan/bitpacker-game";
const mgr = new GameIntegrationManager(PLAYER_STATE_SCHEMA, {
enablePrediction: true,
enableReconciliation: true,
enableNetworkSimulation: true,
predictionOptions: { algorithm: PredictionAlgorithm.KALMAN, historySize: 8 },
networkSimulationOptions: { latencyMin: 50, latencyMax: 100, packetLoss: 2 },
});
const send = mgr.simulateSend(payload);
if (send.status === PacketStatus.DELIVERED) {
/* …route through pipeline… */
}
const stats = mgr.getNetworkStats();
console.log(stats.packetLossRate, stats.averageLatency);
```
## API Reference
### `class GameIntegrationManager<T extends BitPackerSchema>`
Constructor takes the schema and a `GameBitPackerOptions` bundle. Subsystems are allocated based on the `enable*` flags.
#### Routing methods
- `predictPosition(current, dt)` / `predictRotation(current, dt)` — delegate to the corresponding predictor; throw if prediction is disabled
- `interpolate(a, b, t)` — delegate to the interpolator
- `reconcile(serverState, clientHistory)` — delegate to the reconciliation manager and atomically flush dependent subsystems
- `simulateSend(payload)` / `simulateReceive(payload)` — delegate to the network simulator and emit OTel events on the parent span
- `getNetworkStats()` — return the simulator's aggregate counters
## Implementation Notes
- **Atomic rollback semantics.** When `reconcile` performs a rollback, the predictor's history is truncated to the rollback frame and the interpolator's smoothing buffer is flushed in the same call. Splitting these into separate calls would create a window where the predictor and interpolator disagree on the canonical timeline.
- **Disabled subsystems throw, don't no-op.** Calling `predictPosition` with `enablePrediction: false` throws rather than returning a stub value. Silently no-op'ing would mask configuration bugs at the call site.
- **NetworkSimulator events.** `simulateSend` / `simulateReceive` are the only routing methods that produce per-packet OTel events on the parent `bitpacker_game.send` / `bitpacker_game.receive` spans. The other subsystems are too high-frequency to instrument per-call.

View File

@@ -0,0 +1,39 @@
## Interpolation
**Path:** `src/interpolation/interpolation.ts`
**Export:** `GameInterpolator`
### What it does
Advanced interpolation of game state between two points in time. Supports 9 interpolation methods for positions and rotations.
### Methods
| Method | Description |
|--------|-------------|
| `LINEAR` | Simple lerp |
| `CUBIC` | Cubic easing |
| `HERMITE` | Hermite spline with tension/bias |
| `CATMULL_ROM` | Catmull-Rom spline |
| `BEZIER` | Cubic Bezier |
| `SPRING` | Spring physics |
| `ELASTIC` | Elastic easing |
| `BOUNCE` | Bounce easing |
| `SMOOTHSTEP` | 3t² - 2t³ smoothstep |
### Key API
| Method | Description |
|--------|-------------|
| `interpolatePosition(start, end, t, method?)` | Interpolate `Vector3` |
| `interpolateRotation(start, end, t, method?)` | Interpolate `Rotation` with angle wrapping |
| `interpolatePlayerState(start, end, t)` | Full player state interpolation |
| `interpolatePath(points, t, method?)` | Interpolate along a path of points |
### Rotation Handling
Yaw is normalized to `[-180, 180]` and takes the shortest path. Pitch is clamped to `[-90, 90]`.
### Depends on
- `../types.js` — `Vector3`, `Rotation`, `PlayerState`, `InterpolationOptions`

View File

@@ -0,0 +1,12 @@
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## interpolation
**Path:** `bitpacker-game/src/interpolation/interpolation.ts`
**Export:** See source for details.
### What it does
Part of the @suaveplan/ package.

View File

@@ -0,0 +1,94 @@
# Bitpacker Game OTel Instruments
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
OTel meter, tracer, counter, and histogram declarations for `@suaveplan/bitpacker-game`. Ships canonical instrumentation primitives for the `GameBitPacker`'s pack/unpack boundaries plus the three sub-systems (`prediction`, `interpolation`, `reconciliation`). The instruments file is the canonical source of truth for the package's metric and span vocabulary so consumers wiring a game pipeline can attach observability without re-deriving names.
The metric and span names follow the suaveplan convention: tracer/meter named `@suaveplan/bitpacker-game`; spans named `bitpacker_game.<operation>` (`pack`, `unpack`, `predict`, `interpolate`, `reconcile`); counters named `bitpacker_game.<scope>.<metric>`. This shape matches the rest of the bitpacker family.
## Features
- `getBitPackerGameTracer()` — returns the package's tracer
- `gameBitPackerOpsTotal` — counter labelled by `op` and `success`
- `gameBitPackerOpDurationMs` — histogram of pack/unpack duration
- `gameSubsystemOpsTotal` — counter labelled by `subsystem` and `success`
- `BITPACKER_GAME_SPAN_NAMES` — five canonical span names
## Usage: Basic Example
```ts
import {
BITPACKER_GAME_SPAN_NAMES,
gameBitPackerOpsTotal,
getBitPackerGameTracer,
} from "@suaveplan/bitpacker-game";
const tracer = getBitPackerGameTracer();
tracer.startActiveSpan(BITPACKER_GAME_SPAN_NAMES.pack, (span) => {
try {
// pack work
gameBitPackerOpsTotal.add(1, { op: "pack", success: "true" });
} finally {
span.end();
}
});
```
## Usage: Advanced Example
```ts
import {
BITPACKER_GAME_SPAN_NAMES,
gameSubsystemOpsTotal,
getBitPackerGameTracer,
} from "@suaveplan/bitpacker-game";
function runPredict(state: unknown) {
const tracer = getBitPackerGameTracer();
return tracer.startActiveSpan(
BITPACKER_GAME_SPAN_NAMES.predict,
(span) => {
try {
// predict
gameSubsystemOpsTotal.add(1, {
subsystem: "prediction",
success: "true",
});
return state;
} finally {
span.end();
}
}
);
}
```
## API Reference
### `getBitPackerGameTracer(): Tracer`
Returns the OTel `Tracer` instance for the package.
### `gameBitPackerOpsTotal: Counter`
Counter labelled by `op: "pack" | "unpack"` and `success: "true" | "false"`.
### `gameBitPackerOpDurationMs: Histogram`
Histogram of elapsed milliseconds per pack/unpack call, labelled by `op`.
### `gameSubsystemOpsTotal: Counter`
Counter labelled by `subsystem: "prediction" | "interpolation" | "reconciliation"` and `success`.
### `BITPACKER_GAME_SPAN_NAMES`
Const map: `{ pack, unpack, predict, interpolate, reconcile }` → canonical span names.
## Implementation Notes
- **Five sub-spans, one parent.** The pack/unpack span is the parent; predict/interpolate/reconcile spans are children when called from inside the pack/unpack hot path. Standalone calls produce a top-level span of the corresponding name.
- **No per-frame spans.** The game subsystems run at frame rate on real-time pipelines; one span per frame would explode trace volume. The counters fire per frame; the spans are reserved for boundary entries.

View File

@@ -0,0 +1,39 @@
## Prediction
**Path:** `src/prediction/`
**Exports:** `PositionPredictor`, `RotationPredictor`, motion math, Kalman filter, prediction algorithms
### What it does
Position and rotation prediction for game state extrapolation. Supports multiple algorithms from simple linear extrapolation to Kalman filtering.
### Key Classes
| Class | Description |
|-------|-------------|
| `PositionPredictor` | Predicts future positions from historical data |
| `RotationPredictor` | Predicts future rotations from historical data |
### Algorithms
| Algorithm | Description |
|-----------|-------------|
| `linearPredict` | Constant velocity extrapolation |
| `quadraticPredict` | Velocity + acceleration |
| `cubicPredict` | Velocity + acceleration + jerk |
| `hermitePredict` | Hermite spline extrapolation |
| `catmullRomPredict` | Catmull-Rom spline extrapolation |
| `verletPredict` | Physics-based Verlet integration |
| `kalmanPredict` | Kalman filter prediction |
### Adaptive Mode
`PositionPredictor` with `algorithm: ADAPTIVE` automatically switches algorithms based on prediction error:
- Error > 2× threshold → Kalman
- Error > threshold → Verlet
- Otherwise → Cubic
### Depends on
- `../types.js` — `Vector3`, `Rotation`, `PredictionOptions`, `KalmanState`

View File

@@ -0,0 +1,8 @@
## kalman-filter
**Path:** `bitpacker-game/src/prediction/kalman-filter.ts`
**Export:** See source for details.
### What it does
Part of the @suaveplan/ package.

View File

@@ -0,0 +1,8 @@
## motion-math
**Path:** `bitpacker-game/src/prediction/motion-math.ts`
**Export:** See source for details.
### What it does
Part of the @suaveplan/ package.

View File

@@ -0,0 +1,8 @@
## position-predictor
**Path:** `bitpacker-game/src/prediction/position-predictor.ts`
**Export:** See source for details.
### What it does
Part of the @suaveplan/ package.

View File

@@ -0,0 +1,8 @@
## prediction-algorithms
**Path:** `bitpacker-game/src/prediction/prediction-algorithms.ts`
**Export:** See source for details.
### What it does
Part of the @suaveplan/ package.

View File

@@ -0,0 +1,80 @@
# Prediction Subsystem
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs --> - rotation-predictor — **Path:** `bitpacker-game/src/…
- [rotation-predictor](./rotation-predictor.md) — **Path:** `bitpacker-game/src/prediction/rotation-predictor.ts` **Export:** See source for details.
- rotation-predictor — **Path:** `bitpacker-game/src/…
- [rotation-predictor](./rotation-predictor.md) — **Path:** `bitpacker-game/src/prediction/rotation-predictor.ts` **Export:** See source for details.
- rotation-predictor — **Path:** `bitpacker-game/src/…
- [rotation-predictor](./rotation-predictor.md) — **Path:** `bitpacker-game/src/prediction/rotation-predictor.ts` **Export:** See source for details.
- rotation-predictor — **Path:** `bitpacker-game/src/…
- [rotation-predictor](./rotation-predictor.md) — **Path:** `bitpacker-game/src/prediction/rotation-predictor.ts` **Export:** See source for details.
- [rotation-predictor](./rotation-predictor.md) — **Path:** `bitpacker-game/src/prediction/rotation-predictor.ts` **Export:** See source for details.
## Purpose
Position and rotation extrapolation primitives for the `GameBitPacker`. The module is a re-export barrel that surfaces every prediction algorithm — Kalman filter, motion-math derivatives (velocity, acceleration, jerk), per-algorithm predictor classes (`PositionPredictor`, `RotationPredictor`), and the seven supported extrapolation algorithms (linear, quadratic, cubic, hermite, catmull-rom, velocity-verlet, kalman). Consumers pick an algorithm via the `PredictionAlgorithm` enum on the `predictionOptions` they pass to `GameBitPacker`.
The Kalman family is the most accurate (model-based filter that learns process and measurement noise from observed updates). The polynomial family (linear / quadratic / cubic) is cheap and good enough for slow-moving entities. Hermite and Catmull-Rom interpolation produce smooth trajectories from sparse samples and are the right pick for cinematic camera or replay playback. Velocity-Verlet is the staple for physics-driven motion where acceleration is known.
## Features
- `initKalmanState`, `kalmanPredict`, `updateKalmanFilter` — Kalman filter primitives
- `calculateVelocity`, `calculateAcceleration`, `calculateJerk`, `calculateVelocityAt`, `calculateAccelerationAt` — discrete-difference motion math
- `linearPredict`, `quadraticPredict`, `cubicPredict`, `hermitePredict`, `catmullRomPredict`, `verletPredict` — six pure extrapolation functions
- `PositionPredictor`, `RotationPredictor` — stateful predictors that remember a rolling history and pick the algorithm at construction
## Usage: Basic Example
```ts
import { PositionPredictor, PredictionAlgorithm } from "@suaveplan/bitpacker-game";
const predictor = new PositionPredictor({
algorithm: PredictionAlgorithm.LINEAR,
historySize: 5,
});
predictor.observe({ x: 0, y: 0, z: 0 }, 0);
predictor.observe({ x: 1, y: 0, z: 0 }, 16);
predictor.observe({ x: 2, y: 0, z: 0 }, 32);
const next = predictor.predict(48); // { x: 3, y: 0, z: 0 }
```
## Usage: Advanced Example
```ts
import {
initKalmanState,
kalmanPredict,
updateKalmanFilter,
calculateVelocity,
} from "@suaveplan/bitpacker-game";
let kf = initKalmanState({ x: 0, y: 0, z: 0 });
function frame(observation: { x: number; y: number; z: number }, dt: number) {
kf = updateKalmanFilter(kf, observation, dt);
const predicted = kalmanPredict(kf, dt);
const v = calculateVelocity(predicted, kf.position, dt);
return { predicted, velocity: v };
}
```
## API Reference
This module is a barrel re-export; see the per-algorithm `.md` files (when they ship) for full per-function semantics. The headline exports are:
- `PositionPredictor` and `RotationPredictor` — stateful predictors with `observe(value, timestamp)` and `predict(timestamp)` methods
- The six pure prediction functions, each `(history: Vector3[], dt: number) => Vector3`
- `initKalmanState(initial)`, `updateKalmanFilter(state, obs, dt)`, `kalmanPredict(state, dt)` for direct Kalman usage
## Implementation Notes
- **Algorithm choice is a behaviour decision.** The `PredictionAlgorithm` enum is open via declaration merging, but each value implies different observation requirements: linear needs 2 samples, quadratic 3, cubic 4, Catmull-Rom 4, Hermite 2 + tangents, Verlet 2 + acceleration, Kalman a fitted state. Picking an algorithm without enough history degrades to a fallback (typically linear).
- **`historySize` is a soft cap, not a hard one.** The predictor stores up to `historySize` samples in a ring buffer; older samples are dropped on overflow. A larger buffer improves polynomial fit accuracy but raises latency on unstable observations.
- **No coordinate-system assumption.** All predictors operate on a generic `Vector3` (`{ x, y, z }`); rotations are wrapped to `[-π, π]` by `RotationPredictor` before extrapolation to avoid spurious 2π jumps on yaw wrap.
- **Process / measurement noise are tunable.** Kalman state exposes `processNoise` and `measurementNoise`. The defaults are tuned for 60 Hz simulation; faster sample rates need lower noise values to avoid over-smoothing.

View File

@@ -0,0 +1,8 @@
## rotation-predictor
**Path:** `bitpacker-game/src/prediction/rotation-predictor.ts`
**Export:** See source for details.
### What it does
Part of the @suaveplan/ package.

View File

@@ -0,0 +1,84 @@
# Game Quantization Helpers
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Coordinate-rounding helpers for game-state vectors and rotations. The functions in this module trade absolute precision for compact wire representations: `quantizePosition({ x: 1.234, y: 5.678, z: 9.012 }, 0.01)` rounds each component to two decimal places before packing, halving the bit-width versus a raw float. This is the standard tactic for bandwidth-constrained multiplayer games — a typical ±1024 m world quantized to 0.01 m precision packs into ~17 bits per axis instead of 32 bits.
The 2-D and 3-D variants exist because some games (top-down, side-scrolling) work in `Vector2` and would otherwise pay the cost of a wasted z component. `quantizeRotation` separately handles yaw and pitch with their own precisions; `interpolateAngle` handles the 360°/0° wrap so a transition from 350° to 10° interpolates through the short arc, not the long one. `validateRange` is a defensive check used at API boundaries.
## Features
- `quantizePosition(position, precision = 0.01)` — round a `Vector3` to a precision divisor
- `quantizePosition2D(position, precision = 0.01)` — round a `Vector2`
- `quantizeRotation(rotation, yawPrecision = 1, pitchPrecision = 1)` — round yaw + pitch
- `interpolateAngle(a, b, t)` — interpolate angles in degrees, taking the short arc through the wrap
- `validateRange(value, min, max, name?)` — throw if out of range, with an optional field name for the error
## Usage: Basic Example
```ts
import { quantizePosition, quantizeRotation } from "@suaveplan/bitpacker-game";
const pos = quantizePosition({ x: 1.234, y: 5.678, z: 9.012 }, 0.01);
// { x: 1.23, y: 5.68, z: 9.01 }
const rot = quantizeRotation({ yaw: 90.55, pitch: -45.4 }, 1, 1);
// { yaw: 91, pitch: -45 }
```
## Usage: Advanced Example
```ts
import {
quantizePosition,
quantizeRotation,
interpolateAngle,
validateRange,
} from "@suaveplan/bitpacker-game";
function tick(prev: { yaw: number }, target: { yaw: number }, t: number) {
validateRange(t, 0, 1, "interpolation t");
return { yaw: interpolateAngle(prev.yaw, target.yaw, t) };
}
// Quantize before pack to match the schema's fixed-point precision exactly:
function preparePacket(position: { x: number; y: number; z: number }) {
const q = quantizePosition(position, 0.01);
validateRange(q.x, -1024, 1024, "x");
validateRange(q.y, -1024, 1024, "y");
validateRange(q.z, -128, 128, "z");
return q;
}
```
## API Reference
### `quantizePosition(position: Vector3, precision = 0.01): Vector3`
Returns a new `Vector3` with each component rounded to `precision` (e.g. `0.01` for two decimal places, `1` for whole units). The result is the nearest grid point on a precision-divisor lattice.
### `quantizePosition2D(position: Vector2, precision = 0.01): Vector2`
Same as `quantizePosition` for a 2-D vector. No z component.
### `quantizeRotation(rotation: Rotation, yawPrecision = 1, pitchPrecision = 1): Rotation`
Returns a new `Rotation` with `yaw` and `pitch` rounded to their respective precisions. The two axes have separate precisions because yaw typically needs less granularity than pitch (or vice versa).
### `interpolateAngle(a: number, b: number, t: number): number`
Returns the interpolation between `a` and `b` taking the short arc through the 360°/0° wrap. `t ∈ [0, 1]`. Equivalent to slerp on the unit circle for two-axis cases.
### `validateRange(value: number, min: number, max: number, name?: string): void`
Throws if `value` is outside `[min, max]`. The optional `name` is included in the error message to identify the offending field.
## Implementation Notes
- **Quantization is round-to-nearest-grid.** `Math.round(value / precision) * precision` produces banker's rounding behaviour at the exact half. Consumers that need round-half-up should pre-add a half-precision offset before quantizing.
- **No clamp.** These helpers do not clamp out-of-range values; pair them with `validateRange` if your wire format has a hard cap. Quantizing without clamping can produce values outside the schema's bit-width and cause pack failures.
- **`interpolateAngle` is not unwrap-aware.** It takes the short arc per pair; chains of three or more interpolated angles can drift unless the consumer normalizes between calls.
- **Defensive-but-cheap.** `validateRange` is `O(1)` and emits a clear error message including the field name; it's appropriate at every API boundary, not just hot-path entries.

View File

@@ -0,0 +1,41 @@
## Reconciliation
**Path:** `src/reconciliation/reconciliation.ts`
**Export:** `StateReconciliation`
### What it does
Client-side prediction and server reconciliation for multiplayer games. Buffers inputs and server states, detects mispredictions, and smoothly reconciles client state.
### Key API
| Method | Description |
|--------|-------------|
| `processInput(input, timestamp)` | Buffer a player input, return sequence |
| `predictClientState(state, applyPhysics, deltaTime)` | Apply unprocessed inputs locally |
| `processServerUpdate(state, sequence, timestamp)` | Receive server-authoritative state |
| `reconcileState(state, applyPhysics)` | Rewind + replay after server correction |
| `extrapolateState(state, deltaTime)` | Predict forward for missing server data |
| `sendPing()` / `receivePong()` | Latency measurement |
### Buffers
- **Input buffer** — stores client inputs with sequence numbers
- **State buffer** — stores predicted and server states
- **Jitter buffer** — optional delay for out-of-order server packets
### Reconciliation Flow
1. Client predicts state from inputs
2. Server sends authoritative state
3. If prediction error > threshold, reconcile:
- Find server state in buffer
- Rewind to server state
- Replay all inputs after that point
- Smoothly interpolate to reconciled state
### Depends on
- `../types.js` — `PlayerState`, `PlayerInput`, `ReconciliationOptions`
- `../prediction/` — `PositionPredictor`
- `../interpolation/` — `GameInterpolator`

View File

@@ -0,0 +1,12 @@
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## reconciliation
**Path:** `bitpacker-game/src/reconciliation/reconciliation.ts`
**Export:** See source for details.
### What it does
Part of the @suaveplan/ package.

View File

@@ -0,0 +1,65 @@
# Register Schemas — `@suaveplan/bitpacker-game`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Idempotent integration with `@suaveplan/schema-registry` for the `@suaveplan/bitpacker-game` package. Exposes `registerBitPackerGameSchemas(registry)` which converts the package's six public boundary schemas into JSON Schema form and registers them under `bitpacker:@suaveplan/bitpacker-game` at version 1. Re-registration on the same registry is a no-op.
The six schemas covered are: `predictionOptions`, `interpolationOptions`, `reconciliationOptions` (the three sub-options bundles), `gameStateSchema` (the `{ version, entities }` envelope), `quantizedVector` (the `quantizeVector` / `dequantizeVector` input), and `gameBitPackerOptions` (the top-level `GameBitPacker` constructor bundle). Together they describe every external configuration shape the package accepts.
## Features
- `BITPACKER_GAME_SUBJECT` constant — `"bitpacker:@suaveplan/bitpacker-game"`
- `BITPACKER_GAME_SCHEMA_VERSION` constant — `1`
- `registerBitPackerGameSchemas(registry)` — idempotent registration
## Usage: Basic Example
```ts
import { createRegistry } from "@suaveplan/schema-registry";
import {
BITPACKER_GAME_SUBJECT,
registerBitPackerGameSchemas,
} from "@suaveplan/bitpacker-game/register-schemas";
const registry = createRegistry();
registerBitPackerGameSchemas(registry);
```
## Usage: Advanced Example
```ts
import { createRegistry, SchemaRegistry } from "@suaveplan/schema-registry";
import { registerBitPackerSchemas } from "@suaveplan/bitpacker/register-schemas";
import { registerBitPackerGameSchemas } from "@suaveplan/bitpacker-game/register-schemas";
function bootstrapAll(registry: SchemaRegistry) {
registerBitPackerSchemas(registry);
registerBitPackerGameSchemas(registry);
}
const registry = createRegistry();
bootstrapAll(registry);
```
## API Reference
### `BITPACKER_GAME_SUBJECT: "bitpacker:@suaveplan/bitpacker-game"`
Const string.
### `BITPACKER_GAME_SCHEMA_VERSION: 1`
Const number.
### `registerBitPackerGameSchemas(registry: SchemaRegistry): void`
Idempotent registration. Returns without writing if the subject is already present.
## Implementation Notes
- **Six-key payload.** One key per public boundary schema.
- **`unrepresentable: "any"`.** Required because the option bundles use `z.custom` for clock and signal injection points.

View File

@@ -0,0 +1,68 @@
# Game Schema Factory
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Programmatic schema construction for game-specific bitpacker schemas. `createGameSchema(options)` returns a tuned `BitPackerSchema` based on the consumer's choice of position bit-width, rotation precision, health/speed caps, and other gameplay-domain knobs. The function lets a consumer derive a schema from per-game design parameters (e.g. "this game has 1024 m world bounds with 0.01 m precision") rather than hand-rolling the same schema across multiple sources.
The `GameSchemaFactory` const is a curated set of named factory presets — `small`, `medium`, `large`, `precise`, `arcade` — each producing a `BitPackerSchema` with appropriate trade-offs. New presets can be appended; the consumer's `createGameSchema(options)` always overrides preset defaults with explicit options.
## Features
- `createGameSchema(options?)` — main factory that returns a fully-tuned `BitPackerSchema`
- `GameSchemaFactory` — const map of named presets (`small`, `medium`, `large`, `precise`, `arcade`)
- `GameSchemaOptions` — `maxPosition`, `positionPrecision`, `maxRotation`, `rotationPrecision`, `maxHealth`, `maxSpeed`, plus optional fields for actions, effects, animations
- All numeric inputs are checked at construction; out-of-range values produce an error rather than a corrupted schema
## Usage: Basic Example
```ts
import { createGameSchema } from "@suaveplan/bitpacker-game";
const schema = createGameSchema({
maxPosition: 512,
positionPrecision: 1,
maxHealth: 100,
});
```
## Usage: Advanced Example
```ts
import {
createGameSchema,
GameBitPacker,
GameSchemaFactory,
} from "@suaveplan/bitpacker-game";
// Pick a preset for arcade-style games (small world, low precision):
const arcade = GameSchemaFactory.arcade;
const arcadeBP = new GameBitPacker(arcade);
// Or compose: start from a preset and override a single knob:
const customLarge = createGameSchema({
...GameSchemaFactory.large,
rotationPrecision: 0.1, // fine yaw for first-person aim
maxSpeed: 20,
});
const customBP = new GameBitPacker(customLarge);
```
## API Reference
### `createGameSchema(options?: GameSchemaOptions): BitPackerSchema`
Builds a `BitPackerSchema` for a player state with position, rotation, stats, and optional metadata. `options` defaults to `{ maxPosition: 1024, positionPrecision: 2, maxRotation: 180, rotationPrecision: 1, maxHealth: 100, maxSpeed: 8 }`. Returns a schema ready to pass to `new GameBitPacker(schema)`.
### `GameSchemaFactory: { small, medium, large, precise, arcade }`
Const map of pre-built schemas. Each preset is a fully-tuned `BitPackerSchema` produced by `createGameSchema` with appropriate options. Consumers use these as starting points or as drop-in choices for typical game shapes.
## Implementation Notes
- **Precision is a divisor, not a digit count.** `positionPrecision: 0.01` means the schema rounds positions to 2-decimal places (1/100). `positionPrecision: 1` means whole units. The fixed-point bit width is computed from `maxPosition / precision`.
- **Rotation is wrapped to `[-180, 180]`.** Values outside this range are treated as out-of-range at pack time; consumers handling continuous rotations must wrap to this range first.
- **Schema shape is stable across presets.** All factory output shares the same top-level keys (`position`, `rotation`, `stats`, `optional`); only the per-field bit-widths differ. This lets a consumer swap presets at runtime without re-deriving downstream code.
- **No defaults in the schema itself.** The output is a pure schema; default values for missing fields are the consumer's responsibility (e.g. via the optional-with-default strategy in `@suaveplan/bitpacker-strategies`).

View File

@@ -0,0 +1,97 @@
# Pre-tuned Game Schemas
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
A curated set of `BitPackerSchema` constants tuned for common game-state shapes — player position, rotation, stats, optional metadata, world updates, player input — plus the `createDeltaSchema` factory that mirrors any of those into its delta form. Constants here are the right choice when a game's data model fits the upstream conventions (1024 m bounded world, 0.01 m precision, 180° rotation, 0–100 health). Games with unusual ranges should use the `createGameSchema` factory in the `schema-factory` module instead.
The schemas are designed to compose: `PLAYER_STATE_SCHEMA` references `PLAYER_POSITION_SCHEMA`, `PLAYER_ROTATION_SCHEMA`, `PLAYER_STATS_SCHEMA`, and the optional bundle. `WORLD_UPDATE_SCHEMA` references the player schema array. Replacing one constant in a downstream consumer cascades automatically to the consumers of the composed schemas.
## Features
- `PLAYER_POSITION_SCHEMA` — fixed-point `{ x, y, z }` with 0.01 precision and ±1024 m / ±128 m ranges
- `PLAYER_ROTATION_SCHEMA` — fixed-point `{ yaw, pitch }`, ±180° / ±90° respectively
- `PLAYER_STATS_SCHEMA` — `{ health, shield, speed, isMoving, isSprinting }` tuned for a typical FPS
- `PLAYER_OPTIONAL_SCHEMA` — animation name + effect-id array, both optional
- `PLAYER_STATE_SCHEMA` — composes all of the above into one player snapshot
- `WORLD_UPDATE_SCHEMA` — variable-length array of player states + a 16-bit tick
- `PLAYER_INPUT_SCHEMA` — analog move + rotate axes + action-id array
- `createDeltaSchema(base)` — wraps any base schema in a delta envelope (changed-mask + per-field optional)
## Usage: Basic Example
```ts
import { GameBitPacker, PLAYER_STATE_SCHEMA } from "@suaveplan/bitpacker-game";
const bp = new GameBitPacker(PLAYER_STATE_SCHEMA);
const bytes = bp.pack({
position: { x: 100, y: 0, z: 50 },
rotation: { yaw: 90, pitch: 0 },
stats: { health: 95, shield: 50, speed: 5, isMoving: true, isSprinting: false },
});
```
## Usage: Advanced Example
```ts
import {
GameBitPacker,
PLAYER_INPUT_SCHEMA,
WORLD_UPDATE_SCHEMA,
createDeltaSchema,
PLAYER_STATE_SCHEMA,
} from "@suaveplan/bitpacker-game";
// Server emits world snapshots every tick:
const worldBP = new GameBitPacker(WORLD_UPDATE_SCHEMA);
// Client emits inputs at frame rate:
const inputBP = new GameBitPacker(PLAYER_INPUT_SCHEMA);
// Server transmits deltas instead of full snapshots:
const playerDeltaSchema = createDeltaSchema(PLAYER_STATE_SCHEMA);
const deltaBP = new GameBitPacker(playerDeltaSchema);
```
## API Reference
### `PLAYER_POSITION_SCHEMA: PositionSchema`
`{ x: "-1024.2", y: "-1024.2", z: "-128.2" }` — signed fixed-point with 0.01 precision. The `-` prefix marks the field as signed.
### `PLAYER_ROTATION_SCHEMA: RotationSchema`
`{ yaw: "-180.1", pitch: "-90.1" }` — signed fixed-point with 0.1 precision.
### `PLAYER_STATS_SCHEMA: PlayerStatsSchema`
`{ health: 100, shield: 100, speed: "8.2", isMoving: true, isSprinting: true }` — uint, uint, fixed-point, bool, bool.
### `PLAYER_OPTIONAL_SCHEMA: PlayerOptionalSchema`
Optional `{ animation, effects }` bundle. Animation is a variable-length string; effects is a variable-length array of compact ids.
### `PLAYER_STATE_SCHEMA: PlayerStateSchema`
Composes `position`, `rotation`, `stats`, `optional`. The canonical shape every game subsystem reads from.
### `WORLD_UPDATE_SCHEMA: WorldUpdateSchema`
`{ tick: 65535, players: [PLAYER_STATE_SCHEMA] }` — one tick + a variable-length array of player states.
### `PLAYER_INPUT_SCHEMA: PlayerInputSchema`
`{ moveX, moveY, rotateYaw, rotatePitch, actions }` — four signed fixed-point axes plus an action-id array.
### `createDeltaSchema<T>(base: T): DeltaSchema<T>`
Returns a schema that wraps `base` with a per-field changed-mask and optional fields. The wrapped schema is appropriate for incremental updates where most fields stay the same frame-to-frame.
## Implementation Notes
- **Bit-widths are tuned for typical FPS games.** ±1024 m world with 0.01 m precision uses ~17 bits per axis after sign + integer + fractional. Smaller worlds save bits per field; the consumer should switch to `createGameSchema` if the defaults are wasteful.
- **`isMoving` + `isSprinting` are independent.** The schema models them as two booleans because a player can be sprinting while not moving (e.g. holding sprint while stuck against a wall) — collapsing to a single tri-state would lose that distinction.
- **`createDeltaSchema` is a factory, not a const.** It returns a fresh schema every call so the consumer can apply additional transformations (e.g. swapping in a custom `_optional` strategy) without mutating shared state.
- **No timestamps in the player schema.** Timing is owned by the `tick` field on `WORLD_UPDATE_SCHEMA`. Consumers that want per-player timestamps must add a `_optional` field at their own layer.

View File

@@ -0,0 +1,85 @@
# GameStateManager
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
State ownership and delta tracking for the `GameBitPacker`. `GameStateManager<T>` holds the current authoritative state, the last-sent state (for delta computation), and a 4-bit rolling sequence number used to identify out-of-order or duplicate updates on the wire. The class is generic on the `BitPackerSchema` to keep the held state type-safe; the implementation stores the value as `unknown` internally because schema-driven serialization erases the static type at the boundary.
The 4-bit sequence is the key wire-format constraint: the upstream `bitpacker-game` reserves four bits per state update to discriminate which update a delta refers to. `MAX_SEQUENCE = 15` is exposed as a `static readonly` field so callers can validate sequence wraps without redeclaring the constant.
## Features
- `updateState` — replace the current authoritative state
- `getLatestState` / `getLastSentState` — accessors for the live state and the last-transmitted state
- `markSent` — record that the current state has been transmitted (advances the rolling sequence)
- `processReceived` — handle an incoming update, gate against `lastReceivedSequence` to drop replays
- `computeDelta` — produce a `StateDelta<T>` describing the change from `lastSentState` to `currentState`
- `MAX_SEQUENCE` — the 4-bit wire-format cap (`15`)
## Usage: Basic Example
```ts
import { GameStateManager } from "@suaveplan/bitpacker-game";
const manager = new GameStateManager();
manager.updateState({ x: 10, y: 20 });
const latest = manager.getLatestState();
```
## Usage: Advanced Example
```ts
import { GameStateManager } from "@suaveplan/bitpacker-game";
const manager = new GameStateManager<{ position: { x: number; y: number } }>();
function tick(serverFrame: { position: { x: number; y: number } }, sequence: number) {
if (manager.processReceived(serverFrame, sequence)) {
// Accepted as in-order
const delta = manager.computeDelta();
if (delta.hasChanges) {
// …transmit delta only…
manager.markSent();
}
}
}
```
## API Reference
### `class GameStateManager<T extends BitPackerSchema> implements GameStateManagerInterface<T>`
Stores the latest state, the last-sent state, and a rolling 4-bit sequence. The class is generic so consumers can preserve type information through `getLatestState`.
#### `static readonly MAX_SEQUENCE = 15`
The wire-format cap on the rolling sequence. Sequence wraps from `15` back to `0`.
#### `updateState(state: unknown): void`
Replaces the current state. Does NOT advance the sequence — sequence advances only on `markSent`.
#### `getLatestState(): unknown | undefined`
Returns the current authoritative state, or `undefined` if no state has been pushed yet.
#### `markSent(): void`
Snapshots `currentState` into `lastSentState` and advances `sequence` modulo `MAX_SEQUENCE + 1`.
#### `processReceived(state: unknown, sequence: number): boolean`
Returns `true` if the incoming update is in-order (sequence ≥ `lastReceivedSequence`); `false` if it's a replay or out-of-order. Gates downstream consumers from acting on stale frames.
#### `computeDelta<T>(): StateDelta<T>`
Returns a `StateDelta<T>` with `hasChanges`, `delta` (partial of T), and `changedPaths` (string array). Compares `currentState` against `lastSentState` field-by-field.
## Implementation Notes
- **Sequence wrap is modulo 16.** The 4-bit constraint makes the sequence wrap from `15` to `0` after `markSent`. Receivers that compare sequence numbers must use modular comparison (e.g. `((received - lastReceived + 16) % 16) < 8`) rather than naive `received > lastReceived`.
- **`unknown`-typed internals.** `currentState` and `lastSentState` are typed `unknown` rather than `T` because the schema-driven pack/unpack erases the static type at the wire boundary. Generic callers preserve type-safety at their own call sites via the `T extends BitPackerSchema` parameter.
- **No deep clone on `markSent`.** The snapshot is a structural reference, not a deep clone. Consumers mutating `currentState` after `markSent` must do so via copy-on-write semantics or risk corrupting the prior delta baseline.
- **`processReceived` is a gate, not a writer.** It returns a boolean so the caller decides what to do with rejected frames (drop, log, request resync). The function does not auto-advance `lastReceivedSequence` on rejection.

View File

@@ -0,0 +1,37 @@
## Game Types
**Path:** `src/types.ts`
**Export:** All game-related type definitions and enums
### Core Types
| Type | Description |
|------|-------------|
| `Vector3` | `{ x, y, z }` 3D position |
| `Rotation` | `{ yaw, pitch }` euler rotation |
| `PlayerStats` | `{ health, shield, speed, isMoving, isSprinting }` |
| `PlayerState` | `{ position, rotation, stats, optional? }` |
| `PlayerInput` | `{ moveX, moveY, rotateYaw, rotatePitch, actions }` |
| `HistoryPoint<T>` | `{ value: T, timestamp: number }` for prediction history |
| `KalmanState` | Kalman filter position/velocity/covariance state |
### Enums
| Enum | Values |
|------|--------|
| `PredictionAlgorithm` | LINEAR, QUADRATIC, CUBIC, HERMITE, CATMULL_ROM, VELOCITY_VERLET, KALMAN, ADAPTIVE |
| `InterpolationMethod` | LINEAR, CUBIC, HERMITE, CATMULL_ROM, BEZIER, SPRING, ELASTIC, BOUNCE, SMOOTHSTEP |
### Options Interfaces
| Interface | Key Fields |
|-----------|-----------|
| `PredictionOptions` | `algorithm`, `historySize`, `maxPredictionTime`, `adaptiveThreshold`, `gravityFactor`, `velocityDamping` |
| `InterpolationOptions` | `method`, `tension`, `bias`, `springConstant`, `damping` |
| `ReconciliationOptions` | `inputBufferSize`, `stateBufferSize`, `jitterBufferSize`, `reconciliationThreshold`, `smoothingFactor`, `enableExtrapolation` |
### Defaults
- `DEFAULT_PREDICTION_OPTIONS` — historySize: 5, maxPredictionTime: 200ms
- `DEFAULT_INTERPOLATION_OPTIONS` — method: LINEAR, tension: 0.5, bias: 0.5
- `DEFAULT_RECONCILIATION_OPTIONS` — inputBufferSize: 60, stateBufferSize: 120, jitterBufferSize: 3

View File

@@ -0,0 +1,109 @@
# Game Schemas
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Zod schemas for the public configuration types of `@suaveplan/bitpacker-game`: the three sub-options bundles (`PredictionOptions`, `InterpolationOptions`, `ReconciliationOptions`), the top-level `GameBitPackerOptions`, the simple `GameStateSchema` envelope, and the `QuantizedVector` shape used by `quantizeVector`/`dequantizeVector`. Each schema is the runtime gatekeeper at the corresponding constructor or function boundary.
The schemas are strict and reject unknown keys so a typo'd flag (`enablePredictoin` for `enablePrediction`) fails at parse time rather than producing a game that silently runs without prediction enabled. Numeric ranges encode genuine invariants — buffer sizes are non-negative integers, history sizes are positive integers (a zero-history predictor is degenerate), and timing values are non-negative finite numbers.
## Features
- `predictionOptionsSchema` — `algorithm` from `PredictionAlgorithm` enum, positive integer `historySize`, non-negative timing values
- `interpolationOptionsSchema` — `method` from the union of nine published method tokens
- `reconciliationOptionsSchema` — buffer sizes, jitter window, threshold, smoothing, plus nested `predictionOptions` and `interpolationOptions`
- `gameStateSchemaSchema` — versioned `{ version, entities }` envelope, `entities` is an open record (`Record<string, unknown>`)
- `quantizedVectorSchema` — `{ x, y, z? }` for 2-D and 3-D quantization
- `gameBitPackerOptionsSchema` — top-level GameBitPacker options, composing the three sub-bundles
- `as unknown as z.ZodType<T>` casts where Zod's optional `T | undefined` collides with `exactOptionalPropertyTypes`
## Usage: Basic Example
```ts
import {
GameBitPacker,
PredictionAlgorithm,
gameBitPackerOptionsSchema,
} from "@suaveplan/bitpacker-game";
const opts = gameBitPackerOptionsSchema.parse({
enablePrediction: true,
predictionOptions: {
algorithm: PredictionAlgorithm.KALMAN,
historySize: 10,
},
});
const packer = new GameBitPacker(opts);
```
## Usage: Advanced Example
```ts
import {
GameStateManager,
quantizeVector,
quantizedVectorSchema,
gameStateSchemaSchema,
reconciliationOptionsSchema,
PredictionAlgorithm,
} from "@suaveplan/bitpacker-game";
// Validate every external state push:
const manager = new GameStateManager();
function pushState(raw: unknown): void {
manager.pushState(gameStateSchemaSchema.parse(raw));
}
// Validate vectors at the quantization boundary:
function compressedVector(raw: unknown, bits: number) {
const v = quantizedVectorSchema.parse(raw);
return quantizeVector(v, bits);
}
// Compose nested options:
const reconciliation = reconciliationOptionsSchema.parse({
inputBufferSize: 60,
stateBufferSize: 120,
enableExtrapolation: true,
predictionOptions: {
algorithm: PredictionAlgorithm.HERMITE,
historySize: 8,
},
});
```
## API Reference
### `predictionOptionsSchema: z.ZodType<PredictionOptions>`
Strict schema. `algorithm` (if present) must be a `PredictionAlgorithm` enum value. `historySize` must be a positive integer; `maxPredictionTime`, `adaptiveThreshold` must be non-negative numbers. `gravityFactor` and `velocityDamping` are unconstrained finite numbers.
### `interpolationOptionsSchema: z.ZodType<InterpolationOptions>`
Strict schema. `method` is restricted to the nine published method tokens (`linear`, `cubic`, `elastic`, `spring`, `bounce`, `smoothstep`, `hermite`, `catmull-rom`, `bezier`). Other fields are unconstrained finite numbers.
### `reconciliationOptionsSchema: z.ZodType<ReconciliationOptions>`
Strict schema with nested `predictionOptions` and `interpolationOptions`. Buffer/window sizes are non-negative integers; thresholds and timings are non-negative numbers.
### `gameStateSchemaSchema: z.ZodType<GameStateSchema>`
Validates `{ version, entities }`. `version` is a non-negative integer; `entities` is an open record so per-game shapes can be embedded. Validating each entity is the consumer's responsibility.
### `quantizedVectorSchema: z.ZodType<QuantizedVector>`
Validates `{ x, y, z? }`. `z` is optional so the same schema accepts both 2-D and 3-D vectors.
### `gameBitPackerOptionsSchema: z.ZodType<GameBitPackerOptions>`
Strict top-level options schema, composing the three sub-bundles. `networkSimulationOptions` is left as an open record (`Record<string, unknown>`) because the canonical schema lives in `@suaveplan/bitpacker-network` and importing it here would tighten the coupling unnecessarily — consumers who want to validate it can run the network package's schema themselves.
## Implementation Notes
- **Open-record `entities` and `networkSimulationOptions`.** Both are intentionally `Record<string, unknown>` because per-entity / per-network-config shapes are out of this package's scope. Validating at finer granularity would require this package to know about every consumer's data model, which it does not.
- **`PredictionAlgorithm` is a string enum.** Zod's `z.nativeEnum` works on it directly. The enum's serialized values (`"linear"`, `"kalman"`, …) are the same as the runtime values, so the schema accepts both forms.
- **`as unknown as z.ZodType<T>` cast.** Same EOPT mismatch as elsewhere in this change. Runtime semantics are identical.
- **Strict mode everywhere.** A loose schema would silently drop typo'd flags, producing a game-bitpacker configured without the consumer's intended optimizations.