• Matias Klemola

Hobby project spotlight: “vetovoima”

Here’s the story of how software architect Matias Klemola turned an abstract idea into an arcade game



How did you come up with the idea for your hobby project?


“I was reading a children’s book (Sinä olet superrakas) to my toddler in the spring of 2022. One of the illustrations of the book depicted the sea rising above the city skyline like a mountain. I thought of how the world would look like if we’d be living on the inner side of a sphere, instead of the outer. It was obvious to me that gravity would be different. Instead of gravity pulling us towards the center of the earth, gravity could push us towards the inner side of the sphere. And for the reverse effect to happen, there should be an object that we gravitate away from, not towards it.


The thought lingered, so I built a prototype to test the concept. That’s vetovoima.”


How was vetovoima built?


“A prototype in 3D would have been the most immersive, but I wanted to try out the idea in 2D first just to keep things simple.


I chose the Bevy game engine, which is built with the Rust programming language. I’d been looking for a chance to try Bevy for more than a year then.


Bevy has a data-oriented ECS architecture. You create Entities that represent game objects, attach behavior and data to them via Components and update them using various Systems. ECS supports parallel processing of game data, and the game objects can be dynamically changed by adding, updating or removing components. For instance, you can easily disable gravity altogether, or just for one object. When combined with the expressiveness and performance of Rust, you can easily create games that run fast and are a joy to write.


I chose a minimalistic presentation for the game world. The objects are simple geometric shapes like circles and non-regular polygons. The objects vary in mass, and that’s color coded. You can easily see which objects are heavy and which are not. The world is a hollow circle (2D sphere), and the central force of gravity is a circle (like stars appear, except in children’s books).


It would have been time-consuming to write a physics engine from scratch for the project. I used the popular Rapier physics engine instead. I had to disable the default gravity and add a custom force (my version of gravity) to the game objects. After that everything came about naturally.


I added some basic controls to change the direction of gravity. With some vector math, the force itself was updated and the objects followed. The physics engine handles collision, and the force of the collision is combined with gravitational force.



The initial prototype was just a simulation. Once I added a goal to get to and a character you could move, vetovoima transformed into an arcade game.”


How is the gameplay?


“As the player you control a yellow block character towards a goal depicted as a blue pole. You can only move forward, slow down, or change the direction of gravity (towards or away from the central force). That means no jumping, no backtracking. That’s where the challenge comes; when you move the character away from the “ground” to avoid an obstacle, the obstacle may move as well. You need to navigate through potentially dozens of objects flying around to reach the goal. Any change to gravity may trigger a chain reaction and throw your character into a random direction. You might miss the goal and have to travel around the circle world, again.


You have limited time to get to the goal. If the time runs out, it’s game over. Once you reach the goal, you move onto the next level. The game gets progressively more difficult as you progress through the levels. More obstacles, less time to reach the goal.”



What did you learn from the project?


“How to work with the Bevy game engine, for one. I’d definitely use it again for a prototype — or even for a humble commercial game. I used many of Bevy’s features (in the scope of a 2D game), and I feel comfortable using it now. I was already proficient with Rust when I started out, but learned something new on that front as well.


I had been working on another game hobby project before, which is why I had already brushed up on linear algebra and geometry (somewhat mandatory for game development). Yet I learned new tricks, and repetition never hurts.


Considering work projects, which are usually web applications or services, having stronger math intuition comes handy (even if I rarely work with physics…). Rust is becoming quite popular for all kinds of non-systems use cases, so I expect to someday use Rust at work.”


Anything specific you’d like to share?


“I felt great once I came up with an algorithm to display the direction and force of gravity as circles. Depending on the direction of gravity, the circles move away from or towards the central force of gravity. Their lightness and opacity change based on the distance, which makes the visualization striking, in my opinion. The circles are never (de)spawned, instead they move back to the other side if they reach the bounds of the game world. I can use the gravity force value directly to update the radius of a circle, as the force is signed. In plain terms the direction of gravity is included in the force value (between -1.0 and 1.0).


Here’s the update code as a gist: https://gist.github.com/klemola/a2bb8a99f90578c456b7cb6e44c100ea Another tidbit for programmers: true randomness often looks kinda bad. People expect to see patterns, patterns are pretty, so I used normal distribution e.g. for the shape of the terrain and the polygons. I am looking into making the shapes even more natural with 1D noise (https://www.scratchapixel.com/lessons/procedural-generation-virtual-worlds/procedural-patterns-noise-part-1/creating-simple-1D-noise).”


Closing thoughts



vetovoima eventually made it to the Rustconf 2022. This was unexpected! Carlo S., a member of the Rust gamedev community, was building an arcade cabinet that he wanted to load up with indie games built with Rust. I applied to have vetovoima included in the selection. I only had to tweak the controls and display resolution to make the game compatible with the physical cabinet.


I recommend anyone to try their wings at game development. It’s possible even without prior programming experience, even kids can do it! To quote someone “even more fun than playing games, is to build games”. The game doesn’t have to compete with multi-million budget commercial titles. There’s beauty in simple indie games.”

play vetovoima!

https://yourmagicisworking.itch.io/vetovoima


vetovoima source code

https://github.com/klemola/vetovoima