Skip to content

Archived on 2026-10-24. The Godot rewrite is cancelled. Migration decisions and work checklists below are withdrawn. Original claims, code examples, file paths, and completion statements have not all been revalidated. Use the current documentation and issue register for maintenance decisions.

Godot 4 Architecture Plan

This document is the forward-looking architecture reference for rebuilding Tiny Chaos in Godot 4 with pure typed GDScript.

It belongs under docs/migration/ because it describes the target Godot architecture. The Unity evidence remains under docs/migration/unity-analysis/, and docs/migration/system-redesign-analysis.md explains which Unity systems should be redesigned before implementation.

The Godot project should be created as a separate clean project, not inside the Unity repository. The Unity project remains the reference/archive source for behavior, ids, assets, prefabs, ScriptableObjects, and saves.

1. Migration Goal

Rebuild the game behavior in Godot 4 without translating Unity C# or recreating Unity's spaghetti architecture.

The goal is a clean, maintainable, data-driven Godot project that preserves the player-facing behavior of the Unity game: arena survival combat, character-specific weapons and abilities, enemy waves, bosses, XP and level-up rewards, upgrades, items, HUD feedback, game-over flow, and later progression/platform systems.

The rebuild should be:

  • PC-first for development and testing.
  • Mobile-friendly from the start.
  • Pure GDScript, no C#.
  • Built around reusable scenes, Resources, signals, and small scripts.
  • Focused on PC local play first, especially one or two players using keyboard or gamepad.
  • Designed so player creation can later support 1-4 local players and mobile controls without rewriting the core player system.

Current locked decisions:

  • First balance reference is Soldier / Alex.
  • First stage target is Stage 1.
  • First enemy content target is the Stage 1 enemy set.
  • Stage 1 boss behavior should be included when practical because bosses are enemy specializations with extra tags, UI hooks, and movement/attack state logic.
  • Use exact Unity numbers for the first implementation pass.
  • Reward selection pauses the stage/run state, but reward UI, animations, and feedback must remain responsive and must not conflict with the pause menu.
  • Do not migrate the current shop system as-is. Old shop save values should later be refunded into soul points.
  • Existing Unity save/config data must be migrated later. Current saves are expected to include .dat player data and .json config; the future Godot save target is encrypted JSON.
  • UI should use localization keys from the start because the Unity CSV library can be migrated later.
  • The Godot project must be separate from the Unity repo. Do not mix Godot implementation files into the current Unity project folder.
  • Production abilities and upgrades come from Assets/Resources; content under Assets/Scriptable Object is testing, in-development, need-revamp, draft, or reference unless explicitly promoted.
  • Use regular Stage 1, Stage 2, and Stage 3 content. Do not use Stage 1 new or Stage 3 ZhangYG.
  • Stage assets remain the main source that maps stage/difficulty to creep and special spawner data.
  • Steam is required for PC later; Stove and PlayStore are later platform targets if the game is published there.
  • Steam, leaderboard, achievements, mobile ads, and IAP remain late-phase systems.
  • Player expansion is local-first. Do not design online multiplayer architecture now.
  • Character-specific progression remains conceptual and should not block the first implementation.
  • The Unity fullscreen startup freeze is kept only as a reminder of an old Unity issue unless it reproduces in Godot.

2. Architecture Principles

  • Migrate behavior, not Unity code.
  • Use Unity as a behavior reference only.
  • Do not recreate giant managers.
  • Do not create a giant ability holder.
  • Do not hardcode all abilities in one script.
  • Do not hardcode all upgrades in one script.
  • Use one reusable gameplay scene instead of one full gameplay scene per stage.
  • Prefer Resources for static game data.
  • Use scenes for reusable entities, projectiles, abilities, items, bosses, and UI.
  • Keep UI separate from gameplay logic.
  • Use signals or explicit references for communication.
  • Keep platform-specific systems delayed until core gameplay works.
  • Keep PC local co-op and future mobile performance in mind from the start.
  • Build one vertical slice before migrating broad content.
  • Runtime state must not live in static Resources.
  • Save/progression state should be authoritative for unlocks.
  • When behavior is unclear, record it in a deferred audit or task-plan note instead of guessing.
  • Build the Godot implementation in a separate project. Unity stays as the evidence/source archive.
  • Migrate only needed assets into the new Godot folder structure. Do not copy the Unity folder tree wholesale.
  • Use a curated Godot-ready asset migration pack after Godot scene/resource formats are proven.

3. Target Folder Structure

Recommended initial Godot project structure inside the separate Godot project:

res://autoload/

res://scenes/game/
res://scenes/player/
res://scenes/enemies/
res://scenes/bosses/
res://scenes/abilities/
res://scenes/projectiles/
res://scenes/items/
res://scenes/ui/pages/
res://scenes/ui/components/

res://scripts/game/
res://scripts/player/
res://scripts/enemies/
res://scripts/combat/
res://scripts/components/
res://scripts/abilities/
res://scripts/upgrades/
res://scripts/spawning/
res://scripts/stage/
res://scripts/ui/
res://scripts/resources/
res://scripts/save/
res://scripts/audio/

res://data/abilities/
res://data/upgrades/
res://data/enemies/
res://data/characters/
res://data/stages/
res://data/spawn/
res://data/items/

res://art/
res://audio/
res://vfx/

Folder rules:

  • autoload/ contains small global services only.
  • scenes/ contains reusable Godot scenes.
  • scripts/ contains behavior scripts grouped by responsibility.
  • data/ contains static Resource instances and data files.
  • art/, audio/, and vfx/ contain imported assets.

Asset migration boundary:

  • Unity Project: reference only; source of truth for current behavior, ids, assets, prefabs, ScriptableObjects, and saves.
  • Godot Project: separate clean implementation project; no Unity folder noise.
  • Godot Asset Migration Pack: temporary curated package created later from Unity, shaped to match the final Godot folder/resource architecture, then copied into the Godot project.

Future asset pack target:

TinyChaos_GodotAssetPack/
  art/
    characters/
    enemies/
    stages/
    ui/
  audio/
    music/
    sfx/
  vfx/
  data/
    characters/
    enemies/
    abilities/
    upgrades/
    stages/
    spawn/
    items/
  localization/
  legacy_save_aliases/
  migration_manifest.md
  import_notes.md

Asset migration rules:

  • Do not migrate the whole Unity Assets folder.
  • Do not use Unity folder names as the Godot architecture.
  • Do not copy Unity .meta, .prefab, .unity, .cs, .controller, .anim, .mat, URP, plugin, or TextMesh Pro files as active Godot content.
  • Rebuild prefabs as Godot scenes.
  • Convert production Assets/Resources data after Godot Resource formats are known.
  • Use placeholder assets or a tiny real asset sample early to validate scale, pivot, animation format, audio looping, localization keys, and resource structure.
  • Migrate broader assets later through the curated Godot asset migration pack.
  • Keep Assets/Scriptable Object as test/dev/reference unless manually promoted.

4. Core Runtime Flow

  1. SceneLoader starts the app and loads the initial boot/menu scene.
  2. The player selects stage, difficulty, character, and player slot setup.
  3. GameSession stores the selected run configuration.
  4. SceneLoader loads GameScene.tscn.
  5. GameScene initializes core controllers: RunState, StageController, PlayerManager, RewardDirector, UIFlowController, and AudioManager.
  6. StageController loads the selected StageData, applies visuals/music/rules, and starts the timer.
  7. PlayerSpawner creates one or more PlayerEntity scenes from CharacterData and PlayerInputProfile.
  8. SpawnDirector reads immutable spawn schedules and spawns enemies using runtime spawn state.
  9. Combat runs through shared DamageData, HitboxComponent, HurtboxComponent, and HealthComponent.
  10. XP and items notify LevelUpController, PlayerManager, and RewardDirector.
  11. Level-up rewards pause or enter reward state through RunState, show Page_LevelUp, and apply selected UpgradeEffects.
  12. Boss events are coordinated by BossEncounterController.
  13. On win, loss, or timer end, GameOverController builds a summary and asks UIFlowController to show Page_GameOver.
  14. Save/progression updates happen only where enabled for the current phase.
  15. SceneLoader exits the run back to menu or restarts.

5. Main Systems

GameSession

Purpose

Stores the selected run configuration before entering gameplay.

Responsibilities

  • Selected stage id.
  • Difficulty id.
  • Selected character ids.
  • Player slot setup.
  • Optional run modifiers.

Should Not Do

  • Own active gameplay state.
  • Own UI.
  • Apply upgrades.
  • Spawn players or enemies.

Suggested File Path

res://autoload/game_session.gd

Interactions

Read by SceneLoader, StageController, and PlayerSpawner.

Notes from Unity Migration

Preserves the Unity GameSession concept but should remain a small configuration holder, not a gameplay manager.

RunState

Purpose

Owns runtime state flags for the active run.

Responsibilities

  • Pause state.
  • Reward state.
  • Game-over state.
  • Boss-encounter state.
  • Signals when state changes.

Should Not Do

  • Store UI nodes.
  • Roll rewards.
  • Spawn enemies.
  • Save progression.

Suggested File Path

res://scripts/game/run_state.gd

Interactions

Used by StageController, RewardDirector, UIFlowController, SpawnDirector, and player/enemy systems that need pause awareness.

Notes from Unity Migration

Replaces scattered GameManager.isPaused, GameStateService, reward flags, and game-over flags with one explicit state owner.

SceneLoader

Purpose

Controls scene transitions and loading screens.

Responsibilities

  • Boot scene flow.
  • Main menu to game scene transition.
  • Run exit/restart.
  • Loading state.

Should Not Do

  • Own gameplay rules.
  • Store run state.
  • Apply stage data.

Suggested File Path

res://autoload/scene_loader.gd

Interactions

Reads GameSession, loads GameScene, and notifies UI of loading progress.

Notes from Unity Migration

Replaces Unity scene-loading and fullscreen/startup assumptions with explicit Godot loading flow. The Unity fullscreen startup freeze is tracked as Unity-specific unless reproduced in Godot.

StageController

Purpose

Loads and runs the selected stage.

Responsibilities

  • Load StageData.
  • Apply background, music, duration, and stage settings.
  • Own stage timer.
  • Coordinate SpawnDirector.
  • Request boss encounter start/end.
  • Detect stage completion.

Should Not Do

  • Store enemy runtime flags in StageData.
  • Contain enemy behavior.
  • Own UI presentation.

Suggested File Path

res://scripts/stage/stage_controller.gd

Interactions

Talks to GameSession, RunState, SpawnDirector, BossEncounterController, AudioManager, and UIFlowController.

Notes from Unity Migration

Preserves LevelData, StageMap, durations, music, boss references, and wave timing behavior, but replaces duplicated scene assumptions with one reusable gameplay scene.

SpawnDirector

Purpose

Runs stage spawn schedules.

Responsibilities

  • Read immutable SpawnScheduleData.
  • Track runtime event state.
  • Spawn creep waves, special waves, minibosses, and boss triggers.
  • Emit spawn and clear signals.

Should Not Do

  • Mutate StageData or SpawnScheduleData.
  • Own boss UI.
  • Own enemy behavior.

Suggested File Path

res://scripts/spawning/spawn_director.gd

Interactions

Uses StageController, RunState, PoolService or scene spawning, EnemyEntity, and BossEncounterController.

Notes from Unity Migration

Fixes the Unity risk where SpawnerData stores runtime isSpawning and isActive flags. Special/miniboss suppression should be explicit runtime state.

BossEncounterController

Purpose

Coordinates boss encounter presentation and lifecycle.

Responsibilities

  • Start boss encounter.
  • Spawn boss scene.
  • Lock/unlock camera if needed.
  • Show/hide boss HUD.
  • Switch music.
  • End encounter and notify stage flow.

Should Not Do

  • Implement boss attacks.
  • Contain boss-specific behavior logic.
  • Own stage schedules.

Suggested File Path

res://scripts/enemies/boss_encounter_controller.gd

Interactions

Talks to StageController, SpawnDirector, RunState, AudioManager, UIFlowController, and BossEntity.

Notes from Unity Migration

Bosses remain enemy specializations. Boss scripts such as SAGoblinKing, SAHydra, and SAMinotaur map to boss-specific state/mechanic behavior, not encounter orchestration.

PlayerManager

Purpose

Owns active player slots and player registry.

Responsibilities

  • Track active player slots.
  • Register/unregister spawned players.
  • Expose active players to camera, UI, rewards, targeting, and gameplay systems.
  • Support one or two PC local players first while remaining 1-4 player ready.

Should Not Do

  • Hardcode exactly one or two players.
  • Own player movement or weapons.
  • Apply ability behavior directly.

Suggested File Path

res://scripts/player/player_manager.gd

Interactions

Used by PlayerSpawner, StageController, RewardDirector, UIFlowController, camera logic, targeting systems, and save/progression later.

Notes from Unity Migration

Replaces hardcoded Unity player arrays and fixed player-index assumptions. The first target is PC local play with keyboard/gamepad profiles, not a hardcoded mobile-only or single-player-only path.

PlayerSpawner

Purpose

Creates player scenes from selected slot data.

Responsibilities

  • Instantiate Player.tscn.
  • Apply CharacterData.
  • Attach PlayerInputProfile.
  • Assign player id, spawn position, UI slot, and camera target metadata.

Should Not Do

  • Store run state.
  • Own player behavior after spawn.
  • Choose rewards.

Suggested File Path

res://scripts/player/player_spawner.gd

Interactions

Reads GameSession, uses PlayerManager, creates PlayerEntity.

Notes from Unity Migration

Replaces scene-placed player activation and direct character application in Unity.

PlayerEntity

Purpose

Root scene for a playable character.

Responsibilities

  • Coordinate player child components.
  • Hold references to movement, stats, health, weapon, ability, collector, and targeting components.
  • Emit high-level player events.

Should Not Do

  • Become a giant player script.
  • Store all ability logic.
  • Directly control UI pages.

Suggested File Path

res://scripts/player/player_entity.gd

Interactions

Owns PlayerStats, HealthComponent, weapon controller, AbilityRunner, collector, and input adapter.

Notes from Unity Migration

Splits Unity Player, PlayerModifier, PlayerWeapon, PlayerCollectItem, and AbilityHolder responsibilities into smaller components.

PlayerStats

Purpose

Calculates player final stats from base data and runtime modifiers.

Responsibilities

  • Load base stats from CharacterData.
  • Apply upgrades, temporary buffs, ability modifiers, and later progression modifiers.
  • Recalculate only when dirty.
  • Emit stat-changed signals.

Should Not Do

  • Poll every frame without need.
  • Apply upgrade selection logic.
  • Contain ability behavior.

Suggested File Path

res://scripts/player/player_stats.gd

Interactions

Used by player movement, weapon controller, health, abilities, UI, and upgrade effects.

Notes from Unity Migration

Preserves Unity character stats and PlayerModifier behavior but avoids per-frame recalculation and direct ability checks where possible.

EnemyEntity

Purpose

Root scene for enemies.

Responsibilities

  • Coordinate enemy health, stats, state machine, targeting, reward dropper, and crowd-control components.
  • Expose enemy type/id to spawn and reward systems.

Should Not Do

  • Become one script per enemy.
  • Own all enemy attacks in one class.
  • Use broad scene scans in hot paths.

Suggested File Path

res://scripts/enemies/enemy_entity.gd

Interactions

Uses EnemyStats, HealthComponent, EnemyStateMachine, targeting, RewardDropper, and combat components.

Notes from Unity Migration

Preserves the prefab/scene state-composition model from Unity. Enemy behavior should be assembled from reusable states/mechanics.

EnemyStats

Purpose

Stores and calculates enemy runtime stats.

Responsibilities

  • Load EnemyData.
  • Apply difficulty modifiers.
  • Track runtime stat changes.

Should Not Do

  • Own state machine behavior.
  • Own reward dropping.
  • Own UI.

Suggested File Path

res://scripts/enemies/enemy_stats.gd

Interactions

Used by EnemyEntity, HealthComponent, state/mechanic nodes, and reward systems.

Notes from Unity Migration

Preserves Unity enemy health/damage/difficulty scaling while separating it from the large Enemy script.

EntityCore

Purpose

Shared entity concept for player, enemy, and boss scenes.

Responsibilities

  • Common entity identity.
  • Health/death/status composition.
  • Shared hit feedback hooks.

Should Not Do

  • Force all behavior into inheritance.
  • Know about player input or enemy AI.
  • Know about UI presentation.

Suggested File Path

res://scripts/components/entity_core.gd

Interactions

Owned by PlayerEntity, EnemyEntity, and BossEntity.

Notes from Unity Migration

Keeps the useful Unity Entity parent concept, but moves responsibilities into components instead of large child scripts.

HealthComponent

Purpose

Owns health, damage intake, healing, death, and related signals.

Responsibilities

  • Current/max health.
  • Apply damage from DamageData.
  • Apply healing.
  • Emit damaged, healed, died signals.

Should Not Do

  • Directly update UI.
  • Directly spawn rewards.
  • Contain ability-specific branches.

Suggested File Path

res://scripts/components/health_component.gd

Interactions

Receives damage from HurtboxComponent, notifies EntityCore, abilities, UI adapters, and reward/drop logic.

Notes from Unity Migration

Replaces large damage sections in Player.TakeDamage and Enemy.TakeDamage with a shared damage pipeline.

HitboxComponent

Purpose

Describes outgoing damage from attacks, projectiles, and hazards.

Responsibilities

  • Hold or build DamageData.
  • Detect hurtboxes.
  • Send damage to valid targets.

Should Not Do

  • Own health.
  • Apply upgrades directly.
  • Contain enemy/player-specific global logic.

Suggested File Path

res://scripts/combat/hitbox_component.gd

Interactions

Used by projectiles, melee areas, enemy attacks, ability effects, and hazards.

Notes from Unity Migration

Replaces Unity projectile flags with explicit damage/effect data.

HurtboxComponent

Purpose

Receives hits and forwards damage to the owning entity.

Responsibilities

  • Detect incoming hitboxes.
  • Validate target rules.
  • Forward DamageData to HealthComponent or damage pipeline.

Should Not Do

  • Own attack logic.
  • Own UI.
  • Apply reward logic.

Suggested File Path

res://scripts/combat/hurtbox_component.gd

Interactions

Attached to player/enemy/boss scenes and connected to HealthComponent.

Notes from Unity Migration

Makes player/enemy damage receiving consistent.

DamageData

Purpose

Carries damage metadata through the combat pipeline.

Responsibilities

  • Damage amount.
  • Source entity.
  • Tags and damage type.
  • Crit info.
  • Knockback data.
  • Status/effect tags.
  • Ability or weapon source id if needed.

Should Not Do

  • Apply itself globally.
  • Know about UI.
  • Store long-lived runtime state.

Suggested File Path

res://scripts/combat/damage_data.gd

Interactions

Built by weapons, abilities, enemy attacks, and projectiles; consumed by hitboxes, hurtboxes, health, and effects.

Notes from Unity Migration

Replaces many booleans copied into PlayerAttack with one explicit context object.

Projectile

Purpose

Reusable projectile scene/controller.

Responsibilities

  • Movement.
  • Lifetime.
  • Hitbox setup.
  • Optional pierce/bounce/split hooks.
  • Pool return or cleanup.

Should Not Do

  • Contain all ability-specific projectile behavior.
  • Know about reward or UI.

Suggested File Path

res://scripts/combat/projectile.gd

Interactions

Created by weapons, abilities, and enemy attacks; uses HitboxComponent and DamageData.

Notes from Unity Migration

Preserves projectile behaviors from PlayerAttack and PlayerAttackCarrier, but moves ability-specific effects into behavior/effect modules.

EnemyAttack

Purpose

Reusable enemy attack behavior/state node.

Responsibilities

  • Execute one enemy attack pattern.
  • Spawn enemy projectile or hitbox.
  • Signal attack completion.

Should Not Do

  • Own full enemy AI.
  • Own boss encounter flow.
  • Own player health directly.

Suggested File Path

res://scripts/enemies/enemy_attack.gd

Interactions

Used by EnemyStateMachine, EnemyEntity, and boss/enemy attack states.

Notes from Unity Migration

Preserves prefab-attached attack-state composition rather than one script per enemy.

AbilityRegistry

Purpose

Central lookup for available ability definitions.

Responsibilities

  • Map ability id to AbilityData.
  • Validate ability ids.
  • Expose ability data to player/upgrade systems.

Should Not Do

  • Track per-player cooldowns.
  • Execute ability behavior.
  • Know UI state.

Suggested File Path

res://autoload/ability_registry.gd

Interactions

Used by AbilityRunner, UpgradeEffect, content loaders, and UI.

Notes from Unity Migration

Replaces enum/search-heavy Unity ability lookup with stable id lookup.

AbilityData

Purpose

Static Resource definition for an ability.

Responsibilities

  • Ability id.
  • Display/localization keys.
  • Icon.
  • Base cooldown and stamina cost.
  • Tags.
  • Scaling references.
  • Behavior scene/script reference if needed.

Should Not Do

  • Store runtime cooldown.
  • Store current stacks.
  • Know which player owns it.

Suggested File Path

res://scripts/resources/ability_data.gd

Interactions

Loaded by AbilityRegistry, instantiated as AbilityInstance.

Notes from Unity Migration

Fixes Unity Ability ScriptableObjects storing isOnCooldown and currentCooldownTime.

AbilityInstance

Purpose

Per-owner runtime state for an ability.

Responsibilities

  • Owner reference.
  • Level.
  • Current cooldown.
  • Stacks/counters.
  • Modified stats.
  • Active state.

Should Not Do

  • Store static display data.
  • Execute complex behavior by itself.

Suggested File Path

res://scripts/abilities/ability_instance.gd

Interactions

Owned by AbilityRunner, uses AbilityData, passed to AbilityBehavior.

Notes from Unity Migration

Splits Unity ability data from runtime cooldown/player state.

AbilityRunner

Purpose

Runtime controller for a player's active abilities.

Responsibilities

  • Own AbilityInstances.
  • Track cooldowns.
  • Receive trigger events.
  • Request activation from AbilityBehavior.
  • Emit ability UI signals.

Should Not Do

  • Contain ability-specific methods.
  • Hardcode every ability.
  • Apply upgrades directly.

Suggested File Path

res://scripts/abilities/ability_runner.gd

Interactions

Owned by PlayerEntity; talks to AbilityRegistry, AbilityBehavior, PlayerStats, combat systems, and UI adapters.

Notes from Unity Migration

Direct replacement for the useful runtime parts of AbilityHolder and AbilityFunction, without becoming another giant holder.

AbilityBehavior

Purpose

Executes ability-specific behavior.

Responsibilities

  • Implement one complex ability or reusable ability family.
  • Respond to activation context.
  • Spawn projectiles/effects/summons or modify runtime state through explicit APIs.

Should Not Do

  • Own all abilities.
  • Store global player state.
  • Directly control reward UI.

Suggested File Path

res://scripts/abilities/behaviors/

Interactions

Called by AbilityRunner, uses combat/spawn/audio/feedback services as needed.

Notes from Unity Migration

Each ability should move out of Unity's AbilityHolder into its own behavior or reusable behavior family.

UpgradeData

Purpose

Static Resource definition for an upgrade.

Responsibilities

  • Upgrade id.
  • Display/localization keys.
  • Icon.
  • Rarity.
  • Tags.
  • Max level/times taken.
  • Requirements.
  • List of UpgradeEffects.

Should Not Do

  • Store current times taken.
  • Apply behavior directly.
  • Store save unlock authority.

Suggested File Path

res://scripts/resources/upgrade_data.gd

Interactions

Used by UpgradePool, RewardDirector, and UI.

Notes from Unity Migration

Replaces Unity Upgrade assets with static data only.

UpgradeEffect

Purpose

Applies one upgrade effect.

Responsibilities

  • Modify player stats.
  • Unlock ability.
  • Modify ability instance.
  • Start evolution condition.
  • Spawn companion or apply run-state effect when needed.

Should Not Do

  • Become one giant switch.
  • Own reward choice UI.
  • Mutate static upgrade data.

Suggested File Path

res://scripts/upgrades/effects/

Interactions

Called by RewardDirector or upgrade applier with a context containing player/run/ability data.

Notes from Unity Migration

Replaces UpgradeFunction.SelectUpgrade.

UpgradePool

Purpose

Selects eligible upgrades for rewards.

Responsibilities

  • Filter by character, stage, current abilities, requirements, rarity, and max count.
  • Apply weight/luck rules.
  • Return choices without duplicates.

Should Not Do

  • Animate UI.
  • Apply selected effects.
  • Store UI button state.

Suggested File Path

res://scripts/upgrades/upgrade_pool.gd

Interactions

Used by RewardDirector and LevelUpController.

Notes from Unity Migration

Keeps Unity reward pool concepts while separating them from card UI animation.

LevelUpController

Purpose

Tracks XP and level-up reward triggers.

Responsibilities

  • Track XP/level thresholds.
  • Receive XP pickups.
  • Request reward choices on level-up.

Should Not Do

  • Own reward card UI.
  • Apply all upgrade effects.
  • Contain ability-specific level-up behavior directly.

Suggested File Path

res://scripts/upgrades/level_up_controller.gd

Interactions

Talks to PlayerManager, RewardDirector, UpgradePool, and RunState.

Notes from Unity Migration

Preserves Unity PlayerManager XP/level concept while moving ability side effects elsewhere.

RewardDirector

Purpose

Owns reward queue, selection lifecycle, and reward application.

Responsibilities

  • Queue level-up, special, and boss rewards.
  • Ask UpgradePool for choices.
  • Set/clear reward state through RunState.
  • Apply selected UpgradeEffects.

Should Not Do

  • Instantiate UI cards directly.
  • Animate reward UI.
  • Store player UI markers.

Suggested File Path

res://scripts/upgrades/reward_director.gd

Interactions

Talks to RunState, UpgradePool, UIFlowController, PlayerManager, and upgrade effects.

Notes from Unity Migration

Splits Unity RewardRoller into reward logic and UI presentation.

UIFlowController

Purpose

Routes UI pages and gameplay UI state.

Responsibilities

  • Show/hide HUD.
  • Show reward page.
  • Show pause/game-over pages.
  • Route user UI selections back to gameplay controllers through signals.

Should Not Do

  • Apply upgrade effects.
  • Spawn enemies.
  • Own run state.

Suggested File Path

res://scripts/ui/ui_flow_controller.gd

Interactions

Talks to RunState, RewardDirector, StageController, PlayerManager, and UI scenes.

Notes from Unity Migration

Replaces GameManager and RewardRoller storing UI references and logic together.

SaveManager

Purpose

Owns save/load behavior once progression is in scope.

Responsibilities

  • Load save data.
  • Save progression state.
  • Version save data.
  • Later migrate/import data if required.

Should Not Do

  • Call Steam/mobile platform APIs directly.
  • Mutate static Resources as source of truth.
  • Block first gameplay slice.

Suggested File Path

res://scripts/save/save_manager.gd

Interactions

Talks to progression services, GameSession, and platform adapter later.

Notes from Unity Migration

Preserves useful save model concepts but delays full implementation. Current Unity shop is skipped/replaced by character-specific progression later.

AudioManager

Purpose

Owns music, SFX, footstep categories, and anti-stacking playback rules.

Responsibilities

  • Play music.
  • Play SFX.
  • Manage bus/category volume.
  • Avoid sound spam through cooldown keys.

Should Not Do

  • Store gameplay state.
  • Own visual feedback.
  • Directly decide reward/game-over flow.

Suggested File Path

res://autoload/audio_manager.gd

Interactions

Used by stage, UI, abilities, combat, feedback, and boss encounter systems.

Notes from Unity Migration

Preserves Unity AudioService categories and anti-stacking behavior while removing scattered direct clip dependencies.

6. Scene Structure

Reusable scene plan:

GameScene.tscn
- RunState
- StageController
- SpawnDirector
- BossEncounterController
- PlayerManager
- PlayerSpawner
- RewardDirector
- LevelUpController
- UI root
- gameplay roots

Player.tscn
- PlayerEntity
- EntityCore
- HealthComponent
- HurtboxComponent
- PlayerStats
- movement/input components
- weapon controller
- AbilityRunner
- collector/target sensor

EnemyBase.tscn
- EnemyEntity
- EntityCore
- EnemyStats
- HealthComponent
- HurtboxComponent
- EnemyStateMachine
- RewardDropper

BossBase.tscn
- BossEntity
- EnemyEntity-compatible components
- boss state/mechanic nodes

ProjectileBase.tscn
- Projectile
- HitboxComponent
- visuals/collision

ItemDrop.tscn
- collectible behavior
- magnet/collection area

Page_GameHUD.tscn
Page_LevelUp.tscn
Page_GameOver.tscn

Rules:

  • Scene owns visuals and node composition.
  • Script owns behavior.
  • Resource owns static data.
  • UI scene owns presentation, not core gameplay.
  • Runtime state is not stored in Resources.
  • Save/progression is authoritative for unlocks.
  • Enemy behavior should be composed through enemy scene states/mechanics, not one script per enemy.

7. Data Resource Plan

Recommended Resources and data files:

Resource Purpose Location
CharacterData Character id, name keys, base stats, starting weapon, default ability, portrait/icon refs res://data/characters/
AbilityData Ability id, display keys, icon, cooldown, stamina, tags, scaling, behavior reference res://data/abilities/
UpgradeData Upgrade id, rarity, requirements, max count, weight, effects res://data/upgrades/
UpgradeEffect Modular effect resource or script-backed resource res://data/upgrades/effects/ or res://scripts/upgrades/effects/
EnemyData Enemy id, type, stats, rewards, resistances, scene ref res://data/enemies/
BossData Boss id, scene, music, icon, phase/encounter metadata res://data/enemies/bosses/
StageData Stage id, name, background, music, duration, boss, spawn schedules, mechanics res://data/stages/
SpawnScheduleData Immutable wave/special/boss trigger timing res://data/spawn/
ItemData Item id, pickup behavior, value, icon/scene refs res://data/items/
AchievementData Later achievement id, rule/reward metadata later
Character progression data Later character-specific progression replacing current shop later

Resource rules:

  • Resources are static definitions.
  • Runtime state lives in runtime objects such as AbilityInstance, spawn runtime state, player state, and upgrade run state.
  • Unlocks and progression live in save/progression state.
  • If data is unclear, record it in the implementation task plan or a focused audit note before migrating that content.

8. Ability System Architecture

The ability system must avoid the Unity pattern where one holder contains every ability method.

Core parts:

AbilityRegistry
- central lookup for AbilityData

AbilityData
- static Resource definition

AbilityInstance
- per-player runtime state

AbilityRunner
- per-player runtime controller
- handles cooldowns and trigger routing
- no ability-specific logic

AbilityBehavior
- one script/scene per complex ability or reusable behavior family

Activation model:

  • AbilityRunner receives gameplay events such as input, dash, fire, hit, kill, damage taken, timer tick, level-up, pickup, and boss start.
  • It checks owned AbilityInstances and cooldowns.
  • It calls the associated AbilityBehavior with an activation context.
  • The behavior uses explicit APIs to spawn projectiles/effects, modify stats, add shields, or request feedback.
  • UI listens to AbilityRunner signals for cooldown/active state.

Adding a new ability should require:

  1. Create an AbilityData resource.
  2. Create or reuse an AbilityBehavior.
  3. Register the ability id in AbilityRegistry.
  4. Add the ability to character data, upgrade data, or progression data.
  5. Connect it to the appropriate trigger type.

It must not require editing a giant ability manager.

9. Upgrade System Architecture

The upgrade system must avoid one giant hardcoded upgrade script.

Core parts:

UpgradeData
- static upgrade definition

UpgradeEffect
- modular effect applier

UpgradePool
- eligibility and weighted choice selection

LevelUpController
- XP and level-up triggers

RewardDirector
- reward queue and selected reward application

Upgrade categories:

  • General stat upgrades.
  • Ability unlock upgrades.
  • Ability modifier upgrades.
  • Character-specific upgrades.
  • Stage/boss/special upgrades.
  • Evolution upgrades.

Adding a new upgrade should require:

  1. Create an UpgradeData resource.
  2. Assign one or more UpgradeEffects.
  3. Add requirements/tags/pool rules.
  4. Add it to the appropriate data pool.

It must not require editing a single giant switch.

The Unity shop should not be migrated as-is. Future permanent progression should be character-specific and designed after the core loop is stable.

10. Stage System Architecture

Godot should use one reusable gameplay scene.

GameScene
- reusable gameplay root

StageData
- static stage definition

StageController
- applies selected stage
- owns stage timer/state

SpawnDirector
- runs spawn schedules

BossEncounterController
- boss presentation/transition

StageMechanic
- optional modular stage-specific behavior

StageData should include:

  • Stage id and name.
  • Background/visual refs.
  • Music.
  • Duration.
  • Difficulty modifiers.
  • Enemy pool refs.
  • Spawn schedules.
  • Boss rules.
  • Environmental props.
  • Optional stage mechanic refs.

The goal is no duplicated full gameplay scene per stage. Stage-specific behavior should be modular and data-driven where practical.

11. Combat Architecture

Combat should use shared components:

HealthComponent
HitboxComponent
HurtboxComponent
DamageData
Projectile
EnemyAttack

Rules:

  • Health should not know about UI directly.
  • Hitbox should only describe outgoing damage and contact rules.
  • Hurtbox should receive hits and forward damage.
  • DamageData should carry damage amount, source, tags, knockback, crit info, and status/effect metadata.
  • Projectiles should be reusable scenes.
  • Enemy and player damage should use the same base system where practical.
  • Ability-specific damage behavior should be implemented as hit effects, damage tags, or ability behavior modules.
  • The order of shields, reductions, lethal prevention, and death should be documented when implemented.

12. UI Flow Architecture

UI observes gameplay and emits user intent.

Recommended UI systems:

UIFlowController
HUDController
RewardUIController
PauseMenuController
GameOverView
FeedbackLayer

Rules:

  • UI should not apply upgrade effects directly.
  • Reward UI emits selected upgrade/player ids to RewardDirector.
  • HUD observes player/run signals.
  • Game-over UI receives a summary object.
  • Pause UI requests state changes through RunState or a controller.
  • UI scenes should not store core gameplay references beyond explicit controllers/adapters.

13. Save, Progression, and Platform Systems

Save and platform systems should be delayed until the core gameplay loop is stable, but save migration is required later.

Early plan:

  • Use minimal save only if needed for settings or development.
  • Do not import Unity saves in the first vertical slice.
  • Preserve ids and data mapping needed for later Unity save migration.
  • Keep progression state separate from Resources.
  • Current Unity shop is delayed/replaced by character-specific progression.
  • Old shop save values should later be refunded into soul points.
  • Achievements are delayed until core loop and ids are stable.
  • Steam, leaderboard, mobile ads, IAP, and platform services are delayed.

Later plan:

SaveManager
ProgressionState
AchievementService
CharacterProgressionService
PlatformAdapter
LeaderboardService

Platform code should sit behind adapters so PC and mobile targets can diverge without changing core gameplay.

14. Mobile-Friendly Notes

The first implementation target is PC local play, but the architecture must not block later mobile controls.

  • Build the first slice around one or two PC local players while keeping player slots 1-4 ready.
  • Keep input behind PlayerInputProfile.
  • Support keyboard and gamepad profiles for the PC slice.
  • Do not define the final mobile control layout in this architecture document.
  • Keep scripts small and avoid heavy _process loops.
  • Avoid scene-wide searches in hot paths.
  • Use spawn/remove registries for targeting where possible.
  • Use pooled scenes for projectiles, enemies, items, effects, and popups.
  • Add explicit caps for high-volume feedback.
  • Keep UI and input routing capable of adding touch screens later.
  • Avoid platform systems in core gameplay.
  • Keep one reusable gameplay scene to reduce scene duplication and mobile maintenance cost.

15. First Vertical Slice

The first playable target:

  • One reusable gameplay scene.
  • Stage 1 as the first StageData.
  • Soldier / Alex as the first balance-reference character.
  • One PC local player spawned through PlayerManager and PlayerSpawner, then validate the second local player path before broad content migration.
  • Keyboard profiles for WASD and arrow-key players, plus gamepad-ready input profile routing.
  • Stage 1 enemy scenes using state composition.
  • Stage 1 boss if the full Stage 1 loop is in scope for the slice.
  • One basic weapon or projectile.
  • One damage path using HitboxComponent, HurtboxComponent, and HealthComponent.
  • One basic ability using AbilityRunner.
  • One XP drop.
  • One level-up reward.
  • One upgrade effect.
  • Basic HUD.
  • Game timer.
  • Game over.
  • Exact Unity numbers for character, enemy, stage, damage, and upgrade values used by this slice.
  • Localization keys for any UI text introduced in the slice.

Do not include yet:

  • All characters.
  • All abilities.
  • All upgrades.
  • All stages.
  • Shop.
  • Steam.
  • Leaderboard.
  • Achievements.
  • Full localization polish.
  • Mobile ads.
  • IAP.
  • Full save system.
  • Full UI polish.
  • Final mobile control layout.
  • Full 4-player UI.

16. Migration Phases

Phase 1: Godot Project Foundation

Goal: create project structure, base docs, project settings, and autoload decisions.

Done criteria:

  • Folder structure exists.
  • Architecture docs exist.
  • Pure GDScript rule is established.
  • No gameplay complexity yet.

Phase 2: Core Entity And Combat Slice

Goal: implement EntityCore, health, hitbox/hurtbox, one player, one enemy, and one projectile/damage method.

Done criteria:

  • Player can damage enemy.
  • Enemy can die.
  • Combat uses shared damage path.

Phase 3: Player Creation And Input

Goal: implement PlayerManager, PlayerSpawner, PlayerSlot, and PC local keyboard/gamepad input plus a mobile-ready abstraction.

Done criteria:

  • Player is spawned from data.
  • Input is routed through a profile.
  • No fixed one/two-player assumptions in the spawn path.
  • WASD and arrow-key local profiles can be assigned without hardcoding player objects.

Phase 4: Stage And Spawn Flow

Goal: implement reusable GameScene, StageData, StageController, and SpawnDirector.

Done criteria:

  • Stage 1 loads from data.
  • Timer runs.
  • Stage 1 enemy waves spawn from schedule data.
  • Runtime spawn state is not stored in Resources.

Phase 5: XP, Level Up, And Upgrade System

Goal: implement XP pickup, level-up UI, upgrade choices, and one upgrade effect.

Done criteria:

  • Enemy drops XP.
  • Player levels up.
  • Reward UI shows choices.
  • Selected upgrade applies through UpgradeEffect.

Phase 6: Ability System Expansion

Goal: support multiple ability behaviors without a giant holder.

Done criteria:

  • AbilityRunner owns runtime ability instances.
  • At least two abilities are added without editing a giant ability script.
  • Cooldown UI/state works.

Phase 7: Enemy And Boss Content Migration

Goal: migrate enemy state composition and validate boss-as-enemy architecture.

Done criteria:

  • Multiple enemy scenes use reusable states/mechanics.
  • Stage 1 boss uses enemy-derived behavior if boss content is included in the Stage 1 slice.
  • Boss encounter controller owns UI/camera/music flow.

Phase 8: Content Migration

Goal: migrate characters, abilities, upgrades, enemies, and stages as data/scenes.

Done criteria:

  • Production content is triaged.
  • Data ids are stable.
  • In-development/test content is excluded or flagged.

Phase 9: UI, Save, Audio, Polish

Goal: improve UX, HUD, menus, save/progression, audio, and feedback.

Done criteria:

  • Basic save/progression boundary exists.
  • HUD and game-over are stable.
  • Audio and feedback are routed through services.

Phase 10: Platform And Mobile Preparation

Goal: add Steam, leaderboard, mobile-specific systems, and platform integrations after core gameplay is stable.

Done criteria:

  • Platform adapter exists.
  • PC and mobile platform needs are separated from core gameplay.

17. Codex Implementation Rules

  • Do not implement multiple phases at once.
  • Do not create a giant GameManager.
  • Do not create a giant AbilityHolder.
  • Do not put ability-specific logic inside AbilityRunner.
  • Do not hardcode all upgrades in one script.
  • Do not duplicate one full gameplay scene per stage.
  • Do not let UI directly control core gameplay logic.
  • Do not use C#.
  • Use typed GDScript.
  • Use Resources for data where practical.
  • Use reusable scenes.
  • Use clear signals or references.
  • Keep scripts small.
  • Update documentation when architecture changes.
  • When unsure, record the uncertainty in a focused audit note or task-plan follow-up instead of guessing.

18. Locked Decisions And Deferred Audits

Architecture decisions:

  • Production abilities and upgrades come from Assets/Resources.
  • Assets/Scriptable Object content is testing, in-development, need-revamp, draft, or reference unless explicitly promoted.
  • Use regular Stage 1, Stage 2, and Stage 3 content.
  • Do not use Stage 1 new.
  • Do not use Stage 3 ZhangYG.
  • Stage assets are the main mapping source for stage, difficulty, creep spawner, and special spawner references.
  • Spawner data represents creep waves and special waves, including special enemies, minibosses, and boss triggers.
  • Enemy and boss authoring should preserve prefab/scene state composition.
  • Bosses are enemy-derived variants, not unrelated systems.
  • Old shop save values refund to soul points.
  • Character-specific progression remains conceptual and is not implemented in the first slice.
  • Steam is required for PC later.
  • Stove and PlayStore are later platform targets if the game is published there.
  • Player expansion is local-first; do not design online multiplayer architecture now.
  • The Unity fullscreen startup freeze is a reminder of an old Unity issue, not a Godot gameplay architecture driver.

Save migration facts:

  • Current new player save file is player_v2.json.enc.
  • Current legacy player file is player.dat.
  • Current config file is config.json.
  • PlayerData stores soulPoint, chaosFragment, unlockedChar, unlockedAchievement, unlockedSpecialUpgrade, shopUpgrade, unlockedStage, and totalDataCounter.
  • GameConfig stores volume, graphics, language, damage-indicator, and keybind-preset settings.
  • Character saves use Character.id.
  • Stage saves use StageMap.id.
  • Achievement saves use Achievement.id.
  • Shop saves use ShopUpgrade.type.ToString().
  • Special upgrade unlock saves currently use Upgrade.upgradeName; migration needs an alias map from old upgrade names to stable upgrade ids.

PC platform reference:

  • Current Steam store expectations include single-player, shared/split-screen co-op, Steam achievements, Steam Cloud, Remote Play Together, Family Sharing, and Windows PC support.
  • Steam page reference: https://store.steampowered.com/app/2500680/Tiny_Chaos/.

Deferred audits:

  • Full production ability and upgrade catalog validation.
  • Full enemy and boss prefab/state composition catalog.
  • Stage 1 enemy and boss implementation details.
  • Character-specific progression design.
  • Exact Steam, Stove, and PlayStore implementation requirements.
  • Full save migration test fixtures.

For the detailed execution checklist, use docs/migration/godot-implementation-task-plan.md.

Create or prepare the separate Godot project foundation only:

  • Create the recommended folders in the separate Godot project, not inside the Unity repo.
  • Add empty placeholder docs or README files where helpful.
  • Configure pure GDScript project conventions.
  • Decide minimal autoload list: GameSession, SceneLoader, and later AudioManager / registries as needed.
  • Do not implement gameplay yet.

The first gameplay implementation task after foundation should be the core entity and combat slice: one player, one enemy, health, hitbox, hurtbox, and one damage method. Use Soldier / Alex and Stage 1 data as the first concrete references once gameplay data is needed.

Architecture Risks

  • Recreating GameManager as one central Godot autoload.
  • Recreating AbilityHolder as one large script with every ability method.
  • Recreating UpgradeFunction as one large switch.
  • Putting runtime state inside Resources.
  • Letting UI directly apply gameplay effects.
  • Duplicating full gameplay scenes per stage.
  • Mixing the Godot project into the Unity repo and inheriting Unity folder noise.
  • Hardcoding one or two players and blocking future 1-4 player support.
  • Treating bosses as unrelated to enemies instead of enemy specializations.
  • Losing the enemy prefab/state-composition authoring model.
  • Adding platform, shop, achievement, or leaderboard systems before the core loop is stable.
  • Copying the old Unity folder tree instead of importing only needed assets through a curated Godot-ready asset pack.
  • Pausing reward state with the same path as the pause menu and causing reward-selection soft locks.