Files
naddie-jump/src/utils/random.js
AnRil 6f5b4d83f7 Phase B: new content — daily challenge, enemies, platform, settings, stats
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.
2026-05-29 13:29:34 +07:00

46 lines
1.2 KiB
JavaScript

/**
* Thin wrapper over Phaser's seedable RandomDataGenerator (Phaser.Math.RND).
* IMPORTANT: Phaser.Math.Between / FloatBetween use Math.random and are NOT
* seedable — gameplay spawning must use these helpers so a seed fully
* determines a run (Daily Challenge). Cosmetic randomness (particles) may keep
* Math.random.
*/
export const rng = {
seed(value) {
Phaser.Math.RND.sow([String(value)]);
},
/** Random float [0, 1). */
frac() {
return Phaser.Math.RND.frac();
},
/** Integer in [min, max] inclusive. */
between(min, max) {
return Phaser.Math.RND.between(min, max);
},
/** Float in [min, max). */
realBetween(min, max) {
return Phaser.Math.RND.realInRange(min, max);
},
/** Random element of an array. */
pick(arr) {
return Phaser.Math.RND.pick(arr);
},
/** +1 or -1. */
sign() {
return Phaser.Math.RND.frac() < 0.5 ? 1 : -1;
},
};
/** Returns today's date as a YYYY-MM-DD string (local time) for daily seeds. */
export function todaySeed() {
const d = new Date();
const mm = String(d.getMonth() + 1).padStart(2, '0');
const dd = String(d.getDate()).padStart(2, '0');
return `${d.getFullYear()}-${mm}-${dd}`;
}