GameGuide

Bullet Heaven Build Guide

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.


Design decisions this guide follows

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

How to read this guide

Code blocks always say which file they belong to

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

“Find this / Replace with”

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.

Full files at the end of each phase

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.

Code style used everywhere

Editor steps

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

Test checkpoints

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.


Things that are true for the whole project

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

Glossary

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.

Co-op later: the short version

The guide is written for one player, but it avoids choices that would make co-op painful:

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.