It all started with this Feedback Friday reply from /u/jaggygames, where he made a GIF to convey an excellent suggestion about preserving forward momentum during laneshifting:
So we implemented it on Oct 4th:
The previous implementation was a pretty crude anchoring system, detailed here in an older post. Things tend to go awry if the player ends up in-between lanes, or tiles, at the precise moment they rotate or laneshift. The new implementation prevents those issues while still fluidly preserving forward movement, it wasn’t even difficult to do!
Next we got some some insightful feedback from /u/IanMorrison about our camera’s frame-of-reference change during rotations. Although Ian didn’t explicitly mention smoothing out rotation mechanics, our internal conversations about Ian’s feedback concluded with the idea that although Ian’s feedback still needs to be addressed, one of the main causes could be the stop in movement during rotation, much like laneshifting. So then we said “Hey why not apply similar changes to rotation? Have the player lerp to the ‘next’ subtile smoothly!”.
Holy fucknuts that was far more difficult than laneshifting. But before I dive into that, here are the final results, finished and merged in at 3AM ET this Sunday morning:
The gist of it is, it was fairly complex to get a reference for the “next” Subtile. Each “Tile” consists of a 3×3 grid of Subtiles, each with their own NSEW boolean flags telling us which way the player can move (these are automagically set by our custom editor tool MazeGen). To be honest, trying to emulate autorunning mechanics in an omni-directional 3D environment was pretty uncharted territory for us. We didn’t have any systems in place to find out what the “next” Tile was, so I made one. Frankly, if you’re interested in the nitty-gritty technical details of this implementation, you’re better off reading them here since I go into great detail.
Luckily our MazeGen tool already created all of our Tiles in a pre-set order pre-compile time, so we didn’t have to take the huge performance hit of sorting anything. As I was implementing the systems needed to find the next Tile (and consequently the next Subtile) I realized I failed to foresee a few things in the comment linked above. For example, corner Subtiles are tricky:
For corner Subtiles, there are two ways of potentially “exiting” a Tile via the rotation mechanic, depending on the player’s Y rotation. After I realized this I had to backtrack and correct how I was implementing the systems needed. After that was finished, I just had 2 tasks left:
- Figure out exactly how Subtiles mapped to their neighbors, depending on the player’s current Y rotation (0, 90, 180, 270) and which Subtile we’re “exiting” from
- Decide when to smoothly rotate, accounting for the player’s current Y rotation
Those were pretty easy tasks, relatively speaking. When all was said and done, we ended up with a much smoother movement system. 2 weeks ago I would have said our core gameplay loop felt “pretty good”. Today I’m saying that it was garbage, the new loop is far more satisfying and matches player expectations, and it feels pretty fucking good. Can’t wait to release it for this week’s Feedback Friday!