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
.datplayer data and.jsonconfig; 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 underAssets/Scriptable Objectis 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 neworStage 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/, andvfx/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
Assetsfolder. - 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/Resourcesdata 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 Objectas test/dev/reference unless manually promoted.
4. Core Runtime Flow¶
SceneLoaderstarts the app and loads the initial boot/menu scene.- The player selects stage, difficulty, character, and player slot setup.
GameSessionstores the selected run configuration.SceneLoaderloadsGameScene.tscn.GameSceneinitializes core controllers:RunState,StageController,PlayerManager,RewardDirector,UIFlowController, andAudioManager.StageControllerloads the selectedStageData, applies visuals/music/rules, and starts the timer.PlayerSpawnercreates one or morePlayerEntityscenes fromCharacterDataandPlayerInputProfile.SpawnDirectorreads immutable spawn schedules and spawns enemies using runtime spawn state.- Combat runs through shared
DamageData,HitboxComponent,HurtboxComponent, andHealthComponent. - XP and items notify
LevelUpController,PlayerManager, andRewardDirector. - Level-up rewards pause or enter reward state through
RunState, showPage_LevelUp, and apply selectedUpgradeEffects. - Boss events are coordinated by
BossEncounterController. - On win, loss, or timer end,
GameOverControllerbuilds a summary and asksUIFlowControllerto showPage_GameOver. - Save/progression updates happen only where enabled for the current phase.
SceneLoaderexits 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
StageDataorSpawnScheduleData. - 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
DamageDatatoHealthComponentor 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
UpgradePoolfor 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:
AbilityRunnerreceives 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
AbilityBehaviorwith an activation context. - The behavior uses explicit APIs to spawn projectiles/effects, modify stats, add shields, or request feedback.
- UI listens to
AbilityRunnersignals for cooldown/active state.
Adding a new ability should require:
- Create an
AbilityDataresource. - Create or reuse an
AbilityBehavior. - Register the ability id in
AbilityRegistry. - Add the ability to character data, upgrade data, or progression data.
- 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:
- Create an
UpgradeDataresource. - Assign one or more
UpgradeEffects. - Add requirements/tags/pool rules.
- 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.
DamageDatashould 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
RunStateor 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
_processloops. - 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
PlayerManagerandPlayerSpawner, 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, andHealthComponent. - 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:
AbilityRunnerowns 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 Objectcontent 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. PlayerDatastoressoulPoint,chaosFragment,unlockedChar,unlockedAchievement,unlockedSpecialUpgrade,shopUpgrade,unlockedStage, andtotalDataCounter.GameConfigstores 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.
Recommended First Implementation Task¶
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 laterAudioManager/ 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
GameManageras one central Godot autoload. - Recreating
AbilityHolderas one large script with every ability method. - Recreating
UpgradeFunctionas 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.