mirror of
https://github.com/Such-Software/wownerogue.git
synced 2026-10-17 22:31:26 +02:00
docs: record renderer Tavern and production state
This commit is contained in:
@@ -23,7 +23,10 @@ third-party deployment.
|
||||
- **Persistent chat** with 30-day history
|
||||
- **Transaction history** - view payment and payout records
|
||||
- **Multiple game modes**: Free play, per-game payments, or credit bundles
|
||||
- **Social Tavern** with chat, live solo spectating, and in-place race queues
|
||||
- **Anonymous social Tavern** (no account required) with chat, live solo spectating, and in-place
|
||||
race queues
|
||||
- **Shared render kit** with Tiled, ASCII, Iso, and locally served 3D techniques across the dungeon
|
||||
and Tavern
|
||||
- **Real-time multiplayer races**: free, prestige-credit, or crypto winner-take-pot races every block
|
||||
- Configurable difficulty with house edge tuning
|
||||
- Automatic wallet RPC integration for payments and payouts
|
||||
@@ -137,7 +140,7 @@ Click **"📜 History"** to view your payment and payout records. Shows:
|
||||
|
||||
### Session Persistence
|
||||
|
||||
Sessions use an anonymous token stored in localStorage:
|
||||
Sessions, including anonymous Tavern entry, use an anonymous token stored in localStorage:
|
||||
- ✅ Persists across refreshes, browser closes, server restarts
|
||||
- ⚠️ Lost when clearing cookies/localStorage, using incognito mode, or switching browsers/devices
|
||||
|
||||
@@ -264,6 +267,9 @@ See [docs/DEPLOY.md](docs/DEPLOY.md) for detailed production deployment instruct
|
||||
- Database permissions and security hardening
|
||||
- Multi-instance deployment (running Wownero and Monero on the same server)
|
||||
|
||||
The dated [`play.wowne.ro` production record](docs/PRODUCTION_STATE_2026-07-25.md) distinguishes the
|
||||
live schema-neutral renderer/Tavern overlay from the still-gated full mainline migration cutover.
|
||||
|
||||
---
|
||||
|
||||
## Operations
|
||||
|
||||
+26
-16
@@ -2,6 +2,10 @@
|
||||
|
||||
This guide covers deploying Wownerogue to a production environment.
|
||||
|
||||
For evidence about the release currently serving `play.wowne.ro`, see the dated
|
||||
[production-state record](PRODUCTION_STATE_2026-07-25.md). That record is not a substitute for this
|
||||
runbook or authorization for another activation.
|
||||
|
||||
## Operated profiles versus independent deployments
|
||||
|
||||
Such Software (`apps@such.software`) operates only `play.wowne.ro` (Wownero mainnet
|
||||
@@ -44,6 +48,8 @@ claims, and support; Such Software neither endorses nor accepts responsibility f
|
||||
- [ ] Set up database backups (see [LOGS_AND_BACKUP.md](./LOGS_AND_BACKUP.md))
|
||||
- [ ] Configure log rotation
|
||||
- [ ] Run database migrations
|
||||
- [ ] If 3D is offered, provision the gitignored runtime GLBs and verify library/model requests
|
||||
stay same-origin
|
||||
|
||||
---
|
||||
|
||||
@@ -74,10 +80,12 @@ root-owned mode-0700 candidate inbox and compares its remote SHA-256 with the in
|
||||
recorded literal digest. Follow the fleet Wowngeon runbook; the role is a one-shot custody boundary,
|
||||
not deployment.
|
||||
|
||||
The current fleet repository deliberately has no executable extraction/activation helper yet.
|
||||
Until that helper exists, the safe host boundary is blob-only staging: do not manually
|
||||
extract beneath `releases/`, install dependencies there, change `current`, restart an application,
|
||||
or run migrations merely because the blob has arrived.
|
||||
The executable extraction/activation boundary lives only in the separately reviewed fleet
|
||||
repository as the default-closed `wowngeon_release_activate` role. This application checkout cannot
|
||||
attest which fleet revision is installed or authorize its execution. Follow the hash-pinned fleet
|
||||
runbook and literal receipt contract; do not manually extract beneath `releases/`, install
|
||||
dependencies there, change `current`, restart an application, or run migrations merely because a
|
||||
blob has arrived.
|
||||
|
||||
---
|
||||
|
||||
@@ -95,12 +103,13 @@ node --version
|
||||
npm --version
|
||||
```
|
||||
|
||||
The eventual reviewed extraction/activation helper installs exactly the locked production graph in its private,
|
||||
writable staging directory with `npm ci --omit=dev --ignore-scripts --no-audit --no-fund`, verifies
|
||||
it with `npm ls --omit=dev`, and seals the finished release root-owned and non-writable before it can
|
||||
be selected. Never make a release tree writable by `wownerogue`. Online advisory lookup is a
|
||||
separate explicitly authorized source-review operation; never run `npm audit fix` in staging or on
|
||||
a live release.
|
||||
The reviewed fleet extraction/activation role installs exactly the locked production graph in its
|
||||
private, writable staging directory with
|
||||
`npm ci --omit=dev --ignore-scripts --no-audit --no-fund`, verifies it with
|
||||
`npm ls --omit=dev`, and seals the finished release root-owned and non-writable before it can be
|
||||
selected. Never make a release tree writable by `wownerogue`. Online advisory lookup is a separate
|
||||
explicitly authorized source-review operation; never run `npm audit fix` in staging or on a live
|
||||
release.
|
||||
|
||||
---
|
||||
|
||||
@@ -114,7 +123,7 @@ sudo chmod 0640 /etc/wownerogue/app.env
|
||||
```
|
||||
|
||||
Do not use recursive ownership changes on `/var/www/wownerogue`; they can hand the service process
|
||||
write access to immutable code or the rollback selector. The reviewed extraction/activation helper must verify
|
||||
write access to immutable code or the rollback selector. The reviewed fleet role must verify
|
||||
every individual release's ownership and modes before activation.
|
||||
|
||||
**Database ownership** - the application currently runs its own migrations at startup, so its
|
||||
@@ -228,11 +237,12 @@ location /socket.io/ {
|
||||
## Updating the Deployment
|
||||
|
||||
Run the full suite from the clean source commit, then build and verify the runtime artifact using
|
||||
[RELEASE_ARTIFACT.md](./RELEASE_ARTIFACT.md). Today, use the fleet blob-staging playbook and stop at
|
||||
the independently hash-verified root-owned candidate blob because the reviewed extraction/activation
|
||||
helper does not yet exist. When that helper implements the documented contract, it—not an application service identity or a
|
||||
manual shell session—will build a new immutable `/var/www/<instance>/releases/<release-id>`, install
|
||||
the locked graph, run the clone/preflight gates, seal ownership, and atomically select `current`.
|
||||
[RELEASE_ARTIFACT.md](./RELEASE_ARTIFACT.md). Use the fleet blob-staging playbook, then proceed only
|
||||
through the reviewed, hash-pinned `wowngeon_release_activate` role after its clone, wallet,
|
||||
accounting, drain, predecessor, and receipt gates pass. That role—not an application service
|
||||
identity or a manual shell session—builds a new immutable
|
||||
`/var/www/<instance>/releases/<release-id>`, installs the locked graph, verifies the clone/preflight
|
||||
evidence, seals ownership, and atomically selects `current`.
|
||||
Never run `git pull`, `npm install`, or `npm audit fix` inside the active release. Keep the previous
|
||||
release and database backup until the new version has passed public health, WebSocket,
|
||||
payment-intake, and (stagenet only) payout smoke tests.
|
||||
|
||||
@@ -107,8 +107,9 @@ Neither wallet role reads, exports, or proves a mnemonic. A passing keyfile/pass
|
||||
independent seed custody or a full off-host recovery drill. Record those separately as unproven
|
||||
until a human-controlled custody inventory and isolated off-host restore establish them. This gap
|
||||
does not authorize weakening a proof, printing a secret, or applying either role to the funded
|
||||
Wownero mainnet wallet. Wownero wallet promotion and the corresponding application activation
|
||||
remain blocked pending that separate review.
|
||||
Wownero mainnet wallet. Wownero wallet promotion and the corresponding full mainline application
|
||||
activation remain blocked pending that separate review. The dated
|
||||
[schema-neutral production state](PRODUCTION_STATE_2026-07-25.md) does not clear this gate.
|
||||
|
||||
## Step 3 — Create the monerogue identity, immutable layout, and DB
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# `play.wowne.ro` production state — 2026-07-25
|
||||
|
||||
> This is a dated evidence record, not a deployment procedure or authorization to repeat an
|
||||
> exceptional release path. The normal gates in [DEPLOY.md](DEPLOY.md),
|
||||
> [DEPLOY_INSTANCES.md](DEPLOY_INSTANCES.md), and [RELEASE_ARTIFACT.md](RELEASE_ARTIFACT.md) remain
|
||||
> controlling.
|
||||
|
||||
## Active schema-neutral release
|
||||
|
||||
`play.wowne.ro` is serving the immutable release
|
||||
`20260725T121348Z-28d513-overlay-a9d6f8a`. It was prepared from exact predecessor
|
||||
`20260721T143902Z-28d513b29b36` and carries feature source marker
|
||||
`a9d6f8a1bd1af7e77f7872629e325452ed5ae46a`.
|
||||
|
||||
The overlay changes only browser/static renderer and Tavern behavior plus the same-origin
|
||||
Three.js runtime:
|
||||
|
||||
- single-player Tiled, ASCII, Iso, 3D, pack, and camera controls return keyboard focus to the game;
|
||||
- Tavern entry is explicitly anonymous, waits for session readiness, exposes pending/error states,
|
||||
and remains retryable;
|
||||
- Three.js `0.160.0` is loaded from versioned same-origin vendor routes;
|
||||
- production CDN renderer execution remains off;
|
||||
- the existing Wownero mainnet purchased-credit profile remains unchanged, with every payout path
|
||||
off.
|
||||
|
||||
The live database migration ledger still ends at
|
||||
`038_economic_identity_immutability.sql`. The overlay neither applied nor marked migrations
|
||||
039–043 and did not adopt their payment/accounting behavior.
|
||||
|
||||
## Verification evidence
|
||||
|
||||
- Complete source suite: 123 suites passed, 979 tests passed.
|
||||
- Local and public readiness probes passed with PostgreSQL, Wownero daemon, and wallet dependencies
|
||||
ready.
|
||||
- External HTTPS and Socket.IO/WebSocket smoke tests passed through the public domain.
|
||||
- A fresh browser anonymously entered the Tavern and rendered local Three.js plus the generated GLB
|
||||
model from same-origin resources.
|
||||
- Single-player mode/pack clicks retained exact `#game-display` focus; a live 3D run rendered WebGL,
|
||||
attached the animated model, and removed its temporary fallback.
|
||||
- Activation rollback was exercised by failed smoke gates before the corrected release passed.
|
||||
|
||||
Operator-host evidence:
|
||||
|
||||
| Record | SHA-256 |
|
||||
|---|---|
|
||||
| Release manifest | `8ffd5077d906c7307094eda9f1c2332fd7d1edf1bf3b337807dc8c8e5a54b780` |
|
||||
| Activation receipt | `be9ee6c8657222e11464a6e4aff6aebede067e54e83d5d70aa1cf2ac7fa5b437` |
|
||||
|
||||
## Full mainline cutover remains STOP-SHIP
|
||||
|
||||
This production state does **not** mean the complete mainline runtime artifact has been activated.
|
||||
Mainline contains migrations through 043; the existing Wownerogue database remains five migrations
|
||||
behind. A full cutover must not proceed until the reviewed fleet runbook's clone-validation,
|
||||
daemon/wallet, accounting, drain, activation-receipt, and rollback gates all pass for the exact
|
||||
candidate and predecessor.
|
||||
|
||||
The schema-neutral overlay is not precedent for bypassing those gates. Future activation or
|
||||
rollback must use the reviewed fleet control plane with literal targets, hashes, and receipts.
|
||||
+37
-3
@@ -17,8 +17,39 @@ art can be added as products.
|
||||
packs interchangeable across both.
|
||||
|
||||
Entitlement: packs are gated by the operator-owned cosmetic catalog (`cosmetic_catalog` table,
|
||||
`src/multiplayer/entitlements.js`) — free / grant / lifetime-spend / subscription-tier. `?unlock=1`
|
||||
sets a sticky local QA bypass. See `MONETIZATION.md`.
|
||||
`src/multiplayer/entitlements.js`) — free / grant / lifetime-spend / subscription-tier. See
|
||||
`MONETIZATION.md`.
|
||||
|
||||
For browser QA, `?unlock=1` sets a sticky local bypass for render-mode and pack display gates;
|
||||
`?unlock=0` clears it. This affects only that browser's `localStorage`, grants no server
|
||||
entitlement, and is not an operator access-control mechanism.
|
||||
|
||||
## Gameplay focus contract
|
||||
|
||||
Single-player keyboard movement is deliberately accepted only while `#game-display` owns browser
|
||||
focus, so typing in chat or another form cannot move the player. Choosing Tiled, ASCII, Iso, 3D, a
|
||||
pack, or a camera control immediately returns focus to that gameplay area without scrolling.
|
||||
|
||||
## Local 3D runtime
|
||||
|
||||
Three.js `0.160.0` is an exact production dependency. The server advertises the local version in
|
||||
`/runtime-config.js` and exposes only the browser build and required addons beneath:
|
||||
|
||||
```text
|
||||
/vendor/three/0.160.0/three.module.min.js
|
||||
/vendor/three/0.160.0/addons/loaders/GLTFLoader.js
|
||||
/vendor/three/0.160.0/addons/utils/SkeletonUtils.js
|
||||
```
|
||||
|
||||
The modules are imported lazily when 3D is selected. Local delivery is always enabled in the
|
||||
application runtime and takes precedence over external sources. `RENDERER_CDN_ENABLED=true` makes
|
||||
the jsDelivr renderer source path eligible only in a runtime where local delivery is disabled. All
|
||||
checked-in environment profiles keep external renderer execution off, including production, so
|
||||
Three.js remains same-origin under CSP.
|
||||
|
||||
Three.js library delivery is separate from generated model delivery. Runtime GLBs under
|
||||
`html/assets/generated/3d/` are gitignored and must be provisioned independently; the renderer
|
||||
keeps a low-poly fallback when a model cannot load and removes it once the animated GLB is attached.
|
||||
|
||||
## The FX layer (`fxLayer.js`, `RK.fx`)
|
||||
|
||||
@@ -44,5 +75,8 @@ the moment the generator emits their chars (`L`/`P`/`^`) — pending the generat
|
||||
| `zoomControl.js` | `RK.attachZoom(host)` — wheel/pinch zoom (0.4–4.0), dblclick reset, pixelated scaling. |
|
||||
| `catSprites.js` | Animated tavern cat (Pet Cats Pack idle strips). |
|
||||
| `packRegistry.js`| Multi-pack-per-projection registry: active-pack selection persisted per projection, entitlement-gated, graceful fallback. Node-testable. |
|
||||
| `threeRenderer.js` | Same-origin Three.js scene, fog-aware entity retention, animated GLB cloning, fitted model scale, camera follow, and complete renderer/resource cleanup. |
|
||||
| `spGameRenderer.js` | Single-player render bridge, player-centred camera, local 3D lazy-load, and explicit gameplay-focus restoration. |
|
||||
|
||||
Tests: `test/renderPackResolver.test.js`, `test/packRegistry_ultra.test.js`.
|
||||
Tests: `test/renderPackResolver.test.js`, `test/packRegistry_ultra.test.js`,
|
||||
`test/rendererCdnPolicy.test.js`, and `test/pvpUiPolish.test.js`.
|
||||
|
||||
@@ -24,6 +24,19 @@ transport-agnostic makes it unit-testable in isolation and reusable as a standal
|
||||
choose an avatar, move around a shared map, and chat. A spectator camera lets them watch live
|
||||
single-player or multiplayer games from inside the room.
|
||||
|
||||
### Entering anonymously
|
||||
|
||||
The Tavern requires no account or login. On connection, the browser registers the client and waits
|
||||
for the normal anonymous session handshake (`session_token`, `session_resumed`, or the associated
|
||||
identity response) before enabling **Enter tavern**. The token is stored as `wownerogue_token` in
|
||||
that browser's `localStorage` and is reused after refresh or reconnect.
|
||||
|
||||
The join form accepts its submit action, including Enter from the optional name field. Its button
|
||||
shows `Connecting…`, `Preparing…`, or `Entering…` while the corresponding step is pending. A
|
||||
disconnect or connection error resets readiness and retries automatically; a join with no server
|
||||
response becomes a visible retryable error after ten seconds. Cosmetic availability is still
|
||||
normalized and enforced by server entitlement policy.
|
||||
|
||||
**Multiplayer Match** — a shared dungeon Room using the operator-selected ruleset. Players may race
|
||||
to escape, fight to remain last alive, compete for score, or cooperate. Block-bounded rulesets end
|
||||
on the first advancing header after their active-play duration floor; every match also has a hard
|
||||
@@ -151,16 +164,18 @@ into a `Scene` (a tile grid + entities), and any renderer draws it. This lives i
|
||||
`html/js/render/` and is used by the Tavern, multiplayer client, spectators, and the single-player
|
||||
render bridge.
|
||||
|
||||
Render tiers:
|
||||
Selectable render techniques:
|
||||
- **ASCII** — monospace glyph grid (canvas). Always-available fallback; accessible.
|
||||
- **Tiled** — coloured tiles + entity sprites (canvas 2D). The default. Real tilesets/atlases
|
||||
slot in here later.
|
||||
- **Fancy** — WebGL via PixiJS: a blurred bloom on entities, flickering warm lights along the
|
||||
bar, drifting dust motes, a vignette, and smooth movement — all programmatic (no art assets).
|
||||
- **Iso** — canvas isometric projection using Kenney's Isometric Miniature Dungeon runtime PNGs.
|
||||
- **3D** — Three.js projection. It loads generated GLB avatars with `idle` / `run` / `jump`
|
||||
clips when available and falls back to lightweight low-poly avatars during asset iteration.
|
||||
- Planned: **Fancy ASCII** — shader-lit, animated glyphs.
|
||||
- **3D** — Three.js projection, loaded lazily from the pinned same-origin `three@0.160.0` runtime.
|
||||
It attaches generated GLB avatars with `idle` / `run` / `jump` clips when available and keeps a
|
||||
lightweight low-poly fallback only when the model cannot load.
|
||||
|
||||
`fancyRenderer.js` remains an internal PixiJS prototype, not a registered selectable mode.
|
||||
Production top-down styling comes from interchangeable packs plus the shared canvas FX layer.
|
||||
Planned: **Fancy ASCII** — shader-lit, animated glyphs.
|
||||
|
||||
Render mode is a per-user choice (persisted) with an operator default. Modes can be marked
|
||||
**premium** — a cosmetic entitlement intended to be unlocked with credits (the same Operator
|
||||
@@ -169,10 +184,9 @@ not a hard boundary; premium-only *assets* (special tilesets, shaders) are the r
|
||||
stronger gating is wanted. The render kit provides the engine and programmatic tiles/effects —
|
||||
polished pixel-art tilesets, sprite sheets, and shader effects are a separate content effort.
|
||||
|
||||
**CSP note:** PixiJS compiles shaders with `eval`, which the app's strict CSP blocks. The Fancy
|
||||
tier therefore loads `@pixi/unsafe-eval` (it precompiles shaders without eval) immediately after
|
||||
`pixi.js`, so no `'unsafe-eval'` is added to the CSP. Any page using the Fancy renderer must
|
||||
include both scripts, in that order.
|
||||
**CSP note:** If the internal PixiJS prototype is invoked, it loads `@pixi/unsafe-eval`
|
||||
immediately after `pixi.js` to precompile shaders without adding `'unsafe-eval'` to CSP. It also
|
||||
requires the server's explicit external-renderer policy; no current mode button invokes it.
|
||||
|
||||
## Asset delivery & performance
|
||||
|
||||
@@ -181,17 +195,20 @@ Rules for keeping the tree lean and the client fast:
|
||||
- **Heavy source artifacts never go in git.** 3D models and generation intermediates (`*.glb`,
|
||||
`*.fbx`, `*.blend`, …) are produced by the sprite pipeline (`~/src/docs/animated-sprite-pipeline.md`)
|
||||
and are gitignored. Only the *outputs* the game loads are considered for shipping.
|
||||
- **Generated / premium assets are hosted, not committed.** AI-generated premium skins live under
|
||||
`html/assets/generated/` (gitignored) and are delivered from an external asset host / CDN by URL.
|
||||
The base tier's Kenney CC0 tiles are small and stay in-repo.
|
||||
- **Generated / premium assets are provisioned, not committed.** Premium skins and runtime GLBs
|
||||
live under `html/assets/generated/` (gitignored). They may be provisioned into the same-origin
|
||||
runtime path or delivered by an explicitly reviewed asset host and CSP policy; they are not
|
||||
present in the Git release artifact. The base tier's small Kenney CC0 tiles stay in-repo.
|
||||
- **Lazy-load by mode / entitlement.** Nothing heavy loads until it's actually needed:
|
||||
- PixiJS (+ `@pixi/unsafe-eval`) loads only when the **Fancy** mode is first selected — ASCII and
|
||||
Tiled need no WebGL library.
|
||||
- ASCII and Tiled need no WebGL library. The unregistered Fancy prototype requests PixiJS plus
|
||||
`@pixi/unsafe-eval` only if called directly.
|
||||
- A premium skin's sprite sheet is fetched only when that skin is selected and the player is
|
||||
entitled to it.
|
||||
- Three.js loads only when the **3D** mode is selected. Generated GLBs are emitted by
|
||||
`scripts/build_kenney_3d_characters.py` from the local Kenney FBX sources into
|
||||
`html/assets/generated/3d/` (gitignored).
|
||||
- The exact production Three.js dependency is served beneath `/vendor/three/0.160.0/` and
|
||||
imported only when **3D** is selected. Local delivery takes precedence; external renderer
|
||||
execution remains off unless `RENDERER_CDN_ENABLED=true`.
|
||||
- Generated GLBs are emitted by `scripts/build_kenney_3d_characters.py` from local Kenney FBX
|
||||
sources into `html/assets/generated/3d/` (gitignored).
|
||||
- **Optimize what ships.** Sprite sheets are delivered as **WebP** (alpha), right-sized to display
|
||||
resolution, content-hashed with a long cache TTL. (Example: the demo walk sheet is 633 KB as PNG,
|
||||
65 KB as WebP — ~10×.)
|
||||
@@ -213,8 +230,9 @@ Multiplayer:
|
||||
- **M3** — Free, credit-prestige, and gated crypto-race economies wired in. (Done)
|
||||
|
||||
Rendering:
|
||||
- **R0** — Shared render kit: scene model + ASCII / Tiled / Fancy (PixiJS) renderers + mode
|
||||
switch, wired to the Tavern. Premium-mode gating scaffolded. (Done)
|
||||
- **R0** — Shared render kit: scene model + selectable ASCII / Tiled / Iso / 3D techniques,
|
||||
internal Fancy prototype, and a mode switch wired to the Tavern. Premium-mode gating
|
||||
scaffolded. (Done)
|
||||
- **R1** — Wire the main game to the render kit behind the existing display layer. (Done)
|
||||
- **R2** — Real tilesets / sprite sheets and the Fancy-ASCII tier.
|
||||
- **R3** — Wire premium render modes to credit entitlements (Operator Policy). (Done)
|
||||
@@ -233,8 +251,9 @@ All milestones are additive and config-gated; the single-player path is unchange
|
||||
and Socket.IO room broadcasts. Wired into `SocketHandlers` (`tavern_join` / `tavern_move` /
|
||||
`tavern_leave`, plus disconnect cleanup and shutdown). Inert unless `TAVERN_ENABLED=true`.
|
||||
|
||||
`html/tavern.html` — the browser client: connect, choose a name/avatar, enter the room, walk with
|
||||
keyboard or on-screen controls, chat, watch solo/multiplayer games, or join a match.
|
||||
`html/tavern.html` — the browser client: establish/resume an anonymous session, choose an optional
|
||||
name/avatar, enter the room, walk with keyboard or on-screen controls, chat, watch
|
||||
solo/multiplayer games, or join a match. No account login is required.
|
||||
|
||||
`src/network/chat/` — the `ChatProvider` seam. `ChatProvider` (interface) + `SocketChatProvider`
|
||||
(default: Socket.IO delivery + Postgres history). Both the global chat (`ChatHandler`) and tavern
|
||||
@@ -242,14 +261,16 @@ chat deliver through it, so the backend can be swapped (e.g. a Nostr channel) wi
|
||||
callers. Tavern chat is room-scoped and ephemeral.
|
||||
|
||||
`html/js/render/` — the render kit: `sceneModel.js` (renderer-agnostic adapters), ASCII, tiled,
|
||||
Fancy (PixiJS), isometric, and Three.js renderers, plus `renderModes.js` (registry, factory with
|
||||
graceful fallback, entitlements, persistence). Clients expose a mode toolbar where applicable;
|
||||
premium modes are marked and gated by `RK.entitlements`.
|
||||
isometric, and Three.js renderers plus the internal Fancy (PixiJS) prototype, and
|
||||
`renderModes.js` (registry, factory with graceful fallback, entitlements, persistence). Clients
|
||||
expose a mode toolbar where applicable; premium modes are marked and gated by `RK.entitlements`.
|
||||
|
||||
Tests: `test/tavernRoom.test.js` (engine), `test/tavernManager.test.js` (manager incl. chat),
|
||||
`test/chatProvider.test.js`, `test/renderScene.test.js` (scene adapter),
|
||||
`test/entitlements.test.js`, `test/identityService.test.js`, and `test/productGrants.test.js`.
|
||||
End-to-end join/move/leave and chat over a real socket verified out-of-band.
|
||||
`test/pvpUiPolish.test.js` covers the anonymous readiness/join states, and
|
||||
`test/rendererCdnPolicy.test.js` covers the same-origin Three.js runtime policy. End-to-end
|
||||
join/move/leave, local 3D, and chat over a real socket are verified out-of-band.
|
||||
|
||||
Payment/product entitlement pieces:
|
||||
- `src/migrations/020_user_appearance_and_pack_entitlements.sql` — persisted appearance,
|
||||
|
||||
Reference in New Issue
Block a user