← All devlog posts

Earfh

Nine months of silence

One parse error in December 2025 kept Earfh from booting until September 2026. The repair took a night, and within a day of the game running again it surfaced two crashes that nine months of not booting had hidden.

On December 8, 2025, a commit called "Make Logger accessible as static singleton" added nine docstrings to Logger.gd. They were Python style, indented with spaces, in a file that used tabs. GDScript rejected the whole file. Every logging call in the project resolved against a stub, all six autoloads failed to instantiate, and the game stopped starting.

That commit arrived through a pull request meant to investigate a launch error. A second pull request the same evening tried to fix the indentation in Logger.gd. Neither brought the project back, because the parse error was masking three more faults beneath it, and nothing under a parse error can be observed.

Then the log goes quiet. After December 8 the next commit is dated September 17, 2026.

The repair

The repair commit landed a few minutes after midnight on September 17. It moved the project to Godot 4.6 and lists the faults in the order they became visible.

  • The docstrings became ## doc comments, and the doubled tabs were normalized.
  • Godot 4.6 ships a native Logger class, so class_name Logger was now illegal. The class became EarfhLog across 14 files and 62 references.
  • The old class name also collided with an autoload of the same name. That fault predated the outage and had been masked by the parse error the whole time.
  • ParticleManager was written and called as a singleton, but had never been registered as one.

A headless run confirmed all seven autoloads loaded. What remained was 24 audio files already known to be missing, plus three older issues that a second commit cleaned up eleven minutes later: a duplicated Projectile class, a main scene still pointed at the brick test level instead of the main menu, and a muzzle flash animation called on the player's body sprite once per frame. After that, the headless run showed zero errors.

What the outage hid

Booting was the easy half. The open question was what nine months of not booting had kept out of view, and it answered itself before the day was out.

BroMagnon.gd called ParticleManager.spawn_effect at three sites and AnimationQueue.gd called it at one, each passing a value from a ParticleManager.EffectType enum. Neither the function nor the enum existed. Every hit, every death and every queued effect would have crashed the game. No amount of reading the error log in December could have found it, because it only fires during play, and nothing had played since.

Fixing that exposed a second fault under the first. The muzzle flash and impact particle spawners assigned a Vector3 to CPUParticles2D.direction, which takes a Vector2. That is the 3D particle node's signature, pasted into a 2D script. It had never failed only because it had never been called.

Both were fixed in one commit on the evening of the 17th. The missing enum and a dispatcher went in on top of spawner functions that were already there, and all nine effect types now dispatch cleanly.

The muzzle flash had one more problem. Earlier in the same branch it had been hidden to stop it rendering permanently, which left the game with no muzzle flash at all. Wiring it back meant aiming it along each shot and having it hide itself when its animation finished. That signal only fires if the animation does not loop, so the loop had to go. Left looping, the flash would have stayed on screen after the first shot.

The same commit also gave three enemies their first generated sprites, which is its own story.

A count you cannot take

What the repo's own history file settles on is this. A project that cannot boot accumulates defects invisibly, and the count of them is not knowable until it runs.

Two crashes turned up here, and both sat on the path of the first shot anyone would fire. Zero errors at boot said nothing about either of them. A clean headless run proves the game starts. It says nothing about code that only runs once someone fires. The current state of the game lives on the Earfh page.

← All devlog posts