Releases: spawndotfamily/spawn-sdk
Releases · spawndotfamily/spawn-sdk
Release list
SDK 0.12.0
Added
- Public server-side Listing-token payment verification and recovery through
createSpawnPaymentClient().lookup(), with a durable once-only item issuance example. Browser receipts alone never authorize server inventory. - Regression coverage for fast local iframe startup and overlapping, cancelled or timed-out approval requests.
Changed
- Local game bridges install before the iframe can announce readiness. Queued test-driver approvals resume when an existing approval closes, and cancelled token approvals release their dialog and shared approval lock.
- Delayed match completions keep their approval lock until recorded. Interrupted local game asset requests close their file handles when a page reloads or disconnects.
- README and creator instructions distinguish the real local approval host from the legacy fixed-TEST simulator, and document authoritative purchase verification, cancellation and unknown-outcome recovery.
Upgrade notes
- Use 0.12.0 or newer for local approval testing and multiplayer purchases. Update and rebuild the game SDK, then restart the local test host. Server payment verification requires the matching hosted platform endpoint; keep item issuance blocked if verification is unavailable. See
docs/token-payments.md.
SDK 0.11.0
Added
- Local Spawn approval host:
npx spawn-test-hostandstartSpawnTestHostship the actual platform approval components, ledger and token API handlers in a loopback-only process. Ordinary creators can test without a Spawn account, hosted preview, real funds or private infrastructure. Use 1–1,000 independent synthetic players, with 2–6 seats per table and larger fleets across tables. - Ordinary
createSpawnGameClientbuilds (--game-dir) and multiplayer servers (--game-url) both use their actual isolated iframe/MessageChannel transport. Signed local multiplayer admission, browser-driven table/match/trade/token approvals, durable local SQLite state, interrupted-response injection, clock advancement and status recovery. Approval is never automatic; browser automation clicks the same Spawn confirmation controls. - Public deployment/configuration guide and runnable browser examples in
docs/local-approval-testing.md. Packaged types, artifact integrity checks, 100-player conservation tests and browser approval checks run before publishing. - Multiplayer
requestTokenPayment({ amount, item, requestId })now supports optional exact Listing-token payments through the same Spawn-owned confirmation UI. The game does not choose the contract. Receipts are validated; concurrent duplicates share an outstanding request and interrupted outcomes require reconciliation.
Changed
- Table loopback double now rolls back rejected mutations and enforces capacity, expiry, recovery and closed-table behavior. Payout-double status remains readable after suspension, while new payouts are blocked. These fast doubles remain separate from the new production-source test host.
- Removed an accidentally tracked machine-specific
node_modulessymlink. The package carries reproducible runtime artifacts and licensed local fonts, never an installed dependency directory. - Paired platform fixes recheck payout suspension/removal inside the balance transaction and scope transfer IDs to the game. Insufficient table funds now return a typed conflict instead of an ambiguous service failure. The preview download allowlist now includes the current SDK releases.
Upgrade notes
- Additive SDK release. Build the SDK into your game, then follow
docs/local-approval-testing.md; do not add fake identities or approval shortcuts to game code. Node 22.13+ is required; Node 24 is recommended. - Local
LOCALbalances and credentials are isolated simulations. They cannot deposit, withdraw or spend hosted tokens. Keep the generated local configuration outside browser bundles and source control. - Passing local tests checks game logic, bridge/approval behavior and ledger invariants. Still verify the uploaded build, hosted account/credential setup, network behavior and two-player flow in a private preview. No local harness guarantees all production behavior.
SDK 0.10.0
Added
- Server-credential payouts — the missing primitive for game→player economies.
createSpawnPayoutClient(from@spawndotfamily/sdk/server) pays a registered member from the game's own token pool: reward loops, deposit/redemption vaults and any "creator pays a verified member" flow now have a supported API instead of a manual dashboard action. The game's dedicated match server credential authorizes it — a browser can never call it.operationIdis the single idempotency key: an identical retry returns the same receipt and moves money exactly once, andoperation(operationId)reconciles an unknown outcome before you ever pay again. WithdepositIdthe payout is capped at that paid deposit, cumulative across payouts; withoutlaunchIdit pays any registered member of the game (so redemption works while the player is offline), while supplyinglaunchIdapplies the strict active-launch chain. The recipient is always resolved server-side fromplayerId; guests are refused. testing/loopback-payout-service.mjs— a headless double that wires the REAL payout client to a fake platform, so an agent can prove the loop before launch: simulate a paid deposit, issue the claim, redeem it, and assert the member is credited exactly what the pool is debited; replays credit once; overdraft, non-member and over-cap payouts are refused; conservation holds.testing/table-fleet.mjs— run a fleet of simulated players across many tables headlessly (--players 100): seating, approvals, hands, cash-outs, a disconnect/reconnect, per-table and aggregate conservation, and a non-zero exit on any imbalance. 1 000 players complete in well under a second.- Opt-in per-player test balances in the loopback table service (
{ balances: { [playerId]: '1000' } }): an approval a player cannot fund is refused at the click withINSUFFICIENT_BALANCE— where the real overlay refuses it — and tracked wallets debit on approval and credit on cash-out exactly once. Omit the option and behaviour is unchanged. docs/payouts.md— creator-facing guide: idempotency and reconciliation, the two recipient modes, caps and error handling, and testing the loop locally.
Changed
docs/server-setup.mddescribes thematch.keycredential as also covering payouts;docs/token-balances.mdcross-references that a balance read never authorizes a payout;docs/creator-checklist.mdincludes the payout step for reward/redemption flows.docs/table-bankroll.md's coverage note now reflects the fleet driver and opt-in balances instead of claiming N-player concurrency is uncovered.
Upgrade notes
- Additive: no existing API, wire format or behaviour changed. Use the payout client only on an authoritative server and keep the credential out of browser bundles.
SDK 0.9.7
Added
- Simulating approvals for N players is now documented as a first-class path, not a footnote.
service.confirmBuyIn(playerId)simulates one player's Approve click, so call it per player and a whole multiplayer money flow runs headlessly with no real accounts and no second person. Newexamples/table-multiplayer-sim.mjsis a worked three-player flow: unequal buy-ins, a short all-in, a main pot plus side pot, a cash-out, and the money invariant asserted after every step. docs/table-bankroll.mdstates the rule explicitly: the token comes from the Listing in the game workspace, never from the SDK or game code — do not hardcode a token or contract address. Pass the listing token's symbol/decimals to the harness only so local test maths match it.
Changed
- The coverage note no longer says the approval overlay "cannot be simulated", which was misleading: the approval decision is simulatable for any number of players; what cannot be stood in for is Spawn's own overlay UI and a real member account's server-side authorization. The
confirmBuyInreference entry and the coverage list now say exactly that.
Upgrade notes
- No action required: documentation and an example. No runtime API, wire format or server behaviour changed, and the token still comes from the project's Listing exactly as before.
SDK 0.9.6
Fixed
- The documented
--jsonshape was wrong indocs/testing.md: it listed{ total, passed, failed, results }and omittedtitle, whichtesting/README.mdstates correctly. An agent that asserts on a documented shape trips over a missing field, so both files now carry the same payload.
Added
docs/testing.mdstates the full payload inline ({ title, total, passed, failed, results }), so a reader does not have to open another file to learn the shape it prints.
Changed
- The
--jsonshape is written identically indocs/testing.mdandtesting/README.md; both are checked against the runner's actual output.
Upgrade notes
- No action required: documentation only. No runtime API, wire format or server behaviour changed.
SDK 0.9.5
Another creator-side report, and again all docs — plus one thing CI should have caught and now does.
Fixed
- Documented commands that only work inside the SDK repo.
docs/testing.mdtold creators to runnpm run test:tables(a script their project does not have) and said "8 scenarios";testing/README.mdanddocs/table-bankroll.md— including the pre-publish checklist — saidnode testing/table-scenarios.mjs, which does not exist from a consumer project root. Every runnable snippet is now a consumer path (npx spawn-test, with thenode_modules/...form as the fallback), and the count is 10 in both places. docs/testing.mdhad no harness section at all — the highest-value pre-launch tool for a table game was one buried, wrong sentence. It now teaches the harness where testing is explained.
Added
- The harness declarations are type-checked by CI:
npm run checkalso compiles a consumer-style usage file againsttesting/*.d.mts, so the types are verified by the build instead of by a maintainer's report. (Verified the check fails on a wrong type, so it is not passing vacuously.) docs/table-bankroll.mdcarries the economy rule where economies get designed: a fee cannot come out of a pot — committed funds belong to the contributors, so charge fees outside the table.
Changed
- The release workflow builds before
check, because the harness declarations reference the built server types;npm teststill runs first.
Upgrade notes
- No action required: documentation and a type-check only. No runtime API, wire format or server behaviour changed.
SDK 0.9.4
Everything here came from a creator-side integration report, so it is the surface that decides
whether a non-technical creator's agent can use the harness unassisted.
Added
- TypeScript declarations ship with the harness (
testing/loopback-table-service.d.mts,testing/scenario-runner.d.mts), so editors and AI agents get real signatures instead of reading.mjssource. spawn-testbin — run the shipped scenarios from your own project:npx spawn-test, ornpx spawn-test --jsonfor a machine-readable{ total, passed, failed, results }summary an agent can assert on.- Shared scenario runner (
testing/scenario-runner.mjs):runScenarios,checkConservation,executeScenario,summarize,wantsJson. Your own outcome rules now run through the same runner and produce identical output. examples/table-scenarios-custom.mjs— a worked example of custom outcome rules, including the two pot-conservation refusals.- A tenth scenario covering an injected clock.
- Documented: the consumer run command, amounts and the fake asset, the clock contract, every harness member, and the rake constraint.
Changed
- The harness clock is read live on every call, so
now: () => myGameClockfollows your test clock instead of freezing at construction.advance(ms)adds a synthetic offset on top of whatevernowreports rather than owning time. conservation()returnsdeltaand adetailthat names the imbalance, so a failed invariant prints the delta instead of a bare inequality.
Fixed
- Scenario runs exit non-zero on failure through the shared runner, and
--jsonreports the same run.
Upgrade notes
- No action required: no runtime API, wire format or server behaviour changed. If you injected a clock you no longer need to move it in lockstep with
advance(). If you parsedconservation().detail, it now states the imbalance. A rake cannot be taken from a pot — that is a contract property, not a harness limitation; seetesting/README.md.
SDK 0.9.3
Fixed
- The testing harness is now reachable through the package export map.
import { createLoopbackTableService } from '@spawndotfamily/sdk/testing/loopback-table-service.mjs'— the import documented intesting/README.md— threwERR_PACKAGE_PATH_NOT_EXPORTED, becausetesting/was infilesbut not inexports..mjsconsumers also could notrequire.resolveany subpath and had to build a relative path by hand.exportsnow maps./testing/*and./package.json.
Added
service.stubClient({ method: fn })(and the exportedstubClient(client, overrides)) wraps one method of the frozen SDK table client. Tests no longer need a hand-written delegatingProxyto make a single call fail.- A ninth harness scenario covering the stub wrapper, and a resolution test that fails if a documented package subpath stops resolving.
Changed
testing/README.mdstates the harness's package subpath and the stub wrapper, so the documented import and the supported way to stub a call are both explicit.
Upgrade notes
- No action required: no runtime API, wire format or server behaviour changed. If you worked around the missing export with a relative
require.resolve('.../dist/server.js')path, switch to the package subpath above.
SDK 0.9.2
Added
- N-player table scenarios in
testing/table-scenarios.mjs: a six-seat table conserving exactly across twenty hands, and seat churn (one player leaves mid-session, the rest keep playing). Eight scenarios total, all asserting the table conservation invariant. window.__SPAWN_DEV_STATE__.data— a deliberately small agent-readable summary of local player state:{ guest, saves: [{ key, version }], scores }.spawn-publish statusnow reminds you to run automated settlement tests before publishing a release that moves tokens.
Changed
docs/testing.mddocuments the compact state snapshot so an agent can verify outcomes without reading the documentation set (kept terse on purpose: agent context is a real cost).
Upgrade notes
- No action required: no runtime API, wire format or server behaviour changed. The new state field is additive and only present in
spawn-dev.
SDK 0.9.1
Added
testing/automated money-flow harness for table games: a loopback table service that speaks the platform's table contract (testing/loopback-table-service.mjs) plus six scripted scenarios (testing/table-scenarios.mjs) covering unequal all-ins and side pots, cash-out, disconnect grace, reconnect, lost-response retry and abandoned-hand refund. Run withnpm run test:tables.createLoopbackTableServicetest affordances:confirmBuyIn(playerId)simulates the Spawn overlay approval,state(playerId)exposes agent-readable quotes/seats/stacks/totals,loseNextResponse(action)forces the uncertain-outcome path,advance(ms)moves the clock onto grace/deadline/lease boundaries, andconservation()returns a verdict.testing/README.mdand a "Test before launch" section indocs/table-bankroll.md.
Changed
- The published package now includes
testing/.
Upgrade notes
- No action required: no runtime API, wire format or server behaviour changed. To use the new harness, run
npm run test:tables(ornode testing/table-scenarios.mjs) in your game before publishing a table game.