First Commit
What is this blog?
I have been fascinated by video games since childhood and building some ever since. Today I get paid for doing that (among which are Far Cry 5, Rainbow Six Siege, or Company of Heroes 3) but deep down I am hopeful to eventually become independent thanks to one of my ideas. The issue? I procrastinate and would spend my day watching brainless videos if it wasn't for some sort of pressure, someone looking over my shoulder or a deadline to meet before I'm not able to buy groceries anymore.
And then, a friend of mine suggested: why not create a newsletter? A baby weekly step designed to accustom myself to working on my own projects, as well as a social pressure mean: if I don't post, someone will see it! This is what you are now reading, and I hope you will enjoy your time with me on this game(s)-making journey.
PS: this first post will be especially long as it recaps years of work in the making.
The Game Idea
I have multiple game ideas, about 3 concrete ones actually, but 2 years ago I decided to settle on one of them. It is a racing game, heavily inspired by Trackmania and the frustrations I faced trying to mod the game, circumvent its bugs, or create my own maps. If you don't know Trackmania, it is a racing game where players both make the maps thanks to its powerful in-game editor, and try to beat their fastest lap times solo or on community servers.
Trackmania is great, its community created content that I spent thousands of hours enjoying, its gameplay and driving physics is very tight allowing for speed-running and competition to strive, and its map editor is so intuitive and accessible that most players have opened it at least once. But I also know of limitation that prevents certain types of mode or maps to exist, and after a couple years of trying to create my dream maps, I thought: "Why not be in full control and make my own racing game?"
However, making a pale copy of an existing hit would lead nowhere. This is why I decided to first focus my attention on what I think the game lacks: generating both building blocks and maps procedurally. While I would love the game to include a map editor and time trial mechanics, I will start with a chill-focused experience where the player drives to no/little end. Add in a neon style environment supported by a synth-wave soundtrack, and you get a gist of the first major step I would want my game to reach.
My Progress So Far
Did I say I work as a programmer? I have seen my load of game engines through my short career, from proprietary to open source one. And among those available for such a project, none really appealed to me. Between lacking documentation, lower performance on small games, lack of C++ support, outdated architecture, etc. I couldn't get any of them to satisfy my needs. And beside, I love to learn how things work and do so better through doing it myself, so it became quickly obvious I should make my own engine.
A key element, which I became interested in following a GDC talk about Overwatch like many of my peers, was the focus around ECS (Entity-Component-System) architecture. The later consist of a clear separation between data (Entities comprised Components) and behaviors (Systems operating on Components). I originally started with my own archetype-based framework but recently transitioned to entt library. Of my old framework I kept a mechanism forcing systems to declared used resources (components) which allows my engine to be multi-threaded almost automatically.
struct MySystem
{
EcsWorldViewRef m_colliderEntities;
void init(EcsDataAccessRegistrar& a_registrar)
{
// MySystem will access Transform & Collider, nothing else.
m_colliderEntities.init(a_registrar);
}
void update(EcsDataAccessProvider const& a_provider) const
{
for (auto [entity, transform, collider] : m_colliderEntities.get(a_provider).each())
{
// Update collider entity
}
}
};
Another important engine element I worked on, before even knowing I would make this racing game, was a reflexion framework to handle saving, loading, and editing data. I knew, having worked on various engines with various levels of reflexion, I wanted a clean framework both non-intrusive (so it could work with any types including STL ones) and close to C++20 language (no complex pre-compilater generative step for instance) that would handle all of those use-cases. I did achieve something to my liking through templates and visitor pattern and now have an efficient way to load my game's data (although I haven't yet had time to properly implement an editor):
struct TransformComponent
{
glm::vec3 m_position;
glm::quat m_rotation;
}
template , TransformComponent>>>
void accept(TVisitor& a_visitor, T& a_transform)
{
a_visitor.visit(nvp("Position", a_transform.m_position));
a_visitor.visit(nvp("Rotation", a_transform.m_rotation));
}
Finally, the main question when starting to make this game was: can I make the physics as tight as Trackmania's, maybe even fixing some of its bugs along the way? So I went at it. I first attempted to use and tune an existing physics engine, Bullet, but I then realized a handful of approximations (very welcome for most games) were getting along my way. Some collisions were not detected or resolved with a degree of approximation that made it difficult to produce a consistent driving behavior (especially the car bouncing more or less high upon collision). This attempt proving unsuccessful, I iterated for years (whenever I wasn't too tired during the weekends from my weekly work) to implement a good collision detection and resolution engine. The main idea was to let the car and environment collide and clip, then solve the collision through multiple frame by representing it as a dampened spring based off penetration dist. I tried using complex mathematical tools to perfectly compute such dampened spring's restitution but settled on a solution consisting in applying RK4 (Fourth-Order Runge-Kutta) algorithm to discretely solve this rigid-body system. The final result is very satisfying to me, I think it will offer -once tuned- a similar feel to Trackmania's driving and I believe that I fixed one of the key reasons for some of its bugs (while very likely creating other bugs in the process). Here is a video showcasing my physics engine and its capabilities.
What's Next?
Over the coming months and until completion of a playable alpha of my game (which should consist at least of a procedurally generated game mode where player drives in a neon-style environement on a never-ending road), I will post here weekly updates of my progress. Some posts may be short but I'll be sure to have one ready every Sunday.
