How datokey/rouge-like-godot works
This repository is a Godot 4 top-down action roguelike prototype built around a clear split between scene-based gameplay objects, data-driven .tres resources, and a small set of autoload singletons that coordinate run state and events.
1. High-level composition
- The main entry point is scenes/Main.tscn.
- Main separates the game into two major branches:
- World: arena, player, enemies, projectiles, pickups, spawner logic.
- UI: HUD, level-up selection, win, and game-over screens.
- This makes the architecture easy to diagram as “core simulation” plus “presentation/UI”.
2. Runtime orchestration via autoloads
- autoload/RunManager.gd controls run lifecycle: start, timer progression, win/lose state.
- autoload/GameState.gd holds shared state like player HP, XP, and run progress.
- autoload/EventBus.gd is the decoupled messaging layer for gameplay/UI communication.
- autoload/Rng.gd centralizes randomness, which is important for reproducible run behavior and weighted drops.
- These are the primary cross-cutting boundaries; most systems talk through them rather than direct node-to-node references.
3. Scene layer: active gameplay entities
- Core runtime actors live in scenes/entities/:
- Player.tscn
- Enemy.tscn, EnemyRunner.tscn, EnemyTank.tscn
- Projectile.tscn
- PickupItem.tscn
- Simpatisan.tscn as an additional entity/minion-type scene
- World infrastructure lives in scenes/world/, especially EnemySpawner.tscn and TestArena.tscn.
- Visual-only feedback is separated into scenes/vfx/ImpactVFX.tscn.
4. Gameplay logic lives in scripts, not scenes
- Most behavior is implemented in scripts/gameplay/.
- Scene files are thin containers; scripts like PlayerController.gd, EnemyController.gd, WeaponManager.gd, EnemySpawner.gd, and Main.gd own the behavior.
- This keeps the visual hierarchy and the simulation logic distinct, which is useful when drawing the architecture: scenes instantiate, scripts decide behavior.
5. Data-driven balancing through resources
- Almost all balance values are stored in resources/ as .tres files, not hardcoded.
- Key resource families:
- resources/actors/: player and enemy stats/config
- resources/weapons/: weapon definitions and variants
- resources/difficulty/: time-based difficulty phases
- resources/items/: pickups and magnet tuning
- resources/projectiles/: projectile tuning
- resources/run/: survival target and next scene target
- resources/xp/: XP curve progression
- resources/feedback/: hit response tuning
- This is a strongly data-driven architecture: code executes the rules, resources define the numbers and variants.
6. Enemy and difficulty progression
- Enemies are configured by EnemyConfig resources and controlled by EnemyController.gd.
- Spawning is handled by EnemySpawner.gd, which consults SpawnerConfig and DifficultyManager.gd.
- Difficulty is time-based, not wave-based: progress is derived from run_elapsed_time / run_target_time.
- Difficulty phases in resources/difficulty/phase_*.tres define multipliers, spawn cadence, max alive enemies, and which enemy scenes can appear.
- In the diagram, this is a pipeline: run time -> difficulty phase -> spawn selection -> enemy stat scaling.
7. Player combat and weapon system
- WeaponManager.gd owns the active weapon(s) for the player.
- Weapons are scene-driven and defined by WeaponDefinition / WeaponConfig resources.
- The repo already contains multiple weapon styles:
- projectile-based (BasicGun)
- beam-based (BeamGun)
- additional prototype weapons like KoalisiDadakan
- Weapons read runtime modifiers and compute stats like damage, cooldown, range, projectile count, and level scaling.
- This is a key boundary: the player does not directly implement attack behavior; weapon scenes encapsulate combat logic.
8. Ability/upgrade subsystem
- Level-up rewards are data-driven through abilities/definitions/*.
- AbilityDefinition describes the upgrade offer, while AbilityEffect describes individual stat effects.
- AbilityPoolConfig.gd and AbilityManager.gd manage offer rolling, stacking, and runtime modifiers.
- AbilitySelectionScreen.gd renders the 3-choice upgrade UI and sends the selected upgrade back through events.
- Abilities modify weapon/player stats indirectly via the manager, so the systems stay decoupled from UI and from individual weapon scripts.
9. Pickups, XP, and magnet behavior
- Enemies drop PickupItem scenes on death.
- XP pickups increase player XP; HP pickups heal; magnet pickups activate a temporary pull effect.
- MagnetConfig.gd controls the pull behavior, but only for hp and xp pickup types.
- The XP system is tied to XPConfig.gd for level thresholds and progression, and level-up triggers the ability-selection flow.
10. Feedback, hit response, and VFX
- Enemy hit reactions are configured by HitFeedbackConfig.gd.
- Damage feedback includes knockback, flash, impact VFX, and hit-stop style feedback.
- ImpactVFX.gd / ImpactVFX.tscn separate purely visual feedback from combat logic.
- This keeps “damage resolution” distinct from “presentation of impact,” which is useful for clean architecture diagrams.
11. UI and state transitions
- PlayerHud.gd listens to gameplay state via EventBus and displays HP, XP, and survival progress.
- GameOverScreen.gd, WinScreen.gd, and StartingWeaponSelectionScreen.gd are separate UI states.
- Win/lose conditions are not handled by UI; they originate in RunManager, which then signals the appropriate screen to show.
- This means UI is mostly reactive, not authoritative.
12. Main data flow to show in a diagram
- Main starts a run through RunManager.
- RunManager initializes GameState and the survival timer.
- PlayerController seeds player stats from config resources.
- EnemySpawner spawns enemies according to DifficultyManager.
- Combat resolves through weapons/projectiles into enemy damage.
- Enemy death generates pickups and feedback.
- Pickups feed XP/HP back into the player.
- Level-up emits an event that opens ability selection.
- UI subscribes to state changes and displays progress, win, or loss.
13. Architectural boundary summary
- Scenes = instantiated gameplay objects and UI views.
- Scripts = behavior and control logic.
- Resources = all tunable game data and content definitions.
- Autoloads = global coordination for state, run lifecycle, RNG, and events.
- That four-part separation is the most important thing to capture when drawing the architecture.
14. What makes this repo distinct
- It is not a generic Godot project; it is structured like a reusable roguelike combat framework.
- The design emphasizes extensibility:
- add a weapon by creating a weapon scene + WeaponDefinition
- add an ability by creating AbilityDefinition + AbilityEffect
- add enemy variety by adding EnemyConfig and including it in phase resources
- The codebase is intentionally organized so most gameplay tuning happens without changing scripts.
Main entry points: RunManager.gd RunManager · EventBus.gd EventBus · TestArena.tscn Arena · Enemy.tscn Enemies
Components 27
Scenes
Instantiated gameplay objects, world setup, and reusable views.
- Main · Root scene that composes world and UI branches.
scenes/Main.tscn - Arena · Primary gameplay space where combat and spawning happen.
scenes/world/TestArena.tscn - Player · Player character instance used in the run.
scenes/entities/Player.tscn - Enemies · Enemy variants instantiated during combat.
scenes/entities/Enemy.tscn - Spawner · Enemy spawning infrastructure in the active world.
scenes/world/EnemySpawner.tscn - Projectile · Projectile instance used by ranged weapons.
scenes/entities/Projectile.tscn - Pickup · Dropped item instance for XP, HP, and magnet effects.
scenes/entities/PickupItem.tscn - Impact VFX · Pure visual feedback for combat impacts.
scenes/vfx/ImpactVFX.tscn
Scripts
Behavior, control logic, and gameplay managers.
- Main logic · Wires scene branches and bootstraps the run.
scripts/gameplay/Main.gd - Player ctrl · Loads player stats and drives player behavior.
scripts/gameplay/PlayerController.gd - Weapon mgr · Owns active weapons and their runtime modifiers.
scripts/gameplay/WeaponManager.gd - Abilities · Upgrade definitions, pools, and runtime selection logic.
abilities/scripts/AbilityManager.gd
Resources
Data-driven tuning, content definitions, and balance tables.
- Weapons · Weapon definitions, configs, and scene-backed variants.
resources/weapons/BasicGun.tres - Enemy config · Enemy stats and variant configuration resources.
resources/actors/enemy_dummy.tres - Difficulty · Time-based difficulty phases and spawn multipliers.
resources/difficulty/default_difficulty.tres - Spawner config · Enemy spawn tuning used by the spawner.
resources/spawners/enemy_spawner_default.tres - Player config · Base player stats and tuning.
resources/actors/player_default.tres - XP config · XP thresholds and level progression tuning.
resources/xp/default_xp.tres - Ability defs · Data-driven level-up offers and stat effects.
abilities/definitions/offense/double_tap.tres
Autoloads
Global run orchestration and shared state.
- RunManager · Starts runs, advances time, and resolves win/lose state.
autoload/RunManager.gd - GameState · Shared runtime state for HP, XP, and progress.
autoload/GameState.gd - EventBus · Decoupled event layer between gameplay and UI.
autoload/EventBus.gd - Rng · Central random source for reproducible gameplay decisions.
autoload/Rng.gd
UI
Reactive screens and HUD presentation.
- HUD · Displays HP, XP, and survival progress.
ui/screens/PlayerHud.tscn - Upgrade UI · Three-choice level-up selection screen.
ui/screens/AbilitySelectionScreen.tscn - Game over · Lose-state presentation.
ui/screens/GameOverScreen.tscn - Win screen · Win-state presentation.
ui/screens/WinScreen.tscn
Connections 29
- Main → Main logic: drives · Main scene is orchestrated by gameplay logic.
- Main logic → RunManager: starts run · Bootstraps survival session lifecycle.
- RunManager → GameState: initializes · Sets shared run state and progress.
- RunManager → EventBus: signals state · Broadcasts run state changes to listeners.
- Main → Arena: contains · World branch hosts combat simulation.
- Main → HUD: contains · UI branch shows reactive player info.
- Arena → Player: spawns · Arena instantiates the player actor.
- Arena → Enemies: spawns · Arena hosts enemy variants.
- Arena → Spawner: contains · Enemy spawning lives in the world.
- Player → Player ctrl: uses · Player scene behavior comes from controller script.
- Player ctrl → Player config: reads · Seeds stats from player tuning resource.
- Player ctrl → Weapon mgr: delegates combat · Player attack behavior is managed separately.
- Weapon mgr → Weapons: loads · Weapons are defined by data resources and scenes.
- Weapon mgr → Projectile: emits · Projectile weapons instantiate projectile scenes.
- Weapon mgr → EventBus: notifies · Weapon and combat events can be broadcast globally.
- Spawner → Spawner config: uses · Spawner tuning comes from resource data.
- Spawner → Difficulty: consults · Spawn cadence and limits depend on difficulty phase.
- Difficulty → Enemy config: selects · Phase resources determine eligible enemy configs.
- Enemies → Enemy config: configured by · Enemy variants are parameterized by actor resources.
- Enemies → Pickup: drops · Enemy death produces pickups.
- Enemies → Impact VFX: triggers · Combat impacts create visual feedback.
- Pickup → EventBus: reports · Pickup collection flows through shared events.
- Pickup → XP config: advances · XP pickups feed progression thresholds.
- Upgrade UI → Abilities: driven by · UI is populated from upgrade manager state.
- Abilities → Ability defs: loads · Ability offers and effects are data-driven.
- Abilities → EventBus: emits offers · Selection flow is broadcast decoupled from UI.
- HUD → EventBus: subscribes · HUD listens to gameplay state changes.
- Game over → RunManager: reacts to · Lose state originates from run manager.
- Win screen → RunManager: reacts to · Win state originates from run manager.