Reapers Waltz
Details
Timeline
3 weeks
Genre
2D Horror Puzzle
Tools
The Why
While I was streaming one day, someone hopped into the chat and started talking about a game jam they were working on for the Isekai Horror Jam. Long story short: I didn't finish in time (I joined their team with 4 days left to the deadline), but after the jam I rebuilt the game using Godot. While there are many moving parts to this game, I want to focus on the achievements system because its structually different than the rest of the game.

Achievements
This is game, the player explores the cursed dungeon of an cruel god; to escape they must activate certain events - these also counted as achievements. In order to avoid a tangled web of instance passing around the game's node tree, I decided to use a static class.
class_name Achievements
enum Type {
NONE,
AMULET,
CRUSHING,
DROWNING,
ENEMY,
MUSIC_BOX,
SPIKES,
SWORD,
THE_PIT,
}
static var achievements: Dictionary = {
Type.AMULET: false,
Type.CRUSHING: false,
Type.DROWNING: false,
Type.ENEMY: false,
Type.MUSIC_BOX: false,
Type.SPIKES: false,
Type.SWORD: false,
Type.THE_PIT: false,
}
static var added: Type
static func add(type: Type) -> void:
achievements[type] = true;
added = type
static func all_achieved() -> bool:
for value in achievements.values():
if !value:
return false
return true
The value of added and the functions add(...) and all_achieved() are all called on in different parts of the game, and since the references are static, the whole game will have one source of truth for the achievements. The level exit, the in game HUD, and the achievements menu all rely on this class; since these systems are in very different places (code wise), it is simpler to setup achievements this way.