Status Update - January 2021
Hey folks, it has been a while since the last blog post. That doesn’t mean that development on Project Slide has slowed down. On the contrary, lots of things have happened since October. Writing these blog posts is a lot of work and I find that the more I concentrate on them, the less time I have to do actual game development. That means that I have had lots of time to develop the game over the past few months!
Currently I am working on the first playable demo of the game, which will demonstrate the primary game loop: Driving around, fighting enemies and hauling cargo. The demo will be completed in the spring of 2021. Everything in this post, except for the Zig stuff at the end, is being made with the demo in mind. Let’s see what has been going on!
First in-game 6x6 vehicle
In the previous blog post we talked about certain challenges with implementing physics-driven 6x6 vehicles, ie. vehicles where all six wheels are driven by the engine. At the end of the blog post I hinted at the first actual in-game 6x6 vehicle being in development. Well, here it is. “Car3”, known in the in-game universe as the “Badger”:
Image 1 shows the “Combat Badger”, ie. the vehicle fitted with a twin-barrel cannon and a grenade launcher on the roof. The weapons are still lacking details (such as textures/materials and even barrels for the cannon). The vehicle can also be configured as a “Cargo Badger” without the weaponry. The Combat Badger will serve as the primary enemy type in the demo and you will get to drive a Cargo Badger too!
Demo level - whitebox version
Over the holidays I spent a couple of weeks sketching out the level which will be the setting for the demo. The result is a so-called “whitebox” version of the level, ie. a version where the size and layout of the level is more or less final, but meshes, materials and details have been left out. This way the gameplay can be tweaked and polished to fit the space (and the space can be tweaked to fit the gameplay) without having to worry about moving around lots of small objects and details that wont affect the gameplay.
Notice the clash between the vehicle (using final assets) and the environment (consisting of whitebox assets). Once the level layout has been finalized and the demo mission has been scripted and tweaked, the whitebox level assets will be replaced with final assets.
Image 4 shows a ravine which splits the open space in the level into two areas. Slower vehicles such as the Badger need to drive around (or into) the ravine while faster vehicles can jump over it using the cliffs as jumps.
The ravine ends at the edge of a huge cliff. This is also where the mission objective, a research station, is located.
The player will enter the level through a canyon leading past a hydroplant and a small valley. You can see the research station’s mast in the distance (see Image 6).
The game is set on a distant planet, far from Earth, which is colonized by humans. The colonists used large spaceships called “ark ships” to travel to the planet. The game takes place many years after arriving on the planet, but the remnants of the ark ships can still be found scattered across its surface (see image 8).
I am quite happy with how the level turned out. Obviously there are still countless things to do before it looks, sounds and feels as it should but it already plays quite nicely. The whitebox version will allow me to tweak the core gameplay, mission scripting and AI until they are good enough for the demo.
Improved driving AI and obstacle avoidance
Speaking of AI, I have worked a lot on the driving AI lately. In the last part of the AI blog series we looked at how vehicles navigate when moving around the game world. As mentioned in previous blog posts, AI agents drive the vehicles just like human players do, by applying acceleration/braking and turning the steering wheel.
While working on the whitebox level it became apparent that the current driving AI logic wasn’t going to be good enough for the demo. Vehicles got stuck in infinite loops, didn’t detect obstacles in time, couldn’t handle cornering at high speeds etc, so I got to work on improving all that and more.
One area that got improved a lot is the “whisker” system, used by the AI agents to detect dynamic obstacles, ie. things that the navigation mesh system does not know about. This includes other vehicles driving around the world. The agent fires a number of rays forward in a sector and checks which rays hit something and how far away. Based on where the obstacles are and how close they are to the agent, it can make decisions on how to avoid them. The length of the rays can be adjusted on fly based on a number of factors, such as the speed of the agent itself.
The above image shows the whisker rays fired from the vehicle on the right. Two of the front whiskers, the red ones, hit the other vehicle. The agent also has a number of rear whiskers which are used when the agent does a reverse turn, in order to avoid backing into something. The rear whiskers are updated more seldom than the front ones, and only when the vehicle is in reverse gear.
Next we have a video showing an AI agent trying to patrol an area while avoiding vehicles.
About halfway through the video I spawn in a heavy hauler and a trailer right in front of the agent, and see how the it reacts to these new obstacles. The yellow number on top of the agent shows its current speed multiplier. It goes from zero to one and represents how fast the AI agent thinks it should be driving, with zero being “full brakes” and one being “full throttle”.
There is a lot of work left to do on the AI, but it is shaping up nicely and should already be good enough for the demo. The next thing on my list of improvements to be made is combat AI, which is a completely different kind of beast.
Bonus: Gameplay programming in Zig
The last thing I want to mention in this update is the ability to write gameplay code in Zig. This is something I started looking into late last summer and have been working on as a side thing, just for fun.
I am not going to go into much detail why I chose Zig over Rust or C# or Jai (or any other modern language) in this blog post. There is enough to say about that to warrant its own blog post. Suffice to say, I enjoy writing Zig a lot and it seems to fix many of the things I find annoying about C++, while keeping the language very simple. Code I would have written in C++ previously, I might consider writing in Zig in the future.
So, how does Zig fit into Slide’s C++ codebase? The Basis engine used by the game has a component-based object model which is kinda similiar to the GameObject model found in Unity. I basically made it possible to write individual components in Zig instead of C++. The Zig code is then compiled into a dll library which is loaded at startup and objects can use the Zig components in the same way that they use C++ components.
Zig and C++ does not talk to each other directly. However, Zig has excellent support for communicating over the C-ABI and thus much of my work was exposing the Basis/Slide interfaces as C-APIs. For all you non-programmers out there, it essentially means taking some functionality of the game and making sure Zig can use it.
When planning the Zig work I decided it would be best to use Zig for an actual in-game feature, and expose the engine functionality to Zig as it was needed by the feature. I went for a magnetic crane, something I had planned to make for a long time. The crane can be used to load cargo onto a trailer and pick up cargo that has fallen off a trailer. Check out the video below.
As you can see, the visuals for the crane are very much placeholders but the logic is mostly there. The crane is a good candidate for exposing a new programming language since it touches many different systems. It needs to be able to pose and render the arm, create the physics force field which pulls in the cargo objects, it needs to sync the motions across the network etc. It also needs to be able to read the input since the crane acts just like a normal vehicle when controlled by the player.
For comparison, I also implemented the crane components in C++. If you are interested, I made the code available below. The crane logic is split into two components; CraneAvatarComponent which handles the input and camera, and CraneControlSystemComponent which handles the actual crane mechanics (arm, physics forces etc.).
- CraneAvatarComponent: Zig version, C++ version header, C++ version source
- CraneControlSystemComponent: Zig version, C++ version header, C++ version source
What I like about the way the Zig support is set up is that objects can use both Zig and C++ components, and thanks to the messaging system used by the game, they can talk to each other even if they cannot call each others' methods directly. The current version of the crane uses 10 C++ components and 2 Zig components.
For now, the Zig support is just a fun side thing. The Zig language has not reached version 1.0 yet and I am a bit hesitant to write any critical code in it right now. At this point I am not sure if the final game will ship with Zig code or if it will remain experimental for the forseeable future. Perhaps Zig will be stable and production usable by the time the game ships.
An interesting use case for the Zig support is moddability. A player wanting to write gameplay code for the game could do so using Zig. They would only need the Zig compiler (which is tiny), a basic text editor and the APIs for the game which would be included in the modding SDK (and are also tiny). In contrast, building the full C++ codebase requires the user to set up 10+ different pieces of middleware, generate projects using CMake and installing programs like Visual Studio or XCode to build the code.
Using other people’s Zig mods could be a bit risky though, since Zig is native code and not sandboxed in any way. Perhaps the mods would need to be distributed as source code so that they could be properly audited. Something to think about…
What’s next?
At the moment I am working on finalizing the AI for the demo. After that, the demo mission will be implemented and I can move onto modeling and texturing the environment. Then finalizing the vehicles, then particles and VFX, sounds, user interface, HUDs, music… Much to do! Oh, I should also be able to reveal the final name for the game soon, exciting times!