My first full game project with Karta was the Planet Hugo title for the HUGO company. We created a super cool game called Planet Hugo, in which I was one of the core engineers, and still am for the title. One of the systems I created entirely from scratch is the Planet System present in the game. This system underpins the entire experience and was super critical to get working as effectively and efficiently as possible.
When creating this system, we had a couple of options available to us. EgoMoose (A popular math-wizard on Roblox) has a library for handling players walking on objects with different orientations. While this system is super cool and effective, we decided that it may be too much system for our use-case, especially as we wanted this to work well on lower-end devices.
Our solution in the end, was quite unique and ended up working exceptionally well! I decided to pin the player to the top of the planet, and instead, rotate the entire planet underneath the player. Yes, really.
This would provide the illusion of walking around the planet, without having to actually do that. Now, there is a lot of math involved in getting this to work, and that doesn’t even mention that fact that this system does also support multiplayer! Getting multiplayer support to work was by far the most tricky part of this system, but I implemented it in a very interesting way. Essentially, if one anchors the player’s character on the client, then Roblox replication is temporarily disabled for that character. This is crucial because we didn’t want to implement an entire custom character controller for this to work.
For the multiplayer rendering, I simply render the entire planet client-side and then store the orientation of the player’s planet for the client. We then implement a bunch of replication networking on the server and send the new orientation of the planet to every other player. This orientation can then be used to figure out where the player must be standing in order to render that player’s character on the local player’s planet. A whole bunch of complex geometry and angular math later, and we have the above system.
I did run into an issue with gimbal lock however. As we rotate the planet, the issue was that two axes could line up, thus causing weird rotations to happen when you walked to the opposite pole of the planet. We managed to fix this issue by applying the new rotation in world space. Essentially, applying the planet’s current orientation to the new rotation CFrame, rather than applying the rotation to the planet’s current orientation. This took a while to figure out but it ended up working extremely well. Not only this, but the system syncs up with other players extremely well too!
I was quite lucky in a sense, because when I created this system, Roblox had just introduced Unreliable Remote Events, and so I was able to take full advantage of that system to better handle performance on lower-end devices!
The code for this system can be seen below: