Importance of Symmetry
One of the many joys of roguelike development is getting your ass kicked by your own game! However, in my case some of the deaths to ranged enemies felt like cheating. All I would do is come around the corner and blammo — dead. Was this an example of my own reckless play style? Or an actual bug in the game?
Turns out the problem was with my Field Of View (FOV) algorithm. Since I am using the amazing rot.js library, I had been using the default recursive shadowcasting field of view implementation. After poking around on roguebasin and re-reading Jice’s awesome overview of FOV algorithms, I realized my problem is that my FOV was not symmetrical.
Now, depending on who you ask, symmetrical FOV may or may not matter. In a game with only 3 hit points, every shot counts. While I am loath to ever over-optimize, I felt it would be time well spent. I came across Albert Ford’s implementation of a symmetrical recursive shadowcasting and ended up coding something similar in typescript. The end result is exactly what I wanted.
Before (Non-Symmetrical): This bot can see me, but I can’t see him. Which means as soon as I step over, I’ll be in range and get shot.
After (Symmetrical): Neither of us can see each other. In this case, the bot will move closer to the spot where he last saw me – sacrificing some range and giving me a chance to see him one turn before he can attack.