PlayMusic Backlog Snapshot

Cross-repo undelivered work · last updated 2026-06-25 · shipped items verified against git log since 2026-04-15
Blocking Active / next up Planned Research Shipped (verified vs. git)
0
Shipped (verified)
0
Active or next up
0
Planned
0
Research / undecided
Change vs. the 2026-05-13 snapshot, after reconciling the backlog against git history across all three repos (engine · integrations · platform).
Week of 2026-06-25. Discord multiplayer was the big push — the two failures that made it feel broken (rooms dying after an idle drop, and not being able to start a fresh lobby after a match) are fixed with a new single-socket gateway. Two new bets opened up: rewarded ads running live through a Playgama vendor, and the first SEO/LLM discovery pages so curated games can be found by search engines and AI.

⭐ Highlights

Jun 18 → Jun 25 · across consumer, engine & relay

Discord multiplayer — reconnection fixed + single-socket gateway

Discord Activity multiplayer had two structural problems, both now fixed. Rooms died on an idle drop — redundant reconnect attempts were tearing down healthy connections and never recovering, so you had to relaunch the activity. And you couldn't start a fresh lobby after a match — Discord only allows one live connection per activity, so opening a second one just hung.

The fix is a new single-socket gateway: one persistent connection for the whole session, owned by the outer activity frame (which survives Discord's menu navigation), with rooms switched over control messages instead of new connections. It's behind a flag with a one-line rollback. We also tidied the lobby/spectator experience: watch-instead choice on invites, switching to spectator mid-match, spectators see the results screen, and a host "force-start" to unblock stuck lobbies.

Playgama PoC — rewarded ads through the vendor layer

We wired Playgama in as a first-class ad vendor with a new ad manager that routes rewarded-ad requests with CMS-driven vendor selection — proving the end-to-end monetisation path on a partner channel. Sits on top of last fortnight's session-tracking fixes, so Playgama sessions now report clean length data alongside the ad path. The vendor abstraction means the next partner plugs in without a rewrite.

SEO / LLM discovery pages — AEO foundation (in flight)

A new workstream to make curated games discoverable by search engines and LLMs: llms.txt, server-rendered game-detail pages with structured data (JSON-LD), AI-bot crawl rules, and per-game SEO overrides in the CMS. The model is deliberately curated, not automatic — we hand-pick the song × genre combinations worth owning, gated by a single editorial toggle that defaults to no-index. Architecture is merged; the first feature slice (P1a) is on a branch, not yet to production.

Also shipped

Previews · wizard UX · multiplayer correctness · skydomes

Game previews — big push

Manual preview-video upload and preview controls in the CMS Game Library, hover-to-play preview videos on the consumer feed, and a "has preview video" filter. Capture got much more robust across every mode — dismissing the start screen reliably, capturing actual gameplay rather than the menu, and not mistaking rhythm-mode audio for "song complete." Plus an in-engine 3D model preview in the CMS that shows real in-game orientation.

Wizard & vehicle-picker fixes

Camera perspective only resets on an actual game-type change; the mode accordion centers when it opens; the character/vehicle picker got a right-edge fade so hidden cars are discoverable; going Back from Step 3 keeps your picked vehicle; song-generated vehicles now reuse the catalog thumbnail.

Multiplayer correctness — drift & flight

Resolved the phantom 3rd car in drift and the oversized opponent ghost; fixed flight-ghost orientation, grid offset, flicker and glide smoothness — all derived locally with zero extra bandwidth. Drift traffic is now deterministic across screens (host-seeded, fixed-step). Results screens support 3–4 players and abandoned matches resolve to the survivor.

Skydomes & camera (preview parity)

Picked skydomes now render correctly in the wizard preview across aimer and obby — resilient texture loading with retry and CDN fallback, fixed an upside-down skydome bug, and the camera re-applies on perspective changes. Also: the aimer wizard preview now autoplays a muted demo so you can see real gameplay before generating.

Relay repo split complete

The multiplayer relay is now its own repository with CI/CD at parity with the engine — branch-driven deploys, secrets via Doppler, version drift-checking, and contributor docs. The relay side of the single-socket gateway shipped here too.

Next 7 days

What's queued
TikTok MP — promote the single-socket gateway from flag-gated to on, verify back-to-back matches survive in the live activity.
SEO/LLM — land the P1a feature slice to main and production behind the curated-index toggle.
Playgama — verify the rewarded-ad revenue loop on staging, then production.
Jira hygiene — close out the ~8 BUIL items now shipped (drift phantom car, vehicle thumbnails, aimer scoring, Play-Again lobby).
Prosumer — further infrastructure, DevOps, and user-flow work toward the independent-artist self-serve track.
Shared code ownership — expand shared ownership of the codebase across the team.

Why it matters

Discord MP feels reliable

The failure modes that made multiplayer feel broken — dead rooms after a drop, can't-start-a-new-lobby — are gone. That's the difference between a demo and something players will use.

Revenue loop proven

Rewarded ads running through a real vendor on Playgama is the first end-to-end proof of monetisation on a partner channel — and the vendor layer makes the next partner cheap.

New acquisition channel

SEO/LLM pages open organic search and AI-answer discovery. Curated-only keeps quality high — every indexed page is an intentional choice, not thin auto-generated content.

Previews drive clicks

Hover-play previews and robust capture mean every game card can show real gameplay — the single biggest lever on whether a browsing player presses play.

Update · 2026-06-18 — Strategy shift + three delivery streams. The pitch sharpens: "Come play games with music you love — can't find the right game? Build it in seconds." We are closing the gap between customisation and creation. Delivery is now split into three parallel streams (below); the locked End-of-Q2 launch scope is on the Launch Scope tab, and exploratory tracks on R&D.

Three delivery streams

Replaces the prior single-track framing — each stream owns its surface, audience, and pace
PlayMusicMain consumer product
Scope
  • Main application
  • Native embeds — Discord, TikTok, (Reddit or Telegram)
  • Portals
ProsumerIndependent artist
Scope
  • Infrastructure
  • New UI
  • CDN
Decomposing TemplatesReusable kit
Scope
  • Mix & match templates
  • Mix & match game mechanics
PlayMusic Launch Scope — locked for End-of-Q2 Go Live. The committed surface area across gameplay, content/creation, and distribution. Items marked * are in progress / not yet fully shipped.

PlayMusic Launch Scope

End-of-Q2 Go Live · * = in progress / not yet fully shipped
GameplayModes · sub-modes · env
Modes × 8
  • Music Runner
  • Drift
  • Music Aimer
  • Shooter*
  • Obby
  • Clicker
  • Flight
  • Platform Runner
Depth
  • Sub-modes × 20+
  • Environments × 13*
  • SFX — Beat Reactivity* (charts & visuals, filters)
Multiplayer
  • 1v1
  • 2v2*
  • Watcher*
Content & creationAssets · wizard · cards
Assets — 1.4k
  • Generated*
  • Library assets*
Game creation
  • Game Wizard + Advanced
Game cards
  • File upload
  • In-game capture
  • AI generation
  • Preview video*
Distribution & platformChannels · auth · growth
Embedded channels
  • Discord
  • TikTok
  • Reddit?
  • Telegram?
Partner portals
  • Y8
  • PlayGama
  • FRVR
  • PlayHop
  • CrazyGames (disable leaderboards)
Auth
  • Discord
  • Google
  • TikTok*
  • Email (?)
Social
  • Share game
  • Share video
SEO
  • Game indexing for SEO / LLM (HTML indexing)
Analytics & growth
  • Validate onsite happy-conversion analytics
  • Promo — competition cards
  • Misc — unknown-user high-score name capture
PlayMusic R&D. Exploratory tracks beyond the committed launch scope — where we're probing the next wave of formats.

PlayMusic R&D

Exploratory tracks beyond launch scope
Music Mixing

Deeper interactive control over the stems / mix as a play mechanic.

Open World

Exploration beyond the fixed-track loop.

Platformers

Mario / Crash Bandicoot-style platforming.

2D Games

Find, match, and other casual 2D formats.

PlayMusic — Product Strategy

Come play games with music you love.
Can't find the right game? Build it in seconds.
We are closing the gap between customisation and creation.

Strategy shift. Work is now organised into three parallel streams rather than the prior single-track distribution/content/technology framing. Each stream owns its own surface, audience, and pace.

PlayMusic — main app

The core consumer application plus native embeds (Discord, TikTok, Reddit/Telegram) and partner Portals. The flagship "play & create" loop.

Prosumer — independent artist

A self-serve track for independent artists: dedicated infrastructure, a new UI, and CDN. Lets artists stand up their own music-game experiences.

Decomposing templates

Mix & match templates and mix & match game mechanics — breaking modes into reusable, recombinable parts so new games assemble from a shared kit.

This baselines and iterates on: engagement habits (music & game affinity, sessions, session length), channel effectiveness (impressions, sessions), sentiment (D1/D7/D14 retention around creation & gameplay), and ops model at scale (deployments, games, portals, uptime).

Iteration Matrix

How the three focus areas unlock Go Live
Learning goal Distribution Content Technology
Engagement habits Multiple channels = real behavioural patterns ~10 modes × ~20 environments = enough surface to see what sticks Live analytics captures it cleanly
Channel effectiveness Y8 + Playgama + Discord gives genuine comparison Same content across channels = clean A/B Graduated rollout lets us test without risk
Sentiment (creation & gameplay) Channel mix surfaces different audience reactions Diverse modes isolate creation vs. play-loop signal Song-to-game pipeline is the thing being judged
Ops model More partners = more ops surface to stress-test More content = more throughput demands on pipeline CMS + LiveOps + deploy panel — we'll see where they break

Production Status

Live now → In flight → End of Q2 (Go Live) · updated 2026-06-18
Live NowAs of 2026-06-18
Technology
  • Song-to-game pipeline live
  • Engine in production, embedded across internal and external channels
  • CMS with full pipeline control, asset management, and deploy panel
  • Graduated deployments for maximum uptime
  • Google, Discord, and TikTok sign-in
  • Director Studio live — NLE timeline + AI cue generation, mid-song mode switching
  • Full-funnel analytics + UTM/geo attribution; LiveOps model in place
  • Quick user generation
Game Content
  • 8 game modes: Music Runner, Drift, Aimer (OSU/Taiko/Mania/Catch), Shooter, Obby, Clicker, Flight, Platform Runner
  • 20+ sub-modes; Drift Runner + Crash Course + Horror Survival presets
  • 13+ environments live
  • 4-player multiplayer (mid-join + spectators) merged to staging
Distribution
  • Fully remote control of content globally
  • Discord Activity live; partner portals (Y8, PlayGama, FRVR, PlayHop, CrazyGames)
  • Campaign builder + UTM short-link shortener
In FlightNow → Q2
Technology
  • Three delivery streams — PlayMusic (main app), Prosumer (independent artist: infra + new UI + CDN), Decomposing Templates (mix-&-match templates + mechanics, Lego-core)
  • Multiplayer hardening across all modes (2v2, Watcher)
  • Beat-reactivity SFX (charts & visuals, filters)
Game Content
  • Shooter mode finalisation
  • 1.4k asset library (generated + library assets)
  • Preview videos for game cards
Distribution
  • Native embeds: TikTok, plus Reddit / Telegram under evaluation
  • Game indexing for SEO / LLM (HTML indexing)
  • Improved global load times
End of Q2Go Live launch
Technology — platform maturity
  • Multiplayer hardening — scale to 2–4 person rooms across all modes (foundation already on feature/multiplayer; Mid-May ships Music Runner + Duet, Q2 expands the rest)
  • Tournaments & competitions engine
  • CRM in place — closes the loop between analytics and lifecycle communication
  • Advanced game-generation flow
Game Content — 10 modes, double today's depth
  • 3 new modes shipped (10 in total)
  • Multiplayer enabled across all modes (H2H + co-op)
  • Tournament / competition formats
Distribution — 4 partner channels live
  • Partner-curated content
  • Channel-specific competitions and content

Value Proposition & Consumer Messaging

Play games to the music you love. Can't find your combo? Make it in under a minute.

Play-first, create-on-the-gap. The voice makes playing feel effortless and creating feel like the natural next click — never a chore. Source: PlayMusicHack/docs/TONE_OF_VOICE.md + playmusic-value-prop.md.

The voice, in one line

Plain-spoken and confident, action-led, a little playful — we let the music and the game be the exciting part, and never try too hard.

The two-verb spine

Press play. Can't find it? Make it.Press vs make: playing is the default, making is the fallback. Keep that contrast intact wherever both actions appear.

Reference lines (calibration set — pass all eight personas)

Play games to the music you love.
Press play. Can't find it? Make it in under a minute.
Your music. Any game.
The test: if a new line would make the Explorer, the Curator, or the Philosopher wince, rewrite it.

Five rules

The register both ends of the 10–20 audience trust
1 · Plain over hype

"Play games to the music you love" — not "Unleash the ULTIMATE music gaming experience." Plainness reads as confidence to older personas, clarity to younger.

2 · Show, don't sell

Let the song titles, genres, and the actual game be exciting. The copy's job is to get out of the way.

3 · You-and-yours, never "users"

"the music you love," "your game," "the ones you can't find."

4 · Verbs, not adjectives

Play. Make. Press play. Action language is age-neutral; adjective-piles read as try-hard to anyone 15+.

5 · One light human beat, max

"Can't find it? Make it." is playful without cringe. Never two jokes in a row, never stacked exclamation marks.

Who we're talking to

Eight personas, ages 10–20 — write a voice none of them rejects
PersonaAgeAlienated by…
The Explorer / The Storyteller10–12Cynicism, complexity, anything like homework
The Identity Seeker13–15Being talked down to, fake hype, "fellow kids" voice
The Squad13–15Boring, corporate, anything not fun or shareable
The Curator15–17Anything algorithmic, mass-market, or try-hard
The Main Character15–17Flatness — they want stakes, drama, a moment
The Creator17–20Being treated as a passive consumer; over-polish
The Philosopher17–20Hype, exclamation marks, shallowness, marketing-speak

The two poles: young end (10–14) needs clear, warm, energetic, zero-cynicism; older end (15–20) needs understated, authentic, never try-hard — hype is the #1 alienator. What they share: don't be fake. That's the seam the voice threads.

Do / Don't

DoDon't
Play games to the music you loveUnleash the ULTIMATE music-gaming experience!!
Press play.Drop in. (ambiguous — say the real action)
Can't find it? Make it in under a minute.Become a CREATOR and build your dream game today!!!
Your music. Any game.A platform for music-driven gaming experiences
Make your own in under a minute.Our revolutionary next-gen pipeline lets you…
Pick a song, press play.Get ready to embark on an epic musical journey

Hard no's (the alienators): stacked !! → loses 15–20 · slang / "fellow kids" → loses everyone · "revolutionary / ultimate / next-gen / unleash / epic" → loses Curator + Philosopher · corporate flatness ("a platform for…") → loses 10–15 · talking down → loses 13+.

Homepage & SEO templates

One hand-written homepage + two data-driven templates (CMS gameTypeDefinitions)

Tier 1 — Homepage (broad, hand-written)

H1: Play games to the music you love
Subhead: Any song, any genre — from flappy flight to endless runners. Can't find your combo? Make it in under a minute.
CTA: Press play · Can't find it? Make it →

LLM-quotable definition (the line an LLM quotes back)

PlayMusic lets you play games set to any song or artist — across genres like flappy, runner, drift, obby, and rhythm — and create your own in under a minute when the combo you want doesn't exist.

Tier 2 — Genre /play/{genre} · Tier 3 — Song /play/song/{artist}-{title}

Both fill {variables} from the same wizardMeta.gameTypeDefinitions the wizard renders from, plus the song catalog. Add a genre in the CMS → its landing page exists with correct copy, no second edit. SEO surfaces lean plainer still — shaped like the query, genre/artist leads the line.

Positioning — the two-tier business value prop

From playmusic-value-prop.md · the why behind the consumer voice
DistroKid democratized music distribution. PlayMusic democratizes game-based fan engagement. Travis Scott / Ariana Grande / Lil Nas X proved games drive fan engagement — but those activations cost $500K–$5M, locking out 99.9% of artists.
Self-ServeIndie artists · $30/yr
Value
  • Turn your music into playable, shareable games — not another link fans scroll past
  • "Play my song" vs "Listen to my song"
  • 5 general OR 2 in-depth generations/yr · AI beat/energy/mood sync · web-ready export
  • Minutes to a game vs $50K–$500K / months for custom builds
Market
  • 50M+ music creators (SoundCloud 40M+, Spotify indie 11–12M, bedroom producers 20–50M)
EnterpriseLabels · agencies · brands
Value
  • Fan Portal — white-label destination where fans build games with the artist's music
  • 10–20× cheaper than custom Fortnite/Roblox builds; scalable across a roster; measurable
  • UGC flywheel: activate → fans create → compete → winning game ported to a major platform
Pricing
  • $15K/track activation · +$25K custom template · $25K/platform port
  • Blended margin 65–80% · Enterprise TAM $500M–$1B

One-liner: PlayMusic — turn music into games. $30/year for indie artists to create; $15K+ per track for labels to activate their fanbase.

Week of 2026-05-13. We can finally see how long our games take to load — by partner, by country, by device. The Portals dashboard goes live for everyone in CMS tomorrow. This was the missing piece blocking every other speed improvement on the roadmap.

What shipped this week

Cold-start visibility · adaptive loading · partner-portal polish

We can finally see load times

Until this week, partner complaints about "45-second load times" were a guessing game — we had no data. The game now reports back exactly how long each step took (initial download, configuration, game assets, audio) for every play session, on every partner.

New "Portals" dashboard in CMS

Anyone in the business can now open the CMS, go to LiveOps → Portals, and see per-partner load times, trends over time, and how many players are coming back to replay. Sparklines on each partner card give an at-a-glance health check.

Drop-out tracking

We also capture when a user bails before the game finishes loading — historically these players were invisible. Now we know how many we're losing and where.

Smart asset loading

The game now adapts how aggressively it downloads assets based on the player's connection and device. Fast connections on good devices get more in parallel; slow phones get protected from getting overwhelmed. This was originally scheduled later in the roadmap but came along for free.

Hover-to-prefetch on portals

When a player hovers over a game card for 200ms, we start loading the game in the background. By the time they click, it's already partway loaded — feels instant.

Discord embeds report in

Discord-embedded games now route through the same analytics pipeline as everywhere else, so we'll see Discord performance alongside Playgama, Y8, etc.

What we still need to fix on this

Partner-embed coverage gap — follow-up next week

The new load-time tracking works inside our own site (playmusic.gg). It doesn't yet report from games embedded directly on partner sites like Playgama or Y8, or from our portal shells. So tomorrow's prod dashboard will show consumer-site data first; partner-embed coverage is the next follow-up.

Next 7 days

What's queued · who benefits
Tomorrow — Push load-time tracking + the new Portals dashboard to production.
Tomorrow — Y8 build refresh: artist promo + region-specific music.
This week — Turn on interstitial ads for Playgama and resubmit.
Friday — Multiplayer to production; possibly to portal shells too.
Friday — Production-ready game templates integrated.
Friday — Portal shell rebrand.

Why it matters

Data-driven optimisation

Once prod has 7 days of real traffic, we'll have concrete numbers per partner, country, and device tier — and that tells us which speed investment to make next instead of guessing.

Partner conversations

Playgama, Y8, and Discord ask "how fast does it load in our region?" — we can now answer with numbers, not promises.

Drop-off recovery

Drop-out tracking turns invisible churn into a measurable metric. We can fix what we can see.

Free wins along the way

Smart asset loading + hover-prefetch came along with the instrumentation work — already shaving seconds off perceived load.

Production releases · May 1 → May 13. Two weeks of prod pushes. Over a dozen production releases landed. The themes: partner channels got faster and more reliable, internal teams got better tooling, and the platform got more stable under load. Everything below is live in production.

For our partners (Playgama, Y8, Discord)

Faster, more reliable, better measured

Y8 partner attribution fixed

Y8 traffic wasn't being properly credited in our funnel — every session looked like it came from "unknown". Fixed: Y8 sessions now show up correctly in partner reporting, so we can have a real conversation with them about volume and payouts.

Discord Activity foundation

The "game-inside-Discord" launch surface is now mostly in place — Discord Activity UI redesigned, share + mobile UX polished, analytics flowing through the same pipeline as our other partners. Featured Artist Experience landed with STYNGR admin controls for curating which artist gets the prime slot.

Playgama feedback addressed

Items Playgama flagged during partner review have been closed out and shipped to prod.

One-click "promote to prod" for partner content

Previously, getting a new song or partner-portal update from staging to production required manual coordination across systems. Now it's one click from cms-staging — for the team running partner relationships, this is daily friction gone.

For the creator + content teams

More modes, smoother creation flow

New game mode: OSU (rhythm tap)

Full rhythm-tap mode landed in production, with a polished wizard flow for picking it during game creation. Expands the catalogue beyond runner/drift/flight into the rhythm-game category.

Wizard rebuilt around real data

The "create a game" wizard used to have a lot of hardcoded options. It's now driven by actual config — so when content/engineering add a mode, it shows up in the wizard automatically. Less drift, less "why isn't X showing up?".

CMS song delete + maintenance polish

CMS got a clean song-delete flow (previously a support ticket) and maintenance-page polish so partner-visible downtime looks professional.

For the ops / LiveOps team

Better visibility, easier to act on

LiveOps got drill-down views, music data quality, and trend visibility

Five separate LiveOps improvements shipped in two weeks. The internal ops tool keeps getting tighter — drill down from a top-line metric into the underlying sessions, see music data quality at a glance, catch errors that used to go silent. Less time spent asking engineers "can you look this up for me?".

Better partner reporting infrastructure

D1 + Worker Redis runbooks finalised; observability fixes shipped. When something looks weird in the LiveOps dashboard, we now have actual playbooks for triaging it instead of inventing one each time.

For end-users (players)

Bugs fixed before most people noticed

Two same-day production hotfixes

A bug made collectibles invisible in some game modes (May 4); fixed same day. A separate bug caused phantom "MISS" popups in Cyber Run / Cosmo Run (May 5); also fixed same day. Both were caught before they hit large player numbers — operational maturity getting better.

Flight-mode ship revive UX

Smoother revive flow when players crash in flight mode — small UX nicety, but the kind of polish that compounds.

Mobile UI polish on Discord/partner shells

Mobile drawers, auto-hiding bars, share-link flow refined — the embedded-game experience feels closer to a native app.

Behind the scenes — platform reliability

Quieter wins that protect everyone

Production load tolerance improved

Database connection pooling (PgBouncer) extended to production, memory increased on the busiest services, CPU throttling tuned. Net result: we can take more concurrent players without falling over, and OOM crashes that used to happen during traffic spikes are gone.

Engine release process formalised

The game engine now has a proper "canary cutover" promotion system — new versions go to a small slice of traffic first, with one-click flip to full traffic once we're confident. Riskiest part of any release (game engine itself) is now the safest.

By the numbers

15+

Production releases in 13 days. Daily-ish cadence — partners and internal teams get value continuously, not in big quarterly drops.

Zero major outages

Two hotfixes were caught and fixed same-day. No prolonged production downtime in the window.

3 partner channels improved

Playgama, Y8, and Discord all got dedicated work this fortnight — diversifying our distribution risk.

1 new game mode live

OSU rhythm-tap shipped end-to-end — pipeline, wizard, and gameplay. Net new genre in the catalogue.

Production releases · May 14 → Jun 18. Five weeks pulled from all three repos. The engine stream drove features & templates (new modes, sub-modes, Director Studio, multiplayer); the integrations stream drove features & integration channels (Discord Activity, partner portals, embed UX); the platform stream drove CMS, analytics, and the creation flow. Everything below is live or merged to staging.

Engine — features & templates

playmusic-game-engine · new modes, Director Studio, multiplayer, template kit

Director Studio — full NLE timeline + AI cue generation

The engine-side of Director Studio matured into a real non-linear editor: multi-lane timeline, drag-edit cues, scrubbable ruler (SEEK_TO_TIME to scrub the running game), and seamless live mode-switching (APPLY_MODE) with stem crossfade between levels. Switch game mode / map / VFX / song / camera mid-song without a restart.

New & expanded game modes

Drift Runner (music runner with a steerable car), Crash Course (grouped as a Drift sub-mode), the Aimer family (OSU / Taiko / Mania / Catch) with configurable Builder/Breaker stem game-over and Drop integration + fever danger, Obby multiplayer, and a Horror Survival preset (backrooms popout zombies). FlyTap collectibles made reachable; Shooter HUD + enemy preload fixed.

Multiplayer — 4-player, mid-join, spectators

Engine threaded explicit 4-player + spectator caps, a mid-game join flow, and ghost fixes across Drift/Flight/Obby (orientation, phantom-vehicle dedup, ghost height/animation, input gating). Mid-join spectators now start rendering, not just players.

Template kit — Lego-core + env capability bounds

Phase 1–2 of Lego-core: standalone registries with parity-tested canCombine() and a harness-v2 lego route — the seam for mix-&-match templates and mechanics. Plus an env capability-bounds system, Synty Apocalypse traffic pool, and drift/crash-course driving extended to ground+road environments.

SIDEKICK avatar builder (PoC)

Proved live face/head + hair swap on a shared body via slot-agnostic equipPartGLB, natural arms via A-pose re-bind, and head-only hair binding. Foundation for a customizable character pack.

Alchemy mixer redesign

Slot-panel "fill-the-blank" UX wired to live catalog data, More Songs/Games dropdowns, and stable character alternates.

Integration — features & channels

playmusic-integrations + PMH channel plumbing · Discord, TikTok, partner portals

Discord Activity — live channel

The Discord Activity surface went from foundation to a working channel: redesigned activity UI with portal data + brand styling, mobile drawers / auto-hiding bars / share-link flow, Featured Artist Experience with STYNGR admin controls, and the game iframe tagged ?portal=discord. Activity analytics now route through the /game-api proxy and carry portal slug + user-agent in the envelope.

TikTok auth + new embedded channels

TikTok added as an auth provider (SuperTokens authorize-URL fix). Embedded-channel scope now spans Discord, TikTok, and partner portals — with Reddit / Telegram flagged as next.

Partner portals — faster, cache-correct, measured

Portal cold-start fix Phase 2 (edge-cache /api/portal/config/* in KV); scoped edge-cache purge on portal create / delete / config-save; FRVR dev harness + reliable FRVR ad triggering with correct revives; CMS "Test Portal" button + automated suite; per-portal Clear Cache. Partner portals: Y8, PlayGama, FRVR, PlayHop, CrazyGames (leaderboards disabled).

Campaign builder + UTM shortener

CMS Campaign Builder with a general /c/ short-link shortener and full UTM ingestion; environment-specific short/destination URLs; gateway routes /api/c/ to player-api for campaign links. Closes the loop from promo card → tracked session.

Attribution survives the whole funnel

First-touch UTM/referrer persisted across OAuth; GA4 ↔ Playgama join keys upgraded; shared pm_session_id/pm_user_id stamped into the GA4 dataLayer; CF geo (CF-IPCountryX-Country) forwarded end-to-end so analytics country isn't NULL. Abandoned sessions closed via pagehide beacon + hourly reaper.

Platform — CMS, creation & analytics

PlayMusicHack · wizard, LiveOps, deploy, security

Game wizard — accordion picker, persistence, funnel tracking

Accordion-style game-mode picker; persistent wizard state so reload/back recall the engine preview in sync; loading screen on re-sync; full end-to-end funnel instrumentation (wizard + Director Studio). Real game-mode labels on Profile + CMS cards (was always "Runner").

Preview videos (P1)

Capture pipeline for hover-preview videos landed — the missing piece for richer game cards (alongside file upload, in-game capture, and AI generation).

CMS — themes, songs, portals

Operator-editable display names for consumer themes; ISRC/UPC/label/parent-label persisted on song upload; per-tab delete for custom portals; cron layer for portal-cms operationalized (never ran in prod before).

Security & reliability hardening

ADMIN auth enforced on CMS portal/game management; SSRF guard on catalog fetch; staging/canary hostnames blocked from indexing; warm instances kept on user-facing services; remaining console.logs DEV-gated. Multiple Aikido review passes closed out.

By the numbers

3 repos, 5 weeks

Engine, integrations, and platform all shipped continuously — features/templates, channels, and CMS/analytics in parallel.

Director Studio live

NLE timeline + AI cue generation — game authoring without code, mid-song mode switching with no restart.

4-player multiplayer

Caps, mid-join, and spectators threaded end-to-end through engine + relay + CMS seed.

New channels

Discord Activity live, TikTok auth in, campaign shortener + full-funnel attribution.

Two-day release window: Apr 22-23 + Apr 29. Babylon engine consolidation, AI chart review, and a major production push covering portal attribution, share metrics, security hardening, and partner experience.

Apr 22-23 · Babylon engine consolidation + AI chart review

Engine + chart pipeline

Live Babylon engine + per-game config.json everywhere

Finished migrating every game-load path to use the live Babylon engine + per-game config.json. Removed the last legacy "baked HTML export" code paths from the consumer frontend, CMS, and the play API.

Portal import populates engine config

Portal imports now correctly populate game titles and song metadata in the engine config.

AI chart review hardening

Added robustness to the AI-driven chart review pipeline: handles truncated Gemini responses, configurable model, 16K token limit, robust JSON parsing for double-encoded responses.

Apr 29 · Major production push

Portal attribution · share metrics · security hardening

Portal attribution end-to-end

Every game session played from a partner portal (Playgama, Discord, Y8, etc.) now records which portal it came from. Spans the engine, consumer frontend, and backend; backed by a new game_sessions.portal_id column. Critical for partner reporting and revenue attribution.

Wizard song analytics

When a user picks a song, navigates the wizard, and creates a game, we now track impressions, clicks, and "song builds" — feeding the LiveOps Songs leaderboard for editorial decisions ("which songs should we refresh?").

Share metrics fix

Share funnel had been silently broken since March — frontend was firing one event name and backend was looking for another. Fixed; share metrics will populate from now on.

Tween-friendly share menu

Dropped X/Twitter, added Messages (iMessage/SMS), reordered for tween-relevance. Native Discord share works for connected users.

Rich link previews

Share links pasted into Discord/Slack/iMessage/Twitter now unfurl as rich cards with the game thumbnail, title, and description. Previously rendered as a generic placeholder.

Music integration semantics fix

A pipeline-vs-engine vocabulary mismatch ("drop" / "break" / "breaker" weren't valid engine values) was causing audio to drop out and never recover on some songs. Both the publish path and the engine's runtime are now defensive.

Admin security hardening

All /api/admin/* endpoints now require ADMIN-role authentication at the router level. Removed two shared-secret backdoor endpoints that were guarded only by a hardcoded string in the codebase.

Playgama partner experience

New CDN-cached path for engine assets (immutable headers); portal D1 sync respects curated CMS data instead of overwriting; tab-pause/resume on the game modal; vehicle-URL safety fix to prevent cross-mode contamination.

Quick Builder cross-link

CMS sidebar's Quick Builder now opens the consumer-app /create flow on the matching environment.

Two artist games shipped

First content showcase pieces — proof points for the song-to-game pipeline

Boujee Baby (Kendrick) — Drift mode

New environment (NYC streetscape, taller buildings, highway signs, custom sky), rigged character riding a Taxi Drift vehicle, organic camera pull-back, custom collectibles (flowers + trash), uniform Office wall with 8-color variety, denser lamps, full song-spaced gameplay tuning. Demonstrates the pipeline producing a polished one-of-one experience for a specific artist.

It Takes A Village (Canyon) — Platformer mode

New canyon environment with 3-height collectibles, double-jump + extended hang-time, "no game-over" forgiving mode, rolling wheels, diamond collectibles, song progress bar, always-on tutorial, results-screen polish. Audio unmute fix shipped alongside. Shows platformer mode now ready to host artist content, not just abstract levels.

Why these matter

Both are end-to-end proof that the song → concept art → 3D → game pipeline can deliver branded artist experiences. They also surfaced and forced fixes on real edge cases (vehicle wheel preservation, character swapping, audio fallback, void-damage modes) that now harden the engine for everyone.

Multiplayer — built and gated for testing

Live on feature/multiplayer branch · Mid-May merge target
What we'd previously listed as "Q2 / 3-6 month build" turned out to be substantially shipped. The full real-time multiplayer system is feature-complete on a branch and being load-tested with limited modes before staging merge.

Real-time relay infrastructure

Cloudflare Workers relay with Durable Objects GameRoom per match. WebSocket hibernation recovery so a worker restart doesn't drop in-flight games. 30Hz tick rate with smooth client-side interpolation between state ticks. Production relay URL wired up in the harness.

H2H (head-to-head)

Full ghost renderer with synced jump, slide, and celebration animations; lane sync; vertical-curve following on hills; postMessage integration with parent frame; dedicated MultiplayerHUD; H2H results screen.

Duet co-op mode

Stem-builder co-op where two players cooperatively trigger stems. Synced stem state, host config sharing on room join, dedicated co-op results screen.

Lobby + spectator system

Lobby with countdown, ready button gated on config load, room-state config persistence in Durable Object storage. Spectator camera + spectator lobby — anyone can watch live multiplayer matches without joining.

Customization

Ghost color picker, opacity slider, emote system, room settings panel, host toggles for ghost/score display. Player avatars with speed multiplier. Auto-removal of stale ghosts.

Currently gated

Modes restricted to Music Runner + Duet during testing. Flight and Drift disabled in MP for now — they'll come online as physics-sync mode matures. Mid-May ships the gated set; Q2 expands across all 10 modes.

Discord Activity — foundation laid

Targeting Mid-May ship — embedding + attribution groundwork in place

Frame-ancestors + trusted origins for partner embedding

CSP frame-ancestors updated to allow Y8, Playgama, GamePix, and localhost. Portal-shell can be embedded in y8.com iframes without breaking. Same plumbing extends to Discord Activity iframe at launch.

Portal attribution end-to-end

Game sessions now record portal_id at the engine level — Phase 1 (engine sessions) and Phase 2 (frontend + backend regex matching) both shipped. When Discord Activity goes live, it'll plug into the same attribution pipeline with no additional work.

Embed-mode UX

Login button hidden in /e/ embed routes. Recording.js skipped in portal/embed contexts. Tab-pause/resume on the game modal. Cumulatively this is the embed UX Discord Activity will use.

What's left for Mid-May launch

Discord Activity SDK integration, Discord OAuth scopes, lobby/voice channel awareness, and submission to Discord's developer portal. Underlying iframe + attribution + embed UX is already production-tested via Y8 / Playgama traffic.

What broke (and was fixed) during the push

Three in-flight issues, all resolved within minutes of detection
Production migrations workflow had a hardcoded list that hadn't been updated for migrations 044-048. Caused session-start endpoint to error briefly until we appended the missing migrations.
Admin auth lockdown silently broke 19 CMS pages whose fetch calls didn't carry session cookies. Patched (credentials: 'include').
First Playgama portal promote landed with broken state — project links missing, engine URL pointing at staging. Promotion-service hotfix shipped, idempotent re-run healed all 7 games.

Why it matters

Partner reporting unlocked

We can now answer "how many sessions came from Playgama vs Y8 vs Discord this week?" and start setting payouts/billing on accurate data.

Editorial signal restored

Share metrics + song engagement tracking surface "which songs are popular" — informs content refresh decisions.

First-impression upgrade

Rich link previews when users share games make Tweets, Discord posts, and iMessages noticeably more attractive to click. Compounds organic share growth.

Security posture

Admin endpoints are now properly gated. Two shared-secret backdoors removed.

Outstanding for next week

→ Connect the new asset CDN handler to actual engine traffic (currently dormant infrastructure).
→ Backfill creator attribution on Playgama games.
→ Pull baseline share metrics for analysis before next iteration.
→ Resolve a few latent data anomalies (one song with a bad audio path on staging).

Ranked by ROI — impact ÷ effort

Re-sorted to surface the highest-leverage work first: small efforts with outsized impact at the top, large bets where the impact justifies the spend further down. Effort and impact are subjective 1–5 scores; ROI = Impact × 2 − Effort (so small / high-impact items lead).

EffortS = days · M = 1-2 weeks · L = month+
Impact — combined Perf / Creator-User / Ops weight
ROI — high-leverage shipping order, not raw importance

Top 10 by ROI

Highest leverage first · effort ↓ + impact ↑
1
Partner-embed perf coverage
Cold-start load-time tracking shipped this week (consumer site + dashboard live in CMS). Direct partner iframes (Playgama, Y8 standalone) and portal shells aren't yet reporting. Closing this gap completes the partner-perf story before tomorrow's prod push goes wider.
Impact: 4/5Effort: SWhy now: closes the loop on this week's instrumentation work
S Perf Ops
2
Production deploy parity (pool / instances / PgBouncer)
Staging values validated by load test. Production workflow still on old values — risk: prod can't absorb 5K CCU. Just a workflow YAML diff applied to deploy-microservices-production.yml.
Impact: 5/5Effort: SWhy now: protects Go-Live capacity
S Perf Ops
3
Asset catalog production sync
Staging 4,628 → production 1,428 assets. Bulk D1 sync to bring prod creator catalog to parity. Likely a script invocation + verification, not net-new code.
Impact: 4/5Effort: SWhy now: unblocks pipeline at prod scale
S Creator Ops
4
Sentry on consumer-frontend
@sentry/react + error boundaries. We have product analytics (LiveOps) but no error tracking for prod traffic. Blind spots cost minutes during incidents. Grafana stack can come later — Sentry alone delivers 80% of the value.
Impact: 4/5Effort: SWhy now: incident response is currently flying blind
S Ops
5
Merge multiplayer (H2H + Duet) to staging
Branch feature-complete: Cloudflare Workers relay, Durable Objects, ghost renderer, lobby, customization. Largest single user-facing differentiator on the calendar. Effort is the merge + soak test, not the build.
Impact: 5/5Effort: MWhy now: bulk of work already done
M User Ops
6
Concept Art CMS Screen
Backend complete (6 DALL-E images, 8 personas, per-asset upload/regen/3D). Need React screen with gallery + variation cards + selection. Unlocks daily creator workflow for every song. Effort is mostly UI plumbing.
Impact: 5/5Effort: MWhy now: blocked creators on a daily basis
M Creator
7
Per-song asset slots + curated style dropdown
Configurable JSONB slots replace hardcoded 9-slot pipeline. ~12 vetted art styles in dropdown. Internal creator ask — directly enables the next 50+ artist games. Touches both pipeline + CMS.
Impact: 4/5Effort: MWhy now: internal-team unblocked, multiplies output
M Creator
8
Read replica wiring + activation
get_read_connection() already exists in game-pipeline + asset-service. Provision Cloud SQL read replica + flip to use it. Largest remaining single perf lever for backend reads. Falls back to primary so it's safe.
Impact: 4/5Effort: MWhy now: code already laid, infra is the only step
M Perf
9
Discord Activity launch (Mid-May)
Foundation laid (frame-ancestors, attribution, embed UX). Remaining: SDK integration, OAuth scopes, voice/lobby awareness, Developer Portal submission. Unlocks 4th distribution channel — but Discord SDK + review cycle is real work.
Impact: 4/5Effort: MWhy now: on the calendar already
M User
10
Tournaments engine
Docs/briefs landed (engine plan, system design, leaderboard integration). Schema + CMS + consumer UI not yet built. Largest piece of the Q2 Go-Live target — high impact but a multi-week build, so ROI sits below the quick wins.
Impact: 5/5Effort: LWhy now: Q2 gate, but plan first to avoid sprawl
L User Ops

By pillar — open work breakdown

Items unique to each axis (cross-cutting items are in the Top 10 above)

⚡ Performance

Read replica wiringWire get_read_connection() to provisioned Cloud SQL replica. Falls back to primary safely.
Engine bundle size auditTree-shake unused Babylon modules; measure current size. Engine-side.
Asset progressive loadRender scene before all GLBs are ready, swap in as they arrive. Engine-side.
/api/config/modes edge cache~620ms first-load. Cache at edge.
R2 multi-regionAll buckets WEUR today. US/APAC for latency. Research.
Guest sessions → stateless JWTsEliminates last Cloud SQL hot-path write for unauthenticated users.

👤 External user / creator

Concept Art CMS ScreenReact screen with gallery + variation cards (backend ready).
Per-song asset slots + art-style dropdownConfigurable slots; curated style catalog.
Personas viewer pageStandalone /personas with scope toggles for profile + asset use.
Alchemy creator UX polishGLB lazy-load + pagination on character grid (port already shipped).
CMS nav restructurePlan in cms-nav-restructure-plan.md.
Stale chunk error boundaryReact boundary that auto-reloads on lazy-route chunk failure.
Share Experience planScore-share with replay link, highlight clips, challenge invites, OG images.
TikTok video capture flowPlan in video-capture-tiktok-plan.md. Not started.
CrazyGames SDK integrationSubmit at least one game.
Native app (Capacitor) Phase 0-1PWA basics → Capacitor shell + Apple Sign-In + store submission.
Apple Sign-In frontend wiringBackend configured; required for App Store.
AAC fallback for SafariEngine OGG → m4a fallback. ~30 lines.

⚙️ Ops

Production pool / PgBouncer / max-instances parityStaging values validated by load test; prod still on old config.
Auto-sync D1 on publishRemoves manual "Sync to Edge" click.
Asset catalog production sync4,628 staging → 1,428 prod assets. Bulk sync.
Sentry on consumer-frontendError tracking + boundaries.
Prometheus + Grafana CloudUnified dashboards.
PostgresManager dedup~7 services have copies; move to shared.
psycopg2 → psycopg3 conversion~10 files, mechanical translation.
WizardPipelineManagerV2 dedupSingle source of truth across services.
Monolith deploy fallbackHard-fail or remove dead-monolith fallback in staging workflow.
SuperTokens production instanceProd still hits staging SuperTokens; needs dedicated instance.
R2 multi-region(also under Perf — ops cost angle)
Husk package deletionRemove deprecated babylon-game-engine, playmusic-game-sdk, r3f-game-engine dirs.
Filter Active 0 Planned 0 Research 0 Shipped 0 Reset

PlayMusicHack

~/Projects/PlayMusicHack/docs/backlog/

✅ Shipped — Week of Jun 25

Verified against git log across PMH, engine & relay (Jun 18 → Jun 25). See the 📅 Week of Jun 25 tab for the narrative.

Discord multiplayer — gateway & reconnection

  • Reconnection storm fixed — single-flight connect() stops redundant calls tearing down healthy sockets; idle 1006 drops now recover.5756260b
  • Single-socket gateway — one persistent WS to the relay's /gateway/ws, rooms via control frames (fixes Discord's 2nd-WS-per-instance wedge). Flag-gated.d5d5c10da9bbc93
  • Activity-owned socketParentBridgeSocket moves socket ownership to the outer activity frame so it survives Discord menu nav.4afd521d
  • Gateway correctness — bridge is Discord-only (fixed web regression); leave-room scoped to roomId (fast-restart race).a5ffadd79b92110a
  • Lobby / spectator UX — watch-instead picker, in-place spectator switch, spectator results screen, host force-start.ddc3ffad

Partner / discovery bets

  • Playgama rewarded-ads vendor — AdManager routes rewarded requests with CMS-driven vendor selection (PoC).7f07e780
  • SEO/LLM — AEO foundationllms.txt, edge-render game-detail pages, JSON-LD, per-game CMS SEO (P1a, branch).09bfe9cede84f018

Game previews

  • Preview videos end-to-end — manual upload + detail-modal controls, hover-play on consumer feed, "has preview" filter.d259f9bb8f6bd6be
  • Capture robustness — adaptive start + deathless capture, gameplay (not menu) on gated modes, audio autoplay fix.bf1e0312b763cbc2
  • In-engine 3D model preview in CMS — real in-game orientation.267d4a20

Multiplayer correctness · wizard · skydomes

  • Drift phantom 3rd car + oversized ghost — centralized character re-enable; ghost scaled by room mode.fbc3fec946b0b678
  • Flight ghost — orientation/pitch/roll, grid offset, flicker + glide; non-default ghost stays upright. Zero extra bandwidth.21d3cd7f8a99a6ed
  • Deterministic drift traffic — host-seeded, fixed-step cadence + seeded lane shuffle; matches across screens.0d9aba97
  • Wizard UX — picker edge-fade, Back keeps vehicle, accordion centers, song-vehicle thumbnail, camera-reset scoping.13cf2d48e8ec6a88
  • Skydome preview parity — resilient load (retry + CDN fallback), un-flipped skydome, aimer/obby preview fixes, aimer autoplay demo.4ed0536b786c1817
  • Relay repo split complete — pm-mp-relay standalone with engine-parity CI/CD + Doppler secrets + drift-check.352fe92a

Backend Microservices

Tech debt, latent bugs, performance follow-ups across the 7 microservices.

Tech debt

  • psycopg2 → psycopg3 conversion — ~10 files in player-api + media-service still import psycopg2 at module level. Mechanical 1:1 translation.3ad011ac
  • PostgresManager duplicated across 7+ services — each has its own infra/postgres_manager.py copy. Move to shared module.c80d147b
  • WizardPipelineManagerV2 duplicated — exists in portal-cms, game-pipeline, asset-service, celery-worker. Single source of truth needed.46e842a7
  • D1 game sync is manual — CMS "Sync to Edge" must be clicked after publish. Should auto-sync.87ff298f
  • Docker layer cache serves stale shared codebackend/shared/ changes may not propagate due to GHA cache.8b62bf27
  • Game categories inconsistent — DB has old categories (runner, rhythm) for migrated games; consumer app has new (endless, music, drift).8afbf67d
  • Monolith deploy fallback — staging workflow silently falls back to dead playmusic-backend-staging if a service URL fetch fails. Hard-fail or remove.825e2c2b

Latent bugs (April audit)

  • TIME_UPDATE log spam in GameModalV2 — handler added.verified
  • 🟡
    start_session non-UUID insert — accepts "dev-test" as guest_id; psycopg rejects. Validate or 400.
  • 🟡
    get_leaderboard route ordering — static /leaderboard/creators matched by parameterized route. Reorder.
  • 🟢
    Transient psycopg connection drops — Cloud SQL cuts idle connections; pool doesn't pre-ping.
  • asset-service OOM on 512 MiB — bump to 1Gi or profile leak.cc68a05f

Performance follow-ups (load test 2026-04-21)

  • 🟢
    Read replica wiringget_read_connection() exists but isn't called yet. Provision Cloud SQL replica + wire up.
  • Production deploy parity — pool size, PgBouncer config, max-instances bumps from staging.02204539
  • Upstash Redis activation — leaderboard + likes instant reads/writes at scale.6047ef48
  • PgBouncer sidecar permanent in staging — load test fixes including DB pool sizing and edge caching.9ceb43b4
  • Guest sessions → stateless JWTs — eliminates last Cloud SQL hot-path write for unauthenticated users.a40b98a9

Cold-start load time (2026-05-13)

  • Cold-start instrumentation end-to-end — engine reports timing back to host; backend captures per-session step breakdown (download / config / assets / audio); country + device tier dimensions populated.a98263a5af4f019b
  • Drop-out tracking — users who bail before session start now counted via beacon ping; race condition vs in-flight session fixed.b6048dae9ac973ad
  • Portals dashboard in CMS — LiveOps → Portals tab with per-partner KPI cards, inline sparklines, trends + retention.8a6588403ae7b382
  • Hover-to-prefetch on game cards — 200ms intent prefetch on consumer + portal-shell; saved-data / low-tier defended.2e3a8125a8d03cc4
  • Per-session perf token — closes Aikido IDOR finding on the new perf endpoint.595b692fba045eff
  • 🟡
    Partner-embed coverage gap — perf reporting wired from consumer site only. Direct Playgama / Y8 iframes and portal shells not yet reporting. Audit each host + decide engine fallback strategy.

Production cutover

  • game-pipeline service extraction — still partial.8b54e940
  • engine-api service stabilization — works but flagged unstable.98a2698f
  • /api/games/purge-cache route missing on prod gateway — add nginx route.9c97ad4a
  • Production SuperTokens instance — production still hits staging SuperTokens. Need dedicated instance + DB.8488be22

CMS & Creator Tools

Concept art, Alchemy port, share/recording, promote-to-prod. CMS lives in frontend/.

Concept art & creative direction

  • 🟡
    Concept Art CMS Screen — backend complete (6 DALL-E images, 8 persona variations). Need React screen: gallery, variation cards, selection, reference upload.
  • Per-asset upload/replace — replace concept art image in R2 from CMS.0441947a
  • Per-asset prompt regen — show full prompt + extra direction field, regenerate single asset via gpt-image-1.193aa754
  • Per-asset 3D from concept — Meshy I2D button per concept image.d90cb0f5

Alchemy UI port

  • 🟢
    Port Alchemy to React — engine packages/alchemy/consumer-frontend/src/pages/Create.jsx. Replace hardcoded defs with catalog API.
  • 🟢
    /create route — split-panel: engine iframe left, song/mode/character pickers right. Replaces multi-step wizard.

Share & recording

  • 🟢
    Share Experience plan — full plan in docs/share-experience-plan.md. Not started.
  • Recording engine port — Babylon recording.js sourced from backend/game-server/static/, manually synced. Make engine repo canonical.767690cf
  • /play/:gameId GameModalV2 wrap — currently bare EngineFrame. Should wrap in full GameModalV2 (likes, leaderboard, share).2f705103

Promote to Production

  • Promote to Production CMS feature — batch select songs/games/portals from CMS.5cfa3b4f
  • Promotion service hardening — engine URL rewrite, project_id relink, cascades, schema fixes.7c5b5ee7
  • E2E promote flow — first Playgama portal promote landed (with hotfixes); 7 games healed via idempotent re-run.7c5b5ee7

Other CMS gaps

  • 🟢
    Asset Library Tool — standalone /asset-library.html with semantic search across 4,000+ catalog assets.
  • CMS nav restructure — plan in docs/cms-nav-restructure-plan.md.76185308
  • Stale chunk error boundary — lazy-loaded routes fail after deploys. Auto-reload on chunk failure.756308a6
  • Wizard preview env reset bug — after handleConfirm, mode-init effect re-fires with default neonArcade. Visual only.fac37fbf

Song-to-Game Pipeline

Internal-user requests for the song → concept art → 3D → game flow.

Per-song asset slots (drives concept art + 3D)

  • Configurable slot system — replace hardcoded 9 concept art slots + character/obstacle/collectible workers with per-song JSONB concept_art_slots config. Each slot: {id, type, label, generate_concept, generate_3d, art_style?, rigged?}.6d87aba0
  • Slots panel in CMS — UI to add/remove/rename slots before generation. Defaults to current 9.3856028b
  • 🟢
    Engine config compat — slot ids → engine roles. Decision pending: keep canonical filenames or remap in config builder.
  • Migration — new column on songs, default = current 9-slot config.6d87aba0

Curated art-style dropdown

  • Style catalog — ~12 styles vetted against gpt-image-1 + Meshy lowpoly: anime, western cartoon, comic book, Studio Ghibli, cel-shaded, low-poly stylized, claymation, synthwave, noir, watercolor (2D-only), pixel art (2D-only).0af52a90
  • Per-song default + per-slot override — song profile gets art_style field. Regen modal exposes per-asset override.6d87aba0
  • Prompt injection — fragments slot into existing prompt builders.46e842a7
  • 🟢
    Style verification batch — generation run across all 12 to confirm Meshy-safe flag is correct.

Personas viewer (standalone CMS page)

  • /personas page — list all 8 hardcoded personas with name, age range, description, system prompt. Read-only v1.45ba0509
  • Two scope toggles per persona — "Use for song profiles" + "Use for asset generation".658945d9
  • Persistence decision pending — move 8 personas into personas table, or keep hardcoded + side table for scope toggles.mig 053/054

Multiplayer

  • Real-time multiplayer foundation — Cloudflare Workers relay, Durable Objects GameRoom, WebSocket hibernation recovery, 30Hz tick.c2f3f806d442cc
  • H2H (head-to-head) gameplay — ghost renderer, lobby, postMessage integration, MultiplayerHUD, results screen.abb0361661c802
  • Duet co-op mode — stem builder co-op with synced state and dedicated results screen.bd94019a7dd79f
  • Spectator camera + lobby — watch live multiplayer matches.cfd2d697f2ce35
  • Multiplayer customization — ghost color, opacity, emotes, room settings, host toggles.24df3d6
  • Merge feature/multiplayer to staging — branch is feature-complete; gated to Music Runner + Duet during testing. Mid-May ship.8d12b671
  • Expand multiplayer to all modes — flight + drift currently disabled in MP; Q2 target enables across all 10 modes.2e10fd77
  • 🟢
    Score challenges (async ghost share) — share link "beat my 12,000" using existing ghost replay infra.

Tournaments

  • 🔵
    Tournament definition — schema needed: tournament, entry, leaderboard scope, prize, time window. New CMS page to manage.
  • 🔵
    Time-bounded leaderboard scope — D1 leaderboard infra exists; needs tournament_id filter.
  • 🔵
    Tournament UI on consumer — entry, current standings, countdown, results.
  • 🔵
    Reward / prize plumbing — out of scope until tournament v1 ships.

Deeper sharing

  • 🟢
    Score-share with replay link — share link includes recorded session for ghost playback.
  • 🟢
    Highlight clip share — auto-generate clip of best moment for TikTok/Discord.
  • 🟢
    Challenge invite — share-with-target to specific friend, results aggregated server-side.
  • 🟢
    Embed share image — OG image with score, song, character thumbnail. Pre-rendered server-side.

Integrations

TikTok, Discord, CrazyGames, native (Capacitor), Apple Sign-In.

TikTok

  • 🟡
    Profile "Connect" gating — not gated on VITE_ENABLE_TIKTOK_SIGNIN. Auth sign-in is gated; profile connect button always shows.
  • 🟢
    TikTok video capture flow — full plan in docs/video-capture-tiktok-plan.md. Not started.

Discord

  • Discord Activity (game-in-Discord) — full plan in docs/discord-activity-integration.md. Not started.3a28557
  • Discord activity analytics via gateway proxy — analytics calls now route through /game-api so Discord-embedded games are visible in the same pipeline as Playgama / Y8.d7817b6

CrazyGames

  • 🟢
    CrazyGames SDK integration — slash command exists for export prep. Not yet wired into publish flow. Submit at least one game.

Native app (Capacitor)

  • 🟢
    Phase 0 (1-2 wk): PWA basics — manifest, service worker, installable.
  • 🟢
    Phase 1 (4-6 wk): Capacitor shell, Apple + Google Sign-In, store submission.
  • 🟢
    Phase 2 (4-6 wk): Push notifications, offline caching (~500MB), native share, score challenges.
  • 🟢
    Phase 3 (8-12 wk): IAP, ghost replays, Babylon Native prototype.

Apple Sign-In + Luminate

  • 🟢
    Apple Sign-In frontend wiring — backend already configured. Required for App Store submission.
  • Luminate music data — backlog in docs/luminate-backlog.md. Decide before scoping.c2fc013d

Infrastructure

Deploy panel, blue/green, perf, observability, D1, R2.

Deploy

  • Deploy panel + Force Deploy + maintenance page — non-dev control panel with branded maintenance/404 toggle.b1fff58dde771703
  • Canary preview routing + fallback — auto-set cookie + 404 fallback to stable.98d679c4c04801ad
  • Graduated rollout (production) — production canary live; backends graduate to 100% before gateway+frontend.441aaaa0
  • 🔵
    Blue/green deployment — ~$320/mo extra. Revisit if canary doesn't stabilize.

D1 / edge

  • Auto-sync D1 on cache purge — published games sync to D1 edge automatically.9a619716
  • 🟢
    Asset catalog prod sync — staging has 4,628 assets, production has 1,428. Bulk D1 sync.
  • Thumbnail URL cleanup — production games reference staging API URLs. Migrate to CDN.2953fa38
  • /api/config/modes edge cache — ~620ms first load. Cache at edge.2024e482

Performance & storage

  • Engine iframe load time — engine-side optimizations + immutable CDN headers + redundant audio load skip.ca7058a
  • R2 jurisdiction cleanup — switched to default endpoint for WEUR buckets, removed dual-client routing.5921d3b9a9a6a088
  • 🔵
    R2 multi-region — all WEUR today. US/APAC for latency.
  • Thumbnail storage unification — pipeline bucket → assets bucket + CDN URLs in D1.1649bccc
  • Read replica provisioning — Cloud SQL replica + wire get_read_connection().7fb7c3ac

Observability

  • 🟢
    Sentry on consumer-frontend — error boundaries, error tracking.
  • 🟢
    Prometheus + Grafana Cloud — unified dashboards.
  • LiveOps on production — hybrid PostgreSQL + BigQuery analytics live, dynamic source badges, Creation tab.4e6e5d0ea0b9fcf7
  • Migration 042 (analytics_events) — ran on prod via 044-048 hotfix workflow.0ba4065d

Other

  • Remove Godot prefetch — D1 game feed + project detail return Babylon engine URL; wizard prefetches Babylon engine, not Godot.5b4790442e145c07698c581d
  • 🟢
    Delete husk packagesbabylon-game-engine/, playmusic-game-sdk/, r3f-game-engine/ are deprecated.

Open Bugs (April snapshot)

Production / staging bugs not yet fixed.

Production

  • TikTok "Connect" shows on production Profile — gating fixed.verified
  • Game likes refreshing in GameModalV2 — Upstash Redis + D1 edge writes resolved sync issues.6047ef4803b22e3b
  • /api/games/purge-cache on prod gateway — D1 sync side-effect cleaned up.38672324

Catalog / preview

  • Wizard preview env reset to neonArcade — fixed.verified
  • Catalog vehicle/ship thumbnails — generation + upload run, R2 backfilled.verified
  • Catalog vehicle orientation auto-correct (engine-side) — runtime fix for Y-up oriented vehicle models.f81195c
  • Drift vehicle wheel preservation + swap — VehicleController preserves GLB hierarchy and shared modelCache.098ac55de310b7

Mobile / dev experience

  • Director mobile touch input — override select-none for inputs to enable touch.6320356
  • TIME_UPDATE log spam — handler added (or throttled engine-side).verified
  • Stale chunk errors after deploy — lazy-loaded routes fail. Need React error boundary that auto-reloads.756308a6

Babylon Game Engine

~/Projects/playmusic-game-engine/docs/backlog/

Engine Runtime

Performance, audio, retargeting, iframe protocol, catalog assets.

Performance

  • Iframe load time — engine-side optimizations + immutable CDN headers + redundant audio load skip.ca7058a
  • Engine debug logging[STATE] / [gameLoop] console logs stripped before production.verified
  • Adaptive asset-load concurrency — tier-aware GLB preload batch size (sequential gating preserved for low-end).03939a14
  • Cold-start perf instrumentation — engine reports timing marks to host via PERF_TIMING; Server-Timing parser captures gateway overhead.488154ff62e554c9e2cbac02
  • 🟢
    Bundle size audit — measure current Babylon + game code; tree-shake unused modules.
  • 🟢
    Asset progressive load — load scene before all GLBs are ready, swap in as they arrive.

Audio

  • 🟢
    AAC (.m4a) fallback for Safari — full plan in AAC_FALLBACK_PLAN.md. ~30 lines new code.

Iframe protocol bugs

  • TIME_UPDATE log spam — resolved on PMH side.verified
  • SET_VEHICLE_MODEL swap fix — route to DriftMode's VehicleController; reparent meshes correctly.33c980ab617443
  • Director mobile touch input — override select-none on inputs.6320356

Retargeting / animations

  • Runtime animation retargeting — fallback verified; library skeleton kept alive, minimal retarget options for same-convention skeletons.3a38c5637fbfe5
  • Babylon.js v8 upgrade — required for AnimatorAvatar retargeting (CHR-03, ANIM-02, ANIM-03).1db82d75
  • 🔵
    Babylon.js v9 upgrade — supersedes v8 work. WebGPU defaults, IBL improvements, NME updates. Likely batch with v8 (skip straight to v9).
  • 🟢
    Shared animation library — Quaternius UAL packaged into anims-core.glb, etc. on R2. Eliminates per-song animation gen.

Catalog assets

  • Vehicle orientation auto-correct — runtime fix in engine for Y-up oriented vehicle models.f81195c
  • 🟢
    Engine player model API unification — 3 URL fields + 3 SET actions. Long-term: unify into one.

Engine Tools

Standalone tools (Alchemy, Director, Harness, Asset Library, Anim Harness).

Alchemy (creator)

  • Port to React in PMH — Alchemy creator rewritten as React, connected to catalog API.verified
  • 🟢
    GLB lazy-load + pagination — character grid currently loads all at once.

Director Studio

  • Director Studio UI — full plan in DIRECTOR_STUDIO_PLAN.md. Standalone page with timeline + cue editor + VFX/audio/scene panels.5ba325fd
  • Director touch handling — mobile touch input enabled for inputs.6320356

Harness — embedded Scene Editor

  • Slot editor + asset browser in harness (v0) — first cut shipped 2026-04-20.1daf5c4
  • 🟢
    Embed full Babylon Scene Editor — beyond slot editor: drag-place props, edit lights/cameras, materials. Save scene back to game config. Likely iframe or panel inside packages/harness/.
  • 🟢
    Scene → config serialization — Scene Editor writes .babylon/glTF; serializer maps editor entities → our slot/spawn/entity model.
  • 🟢
    Asset library bridge — Scene Editor pulls props/characters from catalog instead of file uploads. Custom asset browser panel.

QA Harness, Asset Library, Anim Harness

  • QA tools panel — full spec in QA-TOOLS-PLAN.md. 11 tool categories.146791f0
  • 🟢
    Standalone /asset-library.html — browse all catalog assets, filter by type/style/pack, semantic search, 3D preview.
  • 🟢
    /anim-harness.html — load any character GLB + animation library, test retargeting. Blocked on Babylon v8/v9.

Husk packages

  • 🟢
    Delete packages/babylon-game-engine/ — deprecated split.
  • 🟢
    Delete packages/playmusic-game-sdk/ — split to separate repo.
  • 🟢
    Delete packages/r3f-game-engine/ — deprecated.

Engine Bridges

postMessage protocol, recording, multiplayer hooks, native, CrazyGames.

Iframe / postMessage protocol

  • 🟢
    TIME_UPDATE handler / throttle — see runtime section.
  • 🟢
    Bridge API docPlayMusicBridge.ts has 3 player-model URL fields + 3 SET actions. Document and unify.

Recording

  • recording.js source-of-truth — currently in PMH, manually synced into engine. Make engine repo canonical.767690cf

Multiplayer & sharing hooks

  • Real-time multiplayer surface — Durable Objects WebSocket relay, ghost renderer, lobby, customization.feature/multiplayer
  • 🟢
    Score-challenge async embed — accept ?challenge=<replay_id>, fetch ghost data, render semi-transparent player. Reuses real-time ghost infra.
  • 🟢
    Highlight clip detection — engine emits "best moment" event for share clip extraction.
  • 🟢
    Pre-rendered OG image — server-side OG image; engine just provides screenshot endpoint.

Native & CrazyGames

  • 🔵
    Babylon Native viability — currently blocked by no Web Audio API support.
  • 🟢
    CrazyGames SDK ad hooks — engine emits "level start"/"level end"/"rewarded ad opportunity" events.