A clean, modular idle → battle pipeline. This post shows what existed, what the battle slice adds, and why the pieces click together without drama.
Pre-Battle Foundation
Before combat, the project already had a solid backbone: a central controller managing UI and input; a modular trio for economy (Purr), progression (Leveling), and attributes (Stats); and a resource loop (Purr Power) pacing bigger moments. UI was dynamic and performance-friendly, with dual live previews and packaged-build fixes in place.
Active & passive gain, growth curves, and upgrade hooks.
XP → Levels → Points, with clean thresholds and pacing.
Long-term values feeding derived combat numbers; player point spend.
Session-bound resource for impactful moments; reset per encounter.
Dynamic lists, two live scene captures, throttled for performance.
The Battle Slice
The slice mounts cleanly on top of that foundation. Encounters start from the main UI, freeze current stats into a per-fight snapshot, alternate turns with readable logs, and award XP on victory.
Start → Player turn ↔ Enemy turn → Auto-battle.
Defined in a table for fast authoring (ID, name, HP, ATK, XP).
Freeze stats at fight start so mid-fight tweaks don’t drift numbers.
Hit/crit/dodge basics, simple mitigation, fair flee checks.
Two HP bars, Attack/Flee, scroll log; buttons enable only on your turn.
Combat broadcasts; UI listens. No tight coupling.
Good Practices & Optimization
Habits that keep it fast, legible, and easy to extend.
Data-first, then visuals
Enemies, upgrades, and long-term stats live in data assets/tables. Balance work and content additions don’t require touching gameplay graphs. Visuals read from data and react to events.
Modularity & separation
Each concern sits in its own module: economy, leveling, stats, and combat. UI doesn’t know how numbers are produced; it just displays what it’s told. Safer changes, easier testing.
Blueprint Interfaces (contracts, not references)
UI talks to gameplay via interface messages (“start fight”, “attack”, “flee”). No hard references, no circular deps, tidier input handling, easy swapping of controller/character shells.
Event Dispatchers (one-way, payloaded)
Gameplay emits simple, one-way events: state changes, HP updates, and log lines. Listeners receive the values they need and update in place. Widgets stay lightweight; no polling.
RNG you can trust (and replay)
A single Random Stream is seeded once per session. All chances (hit, crit, flee) draw from it. For debugging, switch to a fixed seed to reproduce the exact sequence.
- Session seed: random at startup for fresh play; fixed in debug for repeatability.
- From-Stream rolls: use the “from Stream” random nodes so the sequence advances consistently.
- Auditability: log the seed + first few rolls when debugging “impossible” streaks.
Dev Progression (Videos)
Short clips showing the project coming together—from idle foundation to the turn-based slice.
Player Experience
Early upgrades nudge reliability and pace (accuracy, survivability, resource gain). Randomness is seeded once per session for stable testing while still feeling fresh.
Crits and spends create peaks; base loop stays legible.
Simple knobs (HP, ATK, chances, resource flow) for first-hour tuning.
Concise logs, minimal UI, clear turn state.
Changelog
- Sept 4, 2025: Added “Good Practices & Optimization” and “Dev Progression (Videos)” sections.
- Aug 20, 2025: Post fully refreshed; added battle slice details, snapshot model, and clearer flow. New design & meta.
- Aug 5, 2025: Initial prototype notes (idle foundation, previews, and planned combat).