This guide takes the project from “a capsule that faces the mouse” to a full Swarm-style run: a signature weapon, enemies, XP, level-ups, extra weapons, passives, evolutions, elites, a boss, character abilities, and progress that carries over between runs.
Each phase is its own file. Do them in order, because later phases build on earlier code.
| Phase | File | What you end up with |
|---|---|---|
| 0 | phase-0-cleanup-and-stats.md | Cleaned-up code and a stat system ready for weapons |
| 1 | phase-1-signature-weapon.md | The Gunner shoots bullets at the mouse, with an auto-aim toggle |
| 2 | phase-2-enemies-and-damage.md | Enemies spawn in waves, chase you, hurt you, and die |
| 3 | phase-3-xp-and-level-up.md | XP orbs, level-ups that pause the game with 3 choices, and a HUD |
| 4 | phase-4-weapon-slots-and-weapons.md | 4 extra weapon slots and 3 new weapons that target in different ways |
| 5 | phase-5-evolutions.md | Weapon evolutions unlocked by passives |
| 6 | phase-6-elites-access-cards-boss.md | Elites, Access Cards, mini-bosses, and a boss fight you can win |
| 7 | phase-7-character-kit.md | Innate passive, E ability, and R ultimate |
| 8 | phase-8-meta-progression.md | Gold, permanent upgrades, unlocks, difficulty (outline) |
| 9 | phase-9-extras.md | Pods, augments, boons, map events (outline) |
Phases 8 and 9 are lighter outlines on purpose. By the time you get there your game will have its own shape, so they focus on the approach and the key code rather than every click.
These were agreed before writing the guide. If you change your mind later, the phase that depends on it is listed.
| Decision | Choice | Where it matters |
|---|---|---|
| How evolutions are offered | Only from the free pick when you collect an Access Card (Swarm-style) | Phase 5, 6 |
| Cooldown stat | Called cdr, but uses Ability Haste maths: cooldown = base / (1 + cdr / 100) |
Phase 0, 1 |
| Stat stacking | Percentage stats multiply between sources, flat stats add (Swarm-style) | Phase 0, 7, 8, 9 |
| Who owns a weapon’s level | The Weapon node in the scene. OwnedWeapon is deleted |
Phase 0, 1 |
| Multiplayer | Single-player now, co-op maybe later. The guide adds “Co-op note” boxes where something would need to change | All |
| Auto-aim key | C |
Phase 1 |
Every code block has a File: line above it, using the same res:// path Godot shows in the FileSystem dock. For example:
File: res://scripts/characters/player/player.gd
func example() -> void:
pass
When only part of a file changes, the guide shows a Find this block (what is already in your file) and a Replace with block (what it should become). Copy the whole replacement block, not just the lines you think are new.
Each phase ends with a Full file listings section with the complete version of every script that phase touched. If something goes wrong partway through, compare your file with the listing, or paste the listing over your file.
var speed: float = 5.0, never var speed := 5.0.for loops: for enemy: Enemy in enemies:.When a step says In the Godot editor, it means clicking around in Godot rather than writing code. Scene trees are drawn like this:
Bullet (Area3D) <- root node, its type in brackets
├─ CollisionShape3D
└─ MeshInstance3D
Each phase ends with a Test it section. Don’t move on until that works. Small, tested steps are much easier to debug than one huge change.
Main sits at the world origin (0, 0, 0). Because of that, a node’s position before it is added to Main is the same as its global_position after. The guide uses this in several places when spawning things.main.tscn directly (F6). main.gd needs game_state.selected_level, which is only set by the character select screen.| Layer | Name | Used by |
|---|---|---|
| 1 | world | Floor and walls |
| 2 | player | The player body |
| 3 | enemy | Enemy bodies |
| 4 | interactable | Pickups that get pulled toward you (XP orbs, etc.) |
| 5 | projectile | Bullets, blades, and similar |
| 6 | trigger | Spare, used in Phase 9 |
| Word | Meaning |
|---|---|
| Node | One building block in a scene (a mesh, a timer, a body). |
Scene (.tscn) |
A saved tree of nodes you can create copies of with instantiate(). |
Resource (.tres) |
A saved bundle of data, like WeaponData. Shared and reusable, with no position in the world. |
class_name |
Gives a script a global type name so other scripts can write var w: Weapon or if x is Weapon. |
| Autoload | A script Godot creates once at startup and keeps alive across scene changes (game_state, Profile). |
| Signal | A “this happened” message. Other nodes connect to it and get called when it is emitted. |
| Group | A tag on a node. get_tree().get_nodes_in_group("enemies") finds every node with that tag. |
| Layer / Mask | Layer is “what I am”; mask is “what I look for”. A bullet is on the projectile layer and masks the enemy layer. |
@export |
Shows a variable in the Inspector so you can edit it without code. |
@onready |
Sets the variable just before _ready(), when child nodes exist. |
super() |
Calls the parent class’s version of the function you are overriding. |
| Tween | A tiny animation made in code, such as “shrink this over 0.1 seconds”. |
| Variant | A value that could be any type. Godot uses it when something might be null. |
| Source (of a stat) | One thing that gives a bonus: one passive, one permanent upgrade, one buff, and so on. |
The guide is written for one player, but it avoids choices that would make co-op painful:
"players", and enemies chase the nearest player instead of “the player”.game_state, so they are already shared like in Swarm."players" group.Things that would still need real work for co-op (networking, who picks first on a level-up, and so on) are mentioned in the phase where they come up.