Release 3 is scheduled to be completed at the end of this month. I started on this phase five months ago. I’ve completed around 30% of what I planned for this release, due to shifting priorities rather than underestimation. Much of the Release 3 scope consisted of adding – new monsters, new objects, new abilities, new items. Yet, the game wasn’t truly playable; it was buggy, there was no progression, and the main game loop was boring. In response, I stopped adding content and started concentrating on the fundamental experience. I improved game feel. I made combat more tactical. I refined procedural generation to produce more cohesively populated maps. I continuously asked myself what needed to be done to put this game in front of people. The game is now in better shape than it would have been had I stuck to the original Release 3 scope. Key achievements this week:
- Fixed projectile raycasting. I originally implemented Bresenham’s line algorithm to determine the path of a projectile. This algorithm generally worked, but sometimes projectiles would pass right through obstacles, typically corner walls. On multiple occasions I stood waiting for an archer to come to me, thinking I was protected by the wall in between us, only to be shot by an arrow that passed through the wall. It turned out that Bresenham’s line algorithm wasn’t suited for identifying all cells on a grid between two points. This post illustrates the issue. I wrote a new cell traversal algorithm from scratch (I didn’t use the answer from the post) that determines every cell between two cells. The new algorithm fixed the issue.
- Overhauled CellGetter. CellGetter is a utility class for getting cells in a specified pattern, such as adjacent cells, room perimeter cells, room corner cells, etc. It’s used extensively in procedural generation to place Map Elements in appropriate locations. It had become a 1,000 line class because a method was created for every variation of a pattern that was needed. For instance, there were separate methods for filled and unfilled rectangles and room perimeters and borders. I refactored the class by moving the variation to public, read-only C# Funcs that could be chained together as needed (e.g. all cells in a filled rectangle that can have objects placed on them). Then, I consolidated most of the methods into a handful of methods that have Func parameters. This will make it easier to add new Map Elements that place objects in patterns.
I’m still firming up plans for next week. I’ll likely focus on bug fixes and some minor user experience improvements. I also need to continue expanding the Map Elements.