Moving platforms reversed velocity whenever |x-startX|>range, which stays true for several frames after the flip, so direction flipped every frame and the platform vibrated in place. Now reverse only when past the edge AND still heading outward. Same directional guard for enemy 'bug' patrol. Added a 6px deadzone to 'mev_bot' so it stops shaking when aligned with the player. Verified: a moving platform now flips ~4x over 360 frames and travels the full range symmetrically.
B1 Seeded RNG + Daily Challenge
- utils/random.js wraps Phaser seedable RND (Between/frac are NOT seedable)
- All gameplay spawning (PlatformManager, Platform, Enemy) uses seeded rng
- GameScene reads mode/seed in init and seeds the run; daily shows a HUD badge
and keeps a per-day best (daily_<YYYYMMDD>); MenuScene DAILY button;
GameOver RETRY preserves mode and shows today's best
- Verified: same seed -> identical layout, different seed -> different
B2 New content
- Enemy mev_bot: homing chaser that eases toward the player (unlock >1500)
- Platform reorg: phantom, semi-transparent, vanishes shortly after landing
(unlock >600); no power-ups on breaking/reorg; SPAWN_RATES + UNLOCK config
- Verified spawn distribution at high difficulty includes all new types
B3 Settings
- SoundManager gains volume (persisted); MenuScene SETTINGS overlay with
volume stepper, particle-quality Low/High toggle, two-step reset progress
B4 Stats
- StatsManager tracks lifetime games/jumps/stomps/blocks/best combo, flushed
at game over; MenuScene STATS overlay; hooks in GameScene/ScoreManager
B5 Difficulty tuning via UNLOCK thresholds and rebalanced spawn rates
Functionally verified in-browser via eval (no console errors, deterministic
daily, content spawns, particles emit). Visual screenshot unavailable in the
headless preview because the hidden tab pauses Phaser's loop.
A1 Pooled particle system
- New ParticleManager owns 9 reusable Phaser emitters created once per scene
(jump, explosion, powerup, puff, sparks, flame, wind, spring, speedline)
- BootScene generates reusable white textures (px_square/soft/streak/ring)
- GameScene burst helpers + EffectsManager flow effects now delegate to the
pool instead of allocating rectangles + tweens every frame
- Quality auto-detect (low on mobile/small screens) cuts particle counts
A2 Fix high-speed landing tunneling
- Cap downward velocity at PHYSICS.maxFallSpeed (boosts unaffected)
- platformCollisionFilter now uses a swept deltaY one-way check so a fast
fall can never be wrongly rejected or passed through
A3 Safe storage
- New utils/storage.js wraps localStorage with in-memory fallback so private
mode / quota errors cannot crash the game; all access routed through it
A4-A6 Lifecycle and robustness
- Global error / unhandledrejection guard recovers to the menu
- GameScene auto-pauses on tab hidden and cleans up the cross-scene listener
on shutdown; fps pacing + disableContextMenu in game config
- Moving platforms use a proper dynamic body instead of destroy()+new Body
Verified in-browser: menu + game load with zero console errors, all emitters
active, normal bouncing works, fall speed capped.
- EffectsManager handles all powerup visual feedback in one place
- Replace circle trail with proper effects per type:
* Rocket: yellow->red flame particles from feet + occasional bright spark
* Propeller: white/blue wind streaks around player
* Spring: gold/green spark trail while ascending fast
- Boost start burst: two expanding rings + radial sparks + camera shake
(orange/gold for rocket, cyan for propeller, green/gold for spring)
- Boost end puff: gray smoke cloud spreading from player
- Screen edge speed lines during boost (alternate left/right edges)
- Player no longer tilts with horizontal input during boost; rocket
stays rigid upright with tiny lean, propeller has gentle sinusoidal wobble
- AchievementsManager with 10 unlockables and toast popups
(Genesis Block, Chain Reaction x3, Bug Hunter, First Flight,
Liftoff, Power Trip, Survivor 500, Skyscraper 1000,
Speedrun 100/60s, Gas Baron 50k)
- Score popups: +N text floats above player on every landing
(gold and larger for genesis platforms)
- Powerup duration bar in HUD bottom, color-coded per power-up,
uses scaleX for smooth depletion animation
- New enemy: Failed Tx, falls from above with sine drift, unlocks
at difficulty > 800, can be stomped, tinted red
- Dynamic background: dark cosmic overlay alpha scales with height
(max 0.5 at very high altitudes)
- Achievement hooks integrated into ScoreManager, GameScene
- Combo no longer resets if combo was already 0 (was triggering log spam)
- Fix Rocket/PropellerHat hitboxes (relative to sprite size, not magic offsets)
- Spring now destroys itself on use with squash animation instead of staying invisible
- Guard all powerups against double-trigger via consumed flag
- Save genesis glow tween reference for clean destroy
- Player.die() disables collisions (no more post-death platform bounces)
- Replace hardcoded enemy spawn cap 0.5 with DIFFICULTY.maxEnemyRate
- Enemy spawn position now anchored to platform X (-60/+60), not random
- Powerup spawn clamped to screen bounds
- Skip powerup spawn on breaking platforms (was unfair)
- ScoreManager.addPoints() public method; remove direct score mutation
- HUD elements use setScrollFactor(0) instead of per-frame repositioning
- All magic numbers extracted to SCORE / PHYSICS / POWERUP_DURATION config
- Remove dead code: showDeathVignette, drawDebug, createParticles, deathOverlay
- Remove dead constants: PLATFORM_WIDTH/HEIGHT, PLAYER_MAX_SPEED, tileBias
- Remove SUBMIT TO CHAIN fake button, replace with Coming Soon text
- Safer cleanup loop: collect-then-destroy instead of mutating during iterate
- gwei particles now have setScrollFactor(0.3) for parallax depth