Real-time project tracking — every task, user story, and milestone.
Based on analysis of the PAC-MAN BATTLE ROYALE CHOMPIONSHIP arcade cabinet. These user stories close the visual gap between our WebGL version and the arcade original.
#0a0a0f) with dynamic neon grid or animated maze silhouette; oversized branded header with pulsing glow; PLAY LOCAL and PLAY ONLINE rendered as arcade-button cards with distinct hover (scale + brightness) and press (sink + flash) animations; version and status-page link present but not dominant.Bug fixes for pellet persistence across games (local + online), random maze layouts for variety, and power-up icon overhaul for visibility.
PelletTwinkleEffect.OnDestroy() only unsubscribes events but does NOT destroy its overlay GameObjects. When the component is destroyed between games, orphaned SpriteRenderer children persist and render on top of the tilemap. Same issue in PowerPelletGlowEffect. Fix: explicit child GO cleanup in OnDestroy().ClearClientPowerPellets() does not rebuild twinkle/glow effects after downgrading PPs, leaving power-pellet-styled overlays at wrong positions. Fix: OnDestroy() cleanup + rebuilt effects after PP clear.Reinitialise(). All layouts must pass dead-end validation and have ghost house + tunnels.OnDestroy() destroys overlay GOs; no orphans after ResetForNewGame() + BeginGame(); overlay count matches layout after Reinitialise().Reinitialise() correct pellet count.Eliminate the structural reasons why every change breaks something else. Informed by a full-codebase fragility audit (May 23 2026): hub-assembly coupling, god objects (LocalMultiPlayerLoop ~1,300 LOC), multiple sources of truth for player state, defensive null-conditional patterns that hide broken wiring, and duplicated local-vs-server tick logic.
LocalMultiPlayerLoop God ObjectPowerUpManager, PlayerLifecycleController, ScoreCoordinator, BoardRepopulator from the ~1,300 LOC class. Loop becomes a thin orchestrator (≤ 350 LOC).IGameTickerIGameTicker + shared GameTickerOrchestrator and refactored LocalMultiPlayerLoop to execute a deterministic ordered ticker pipeline. EditMode tests validate registration-order execution, exception isolation, and verbatim deltaTime forwarding.PlayerEntry / PlayerState / snapshot structs mirror the same fields. Collapse into one canonical PlayerStateRecord owned by PlayerStateStore; sync bugs become impossible by construction.?. chains on required [SerializeField] refs with fail-fast validation hooks. Added [RequireReference] coverage across production MonoBehaviours plus EditMode reflection enforcement. Phase 1 + 2 complete.GameConfig ScriptableObjectsGameConfig.asset + BalanceConfig.asset. Tuning becomes a single asset edit.+= paired with -= in OnDestroy. Introduce EventBag helper for auto-unsubscribe. Replaces // avoid double-sub defensive patterns.Find* Outside BootstrapFindFirstObjectByType / FindObjectsByType in OnlineServerGameLoop, GameContext, MazeGlowController with explicit DI. EditMode test fails if Find* appears outside Bootstrap*.cs..unity YAML edits as a fix path repeatedly. Move all such wiring into a self-validating SceneBootstrapper; the committed scene file becomes a thin stub.PacmanRoyale.Game.asmdef references Core + BattleRoyale + UI + Networking. Introduce PacmanRoyale.Contracts (interfaces only). Dep graph becomes acyclic with max depth 3.PlayerEntryStartPower(float), Eliminate()). Validates state transitions.PacmanController Rendering from LogicPacmanRenderer (chomp, rotation, network facing, death blink). Controller handles input + movement + collision only. Structurally prevents the "rendering code overwrote network state" bug class.Update()/IGameTicker contract checks, Core mutable-field bans (with explicit allowlists), and US-9.05 catalogue-driven config-consumption regressions.[SerializeField] → component disables itself + logs error (no silent soft-fail). Test files authored and in review.ARCHITECTURE.mdREADME.md and Copilot instructions.Beautiful AND silky-smooth on weak hardware. Target: steady 60 FPS on Intel HD 620 / 4-year-old laptop / 720p / 4-player local mode; ≤ 0.5 ms/frame GC pressure; ≤ 200 KB/s online bandwidth; ≤ 3 s scene load. Informed by the May 23 2026 performance audit (10 specific wins identified).
MazeRenderer.RenderPelletsOnly() clears 868 tiles + redraws every pellet eat (~217,000 wasted ops per game). Replace with ClearPellet(col, row) / SetPellet(col, row).MazeTextureGenerator + editor menu Tools/Pac-Man/Bake Maze Textures; baked 4 assets under Resources/Textures/Generated/; runtime now uses Resources.Load<Texture2D> with warning-backed fallback generation. Baked assets are uncompressed RGBA32 for this story (ETC2 follow-up)..text Assignments (In Review)TmpTextCache.SetIfChanged() added; ScoreFormat pre-formats 100k score strings. 14 .text= assignments migrated across ArcadeHudChrome, HudController, PowerTimerHud, LeaderDisplay, OnlineClientRenderer. TmpTextCacheTests + ScoreFormatTests added.FindObjectsByType in MazeGlowController (In Review)MazeGlowController now caches tilemaps in OnEnable and refreshes the cache on sceneLoaded; EditMode cache tests added._spritesDefaultMat + GetSpritesDefaultMaterial() added to LeaderDisplay and OnlineYouArrow. MaterialCachingTests verifies same instance returned on repeated calls. 2 material caches added.SteadyStateAllocationTests ([Category("Performance")]) for a 1,000-frame GC budget assertion (≤ 1 MB).skipIterations=1 (already configured); URP Bloom/Vignette controlled by PostProcessQualityBridge. QualityPresetManager static service (enum Low/Medium/High, PlayerPrefs key pacman.quality, QualityChanged event). Ghost trails disabled on Low (GhostTrailEffect). Leader aura disabled on Low (LeaderDisplay). Corner vignettes disabled on Low (MazeGlowController). QualityToggleSettingsPanel toggle UI. 10 EditMode tests added.EffectPool<T> + PoolableEffect; migrated PacmanDeathEffect, PelletEatEffect, PowerActivateEffect, ComboScorePopup, PowerPelletGlowEffect, PelletTwinkleEffect, and EnhancedParticles; added pool reuse/max-size PlayMode tests.Low/Medium/High from SystemInfo (GFX MB + CPU MHz) on non-WebGL; WebGL starts Medium then runs a 5-second FPS sampler — average < 50 FPS downgrades to Low. Guard key pacman.quality.detected prevents re-detection. Wired via WebGLBootstrapper. 14 EditMode tests.ProceduralMusic (In Review)MazeGlow.shader (URP HLSL) moves sine pulse + neon colour cycle to GPU via _Time.y. MazeGlowController throttles MaterialPropertyBlock pushes to ≤ 10 Hz. 4 EditMode tests verify push-count invariant.PlayTestRunner records frame-time + GC bytes/frame against PerfBaseline.json. Deploy blocks if frame time > +10% or GC bytes > +25%.Make it shippable to strangers. M9 made the code anti-fragile and M10 made it fast; M11 closes the gap between "technically solid" and "publish-ready." Four pillars: Online resilience (graceful disconnects, reconnect-with-state-restore, shareable room codes, error-recoverable matchmaking, host-leave handling, spectator mode), Operability (anonymous telemetry, crash reporting + "Report Issue" UI, semver + embedded git SHA), Inclusivity (color-blind palettes, motion-reduction, high-contrast HUD), and Release plumbing (WebGL tab blur auto-pause, settings persistence audit, release CI gate with WebGL build smoke + perf gate + version-tag automation). 14 stories.
Disconnected, freeze Pac-Man at last tile, render RECONNECTING… overlay for ≤ 30 s (GameConfig.DisconnectGracePeriodSeconds); only on grace expiry call existing elimination path. New PlayerConnectionTracker + DisconnectGraceController.(roomCode, playerToken) handshake; server restreams last GameStateBroadcast + recent deltas; Pac-Man resumes at frozen tile with prior lives/score/power-timer. PlayerPrefs.pacman.playerToken GUID; new ReconnectHandshake + PlayerTokenStore.RoomCodeGenerator + RoomDirectory + LobbyManager, FishNet room-code handshake, Create Private Room + Join with Code modal (auto-uppercase + validation), copy-share-link helper (https://<host>/?room=CODE), and WebGL URL prefill bridge.MatchmakingFailureMode enum (TransportTimeout/ServerFull/VersionMismatch/AuthFailed/RoomNotFound/Unknown) + MatchmakingErrorService diagnostics persistence + MatchmakingErrorPanel with Retry/Back/Report. Retry backoff uses 1s → 2s → 4s and final failure surfaces a stable error code.HostLeftMatch → 5 s HOST LEFT — RETURNING TO MENU overlay on remaining clients → auto-return to main menu. ARCHITECTURE.md §11 documents v1 decision to defer peer-to-peer host promotion.GameStateBroadcast snapshots); SpectatorHud shows leader view + cycle-with-Tab + "SPECTATOR" badge; promoted to active player on next-round lobby transition.{schemaVersion, buildVersion, gitSha, platform, mode, playerCount, durationSec, avgFps, p99FrameTimeMs, winnerSlot, totalPellets, totalEliminations}. Stub https://telemetry.pacmanbr.example/v1/round, 3 s fire-and-forget. No PII.UncaughtExceptionBuffer retains last 100 Exception/Error log entries (ring, stack + timestamp + scene + version). Pause-menu Report Issue button opens ReportIssuePanel with description text + "Include diagnostic log" checkbox; POST to stub /v1/report.ColorBlindPalette enum + central PaletteService; Ghost/PowerUpSprites/LeaderDisplay/HudController consume from service; runtime switch updates visuals in one frame via PaletteChanged event. Each palette: 4 unique ghost colors + 3 unique power-up tints with min ΔE ≥ 25.Reduce Motion toggle disables camera shake, GhostTrailEffect, EnhancedParticles burst mode (rate cap 25%), PelletTwinkleEffect/PowerPelletGlowEffect pulse, VictoryCelebration confetti. All five hooks read from MotionReductionService.HudController/ArcadeHudChrome/PowerTimerHud/LeaderDisplay/EliminationScreenUI. Independent of US-11.09 (combinable).TabFocusController + VisibilityBridge.jslib + TabInactiveOverlay. Single-player/local-MP now fully pause (Time.timeScale=0 + audio duck) and resume on focus return; online mode keeps simulation running while muting locally, showing overlay, and suppressing local input broadcast only.BuildInfo.cs stamped by BuildInfoBaker (IPreprocessBuildWithReport) from PlayerSettings.bundleVersion + git rev-parse --short HEAD + UTC build timestamp. BuildVersionHud (bottom-right, 10 pt, 50% alpha) shows v{semver}+{shortSha} on every screen, with persisted ON/OFF toggle (default ON). Main-menu AboutPanel shows full version + SHA + build timestamp + Unity version + repo URL + credits.SETTINGS_REGISTRY.md enumerates every user-tunable setting with PlayerPrefs key + default + consumer; SettingsPersistenceAuditTests.cs round-trips each. (b) Run-Release-PlayTests.ps1: full EditMode+PlayMode → headless WebGL build (fail on warning) → temp HTTP server + headless-browser smoke (READY ≤ 30 s) → M10 perf gate → git tag v$(Semver)-$(GitSha) + release-notes skeleton on success.