Commits
-
Gate joins on content digests and load Scraplandia's default mapOpenVibers · 4 Oct 2026
6a1f3a3 -
Merge games-content@2 pack definitions into content at server boot (#3)OpenVibers · 4 Oct 2026
545f6c1 -
Run Games' vitest files through test/run.js so ov test can shard themOpenVibers · 3 Oct 2026
1cae50b -
Rapier replaces Havok behind the unchanged physics seam (ADR-0007 M1 steps 4-7), and Games serves its own legal pages (plan T11 decision 6).OpenVibers · 29 Sept 2026
9201a6f -
Physics conformance suite and an in-memory mock world (ADR-0007 M1 step 1): packages/physics/src/conformance.test.ts runs every seam case against MockPhysicsWorld and the Havok adapter (bodies, sweeps, joints, sleep and settle thresholds read through the adapter under test, gravity measured, per-engine landing heights pinned separately), with a guard that fails on a skip entry naming no case. The mock (@openvibe/physics/mock) now backs the gameplay movement tests in place of their ad-hoc stub, which exposed two mock bugs: a swept capsule's height is its total height including caps (it was 0.8 m too tall), and a capsule sweep meets a plane from either side (walls and ceilings were passed through), with the start-overlap guard both engines have. The two unrun smoke scripts are gone (the suite covers them). sliceTest waits for the recalled snapshot and meta.secured inside one budget (a race). Reviewed independently twice; pnpm typecheck, lint and test green (1036 passed, 9 skipped).OpenVibers · 29 Sept 2026
c24b7b1 -
M1 identity: the WebSocket authenticates at the upgrade, the editor key is gone, and the contracts pin is current (ADR-0007 decisions 8 and 12).OpenVibers · 29 Sept 2026
3ea36b3 -
M1 persistence: Games runs on PostgreSQL 18 + Valkey through openvibe-sdk (ADR-0007 decision 5). SQLite is gone (no data is restored; a new schema from scratch, no schema-version history). - packages/persistence: openPgStore on an openvibe-sdk/db handle, every repository async, batch upserts as multi-row INSERT ... ON CONFLICT in chunks of 500; migrations/0001_initial.sql: places, world_meta, world_entities and world_constraints keyed by place, characters (account_key is the subject, or guest: + sha256 of a guest token: a raw guest token is never stored), mods, grants, placements, audit, media mirrors, account data events, identity adoptions, and the SDK's event_outbox and token_revocations. transaction() hands the tx to its callback; the outbox enqueue takes it and refuses to run outside one. - The write-behind flusher (apps/server/src/game/flusher.ts): the tick builds a copy-on-write snapshot and never awaits I/O; one transaction at a time writes meta, NPCs (now dirty-tracked), entities, constraints, characters and their outbox events; a checkpoint while one is in flight is coalesced (flags stay set); a failed one restores its dirtiness. The shutdown checkpoint is never coalesced (queued behind one in flight), drain has a real deadline, a failed disconnect save retries in place with backoff, and a returning player's sign-in waits for queued saves before reading the character. - No database access on the tick: markets and env preload at boot, mod placements come from an in-memory mirror written through a serialized queue (rolled back if the write fails), an offline owner's friends load asynchronously (denied until loaded), hello resolves asynchronously with an in-flight guard. - Platform adapters on the SDK handle (createPgOutbox, createPgRevocationStore, account data), readiness via db.ready(), per-actor limits on Valkey when VALKEY_URL is set; development without DATABASE_URL runs on PGlite; migrations run as the owner on DATABASE_DIRECT_URL. Unhandled rejections closed in /api/v1/platform, readiness, the media mirror pass and account events; the Network revision advances only after its writes; a failed budget disable keeps enforcing. - openvibe-sdk v0.22.0, openvibe-shared v1.30.1; better-sqlite3 removed. Built by DeepSeek from Claude's spec; reviewed independently twice (FIX, FIX) and by Claude (the shutdown coalescing loss, drain deadline, disconnect retries and sign-in ordering fixed by Claude); every finding fixed with tests. pnpm typecheck, lint, test 872/872, slice test OK on PGlite, server bundle builds. Not deployed yet: production needs its database (roles/data/add-service.sh games) and Host's Games strategy moved off better-sqlite3 first.OpenVibers · 29 Sept 2026
540f672 -
ADR-0007: rewrite the moddable base (the base is the product, Scraplandia its first pack; Rapier; places and instances; PostgreSQL + Valkey with a write-behind flusher; declarative, QuickJS and Worker mods; phones a real target; OpenVibe.Play for achievements, stats, inventories and lobbies; milestones M1-M6). Nothing on openvibe.games is kept or restored, so M1 starts by deleting the legacy surface, with no shims and no redirects: - the Live legacy import (liveLegacyImport, importLiveLegacy, legacy_live_rows, docs/legacy-import.md); - identity adoption of ovn: keys (migrateIdentity, identityMigration, the ovn: prefix; sign-in keys on the token's subject and a token without one is refused) and IP-bound guest recovery (guest_ips, GUEST_IP_BINDING); the once-only ledger that account merge and deletion still use is renamed identity_adoptions; - the /api/texture alias and the /game and /canvas redirects; - map v1 (migrateV1ToV2, MAIN_TERRAIN_MIGRATED_ID, migrateLegacyMix, the client's legacyLayer, TerrainPatchData.mix): a v1 document is invalid, and the editor e2e checks that it opens empty; - the committed dist-types build output (366 files, now ignored) and the stale gameplay status doc. The guest cookie keys hq_token/hq_reload_ts became openvibe.token/openvibe.reload_ts. ADR-0006 notes that its identity adoption is superseded. The SQLite schema version went 13 -> 11: this build refuses the old world.db on purpose and is not deployed; PostgreSQL replaces the store next (M1), on a fresh database. Reviewed independently; its findings are fixed here (e2e v1 section, ADR notes) or in Live (links to /game and /canvas). pnpm typecheck, lint, test 843/843.OpenVibers · 29 Sept 2026
cfaf83c -
README and STATUS.json are current (roadmap WS-U task 3): the README gains Purpose (OpenVibe.Games: Scraplandia on openvibe.games), Owns, Does not own, Depends on, Capabilities (the four games.* capabilities in the manifest, and every grant the games principal uses, now including events.subscription.manage, network.modules.write and mods.grant.manage), Tests and Security (SECURITY.md, server authority, limits, identity, mods, secrets by name) sections; Production names the env file, database and rollback with its schema-version blocker. Stale facts corrected: Games pins openvibe-contracts v0.71.0 (not v0.8.0) and serves the OpenVibe Frame from its own pinned copy, not openvibe.network. STATUS.json is new, in the shape of Search's, updated 2026-09-28.OpenVibers · 28 Sept 2026
eb2d008 -
deploy/scripts/deploy.sh: deploys run through ovhost deploy games (OpenVibe.Host strategy pnpm-build; roadmap WS-N task 11). ovhost does the production procedure (pull, pnpm install --frozen-lockfile, pnpm build, restart openvibe-games) with git as the checkout owner instead of sudo git, restores the tracked dist-types/ a previous build rewrote before the pull, checks every workspace package's dependencies and that better-sqlite3 loads under the host's Node before the restart, polls /api/ready, and on failure restores, reinstalls and rebuilds (the build writes the served client) and restarts again. Players online are reported and reconnect (drain policy report); --wait-idle holds the restart until nobody plays. The wrapper passes --wait-idle, --restart, --force, --rollback and DRY_RUN=1 (ovhost plan games); it asks ovhost capabilities games first and falls back to deploy/scripts/deploy-legacy.sh, the procedure as it was run by hand (sudo git -c safe.directory pull, pnpm install --frozen-lockfile, pnpm build, sudo systemctl restart openvibe-games, then a readiness wait and the best-effort release notification), when ovhost is missing, too old or the host inventory does not deploy games with pnpm-build (OVHOST_LEGACY=1 forces it). apps/server/scripts/deployWrapper.test.ts. README.OpenVibers · 27 Sept 2026
e2d9a5d -
Unknown paths answer 404 instead of the landing page: a path that was neither a route nor a file of the client build used to get the portal (openvibe.games) or the game (play.openvibe.games) with a 200, a soft 404 that search engines index and monitors read as up. It now gets a real 404 with Cache-Control: no-store. Browsers get a small self-contained HTML page (inline CSS, no scripts) that shows the requested path escaped and links to the host's entry points (apex: /, /play, /editor; play host: /, /editor and the portal). Anything under /api, and a client that asks for JSON, gets {"error":"not_found"}, the shape /auth/* already answers. A missing asset (any extension but .html, e.g. /favicon.ico, /robots.txt, a stale /assets/*.js) gets plain text. HEAD and POST get the same status. Real routes keep their status: / (portal on the apex, the game on the play host), /play (301 to / on the play host), /editor, the build's files including the hashed /assets, /map.json, /map-assets/<id>, the API (/api/characters, /api/map, /api/map-assets, /api/texture, /api/ready, /api/v1/platform, /api/v1/mods), /auth/*, /healthz and /metrics; /play/ and /editor/ now redirect to their canonical URL, and /game and /canvas (the URLs from when the game lived on OpenVibe.Live, which still links and 301s to them) redirect to /play and / (both to / on the play host) instead of becoming 404s. The client has no router of its own, so no page prefix accepts sub-paths. apps/server/src/net/httpServer.test.ts drives the real HTTP layer over a stand-in build on both hostsOpenVibers · 23 Sept 2026
84ee13e -
Live legacy import (Wave 12 migration gate): every HoboQuest and canvas table in Live has a recorded decision, and scripts/importLiveLegacy.ts reconciles each one (read = imported + held + excluded). Per-player HoboQuest rows (players, inventory, bank, achievements, recipes, fish, battle stats, structures, farm plots) are archived verbatim under the owner's Network subject in world.db legacy_live_rows (schema 13), because Scraplandia has no equivalent for them. Nothing is mapped into characters. Excluded: the world seed, expired daily quests, empty buff/dungeon/leaderboard tables, the pixel canvas (not a Games feature, and its rows carry IP addresses), and 47 placeholder game_players rows that Live's profile lookup still inserts. Subjects come from the Network identity service (system live) as the games principal, with Live's linked_accounts as a cross-check. Unresolved or conflicting owners are held and listed, never guessed. The importer is a dry run by default and idempotent (keyed by source primary key, never overwrites). --apply needs --backup, which it writes and verifies with integrity_check before one transaction. It refuses Live's production file. The dry run on production copies: 2224 read = 616 imported + 200 held + 1408 excluded. Not applied. docs/legacy-import.md has the inventory, the output and the host commandsOpenVibers · 23 Sept 2026
474df50 -
Docs: STATUS.json and README match production (2026-09-23)OpenVibers · 23 Sept 2026
8aef490 -
GET /api/ready: 200 only while world.db answers and the simulation ticksOpenVibers · 23 Sept 2026
f11e21c -
Docs: ADR-0006 (canonical subjects, platform boundary), README platform integration (env, grants, mods API), architecture and roadmap notes, platform env in the unit fileOpenVibers · 23 Sept 2026
208f41b -
Initial OpenVibe releaseOpenVibers · 17 Aug 2026
c8c9c25