@tpgames/sdk
v0.4.1
Published
Public game authoring SDK for TPG.
Readme
@tpgames/sdk
Public game authoring SDK for TPG.
Most browser games that run inside TPG iframes should install
@tpgames/game-kit instead. The game kit re-exports this SDK and owns the default
iframe postMessage/runtime bootstrap, so game authors do not need to wire
@tpgames/runtime-game or bridge packages directly.
Install
For normal iframe-hosted browser games:
bun add @tpgames/game-kitFor reusable non-iframe game logic packages or advanced bridge integrations:
bun add @tpgames/sdk @tpgames/core-typesExample
import { defineSimpleGame } from "@tpgames/sdk";
export default defineSimpleGame<{ phase: "lobby" | "prompt" }>({
async surfacesReady(api) {
if (!api.context().isAuthority) {
return;
}
const controllers = api.controllerIds({ connectedOnly: true });
const snapshot = api.getSharedStateSnapshot();
const result = await api.setSharedState(
{ phase: controllers.length > 0 ? "prompt" : "lobby" },
{ expectedRevision: snapshot.revision }
);
if (result.status === "rejected") {
console.warn(result.message);
}
}
});Authoring helpers also include:
createDeadline(startedAt, durationMs)for round timers and vote windowssetPhase(state, nextPhase, updates)for phase transitionssyncPlayerValues(current, participantIds, createDefault)for player-scoped collectionsFixedStepSimulationfor host-authoritative ticks with explicit revisions and visible catch-up backlogClockOffsetEstimatorfor low-RTT timer/input timestamp alignmentSequencedInputBufferfor bounded reordering, contiguous consumption, and safe acknowledgementsinterpolateSnapshotandreconcilePredictedStatefor remote rendering and optional local input replayDeterministicFaultLinkfor seeded latency, jitter, loss, reordering, disconnect, and reconnect tests
Casual real-time pattern
Keep simulation state canonical on the authority. Send controller movement or
aim on a latest-value channel, assign each input a participant-local
sequence, and let the authority consume bounded contiguous inputs on fixed
ticks. Publish tick, revision, and acknowledgement values with snapshots.
import {
FixedStepSimulation,
SequencedInputBuffer
} from "@tpgames/game-kit";
const inputs = new SequencedInputBuffer<MoveInput>(64);
const authority = new FixedStepSimulation({
initialState,
tickRateHz: 20,
maxStepsPerAdvance: 8,
step(state, { tick, revision, deltaMs }) {
return simulate(state, inputs.drainContiguous(), {
tick,
revision,
deltaMs
});
}
});Render remote entities slightly behind server time and interpolate between two snapshots. Prediction is optional: apply local inputs immediately for visual responsiveness, then replace the base with each authoritative snapshot and replay only inputs newer than its acknowledgement. Smooth small corrections; snap large or safety-critical corrections. Never let predicted state decide scores, hits, authority, or persistence.
The reference envelope is a 20 Hz host simulation, at most eight catch-up steps per callback, 64 buffered inputs per participant, and small rooms on the published reliable/latest-value transport budget. Tank Arena exercises 80 ms one-way controller latency plus deterministic 80 ± 25 ms jitter/reordering tests. Packet loss, rollback fighting games, competitive FPS reconciliation, and audio-grade rhythm synchronization are not supported guarantees.
Each mounted surface executes its own definition. Use lifecycle hooks for the
shell-owned game stage and repeatable surfacesLoading/surfacesReady hooks
for iframe readiness. Shared-state setters reject non-authority surfaces.
Player-state setters accept only the current participant's state unless the
surface is authoritative. On request-capable bridges, setters resolve to
applied or rejected; compatibility bridges resolve to accepted, and the
later subscription echo remains canonical. Snapshot getters expose revisions
for optimistic concurrency, so initialization hooks should pass
expectedRevision and remain idempotent.
See the repo docs for the full runtime model and publishing flow.
- Iframe authoring entrypoint:
packages/game-kit - SDK runtime guide:
docs/game-sdk.md - End-to-end author guide:
docs/game-authoring-guide.md
