System Fault Devlog 9

I’m trying a new format for these. With the early access demo released, my goal is to post at least one build per week. These devlogs will conclude with lists of changes broken down by version. I’ll also publish the raw changelog to itch, but without the extra exposition. I’ll do my best to publish additional devlogs, but my priority is fixing bugs and shipping code, not writing stories about the development.

That said, the early access demo certainly had some rough edges.

The biggest of these was the new visibility system. The original System Fault code was written for a turn-based roguelike, where performance and other demands aren’t nearly as high. To determine if a thing was visible, I often checked whether its position was visible rather than the thing itself. This didn’t work for a couple reasons:

  1. If an entity occupied multiple tiles, the position of its center often wasn’t visible because its outer shape obscured the center. For instance, a 1X1 entity at coordinates (14, 0) would obscure the position (14, 0) by virtue of blocking visibility at (13.5, 0).
  2. I wrote several systems to convey visibility with audio and text. A sound icon system plays a specified sound at an entity’s location if it is visible, and a separate system logs its direction and distance. But the sound icon system had a few crucial bugs, and the logging system had a necessary sanity check to not log a thing that rapidly flickered in and out of visibility. Unfortunately, flickering in and out of visibility was exactly what was happening, so the logging system did what it should, with the unfortunate side-effect of obscuring the bug.

So I decided to scrap most of the visibility system. What shipped in the early access demo was version 2. It attempted to model visibility as a collider shape in the physics system. The shadowcaster fed a list of points to a system which calculated a convex hull. Then, whenever a visible entity collided or stopped colliding with the shape, a list of visible entities was updated. This let me switch away from asking if a given pair of coordinates were visible, instead focusing on whether any one given entity could see another. It worked in that respect, but I misunderstood the nature of convex hulls. There were many false positives, including some through walls and other obstructions.

This week’s focus was Visibility V3. It seems far more accurate but slower, and is throttled to 5 updates per second until I either figure out another optimization or create Visibility V4. V3 uses the shapecasting method from V1, essentially casting a grid of roughly 1X1 cuboids onto the tilemap and recording any collisions. I can still check if a given point is visible, but more crucially, each entity that can see its environment tracks a list of every other visible entity it can see, and events are generated each time something appears or disappears. This had the effect of simplifying code, reducing visibility false positives, and uncovering various bugs in systems that needed to track whether or not a given entity could see another.

And as if mostly rewriting visibility wasn’t enough, I also decided that I needed the ability to explore the map accessibly without moving my character around. Fortunately, I had some old and dusty code kicking around from the old roguelike prototype. Unfortunately, it was old and dusty. What shipped in the demo had a number of rough edges where its roguelike roots were very obvious, but it did let me move a cursor around the map square by square, identifying gaps in visibility coverage where there shouldn’t be any, or areas where visibility passed through walls.

The map explorer is now vastly improved over what shipped in the demo. Tiles can be explored square-by-square, and their presentation is more consistent and sensible. Additionally, the map can be explored by individual feature, letting you quickly snap to an enemy or item and seamlessly explore the map around it.

I also spent probably half a dozen or more hours running through the early levels this week, polishing as much as I could. Robot hitboxes are larger–perhaps too large. Explosions and points bonuses were nerfed a bit after one explosive server room battle earned me 20000 or so points in 30 seconds. Lots of numbers were tweaked. Mines were fixed after a recent change caused them to not do any damage. Powerups spawn less frequently, and the spawn tables were tweaked to distribute things a bit less generously. See a more complete changelog below.

Last week’s dodgy demo aside, System Fault is getting better and better by the week. In addition to more polish, next week’s goals are to draw up an early access roadmap, and to perhaps release a full early access build alongside the demo.

Changes in version

  • Dropped range of lure grenades.
  • Fix various issues that kept mines from working.
  • Increased robot hitbox size.
  • Increase player projectile speed and range.
  • Correctly tag powerups for exploration by item/feature type.
  • Nerfed explosions. They now cover a larger area but are not instant kills, instead deducting damage based on robot type.
  • Reduced powerup spawns and tweaked ratios.
  • Reduced bonus for rapid kills from 20% to 10%.
  • Increased robot shot accuracy.
  • Take idle hunting robots into account when calculating tension levels.
  • Switch to new, hybrid shadowcast/shapecast model for visibility.
  • Numerous exploration mode fixes.
    • Coordinates are consistently truncated so directions make sense.
    • When exploring by feature, only select features that are either visible are explicitly marked explorable.
    • Fix issue where navigating to the next feature got stuck on the current one.
    • When the exploration pointer lands on a feature, try more aggressively to discover its name.
    • Fix incorrect keybinding to select previous item type for filtering.