I’d like to introduce my racing game called Sektor. It’s inspired by Super Mario Kart and Death Rally for the PC.
It’s still a work in progress. At this stage it is playable, the basic mechanics are in place. First I’ll explain how this all got started.
What went before
I’ve always been inspired by computer graphics, the demo scene and games. While I was working as a web developer I got into contact with the Gaming Department of the company I was working for. They made some cool games for the iPhone, one of which was even demonstrated at a WWDC keynote. For me it was clear, I wanted to try to get into that department. Too bad that shortly after that the Department was sold. I continued doing web development for a few years, until I had enough of it. It started to get a bit boring, I wanted to create something with stunning and beautiful graphics. My employer gave me the opportunity to start working for the mobile department, this really felt as a big relief. A whole new world opened up for me.
After a year or so, I figured I should just create my own game in my spare time. Some people at work told me I should use Unity others said Unreal. I decided to start with unity. I did some tutorials and made a few prototypes, relearned how to use a 3d modeling tool. Within no time I had something working.
early prototype in unity
I asked myself a question: Do I want to just make a game, or do I want to _learn_ how to make a game? The answer at the time was that I wanted to learn how game engines etc work.
I decided to buy some books about game programming and just start. Some of the books I bought were: “Game Engine Architecture”, “OpenGL programming guide”, “3D Math Primer For Graphics and Game Development” and books about storytelling and creating the art for the game.
At the time I think apple just released swift, and I wanted to learn about the language. I decided to create a game using swift and SceneKit. In order to use swift I had to install a beta version of Xcode, and for using SceneKit I had to install a beta version of MacOS (I have to laugh while reading what I’m writing, what in gods name was I thinking :).) The compiler crashed a few times per day, I just kept going after every update it became more stable.
I estimated it would take me about 6 months to create something. In hindsight it took me more then 2 years to be at the stage where I am now, in the mean time I also became father of 2 more baby boys. The actual development is like a wave, sometimes there are weeks/months of inactivity.
What’s in this release
This release is written in swift 3.0, using SceneKit and GamePlayKit. For the actual car physics I’m using ‘SCNPhysicsVehicle’ which is included in SceneKit.
The architecture is based on the Entity/Component pattern. This means I have a ‘Car’ entity which has several components. For instance the car has a ‘CarControlComponent’, which is responsible to convert user input into actual forces on the car’s ‘SCNPhysicsVehicle’. Some other components are ‘WeaponComponent’, ‘PowerUpComponent’, ‘CameraComponent’, ‘CarAudioComponent’ and others. Each component has its own specific task.
This release only consists of 1 prototype track, which is actually level 1 of Mario Kart. I’m using this track to see if I get the same adrenaline rush as I get with Mario Kart ;).
The handling of the car is tricky to get right, I’ve literally spent many weeks, maybe months, tweaking the car to make it feel the way I want it to feel.
This first big challenge making this game was how to let the AI cars drive. At first I created a waypoint system, as you might imagine this made the steering of the car really abrupt because of the sharp edges between some waypoints. Anyway, the first time I got it working I was really proud, it gave me a really good feeling to see my own creation move by itself. The rest of the evening I spent watching the cars go round and round :).
Later I saw a video snippet on youtube which explained how AI cars move in some games. They talked about a waypoint system that had a target (called a rabbit) following the waypoints, the car would then just follow the target at some distance (at least that’s what I understood.) Doing this would make the car turn more naturally. I programmed this by letting the rabbit follow the waypoints at a fixed speed. I would then let the car follow the rabbit at some distance, this kind of worked, the turns were smooth, the only problem now was that the car couldn’t make tight corners because it was going too fast.
A while later I found out I was doing it wrong. The idea was to have a waypoint system with sectors. You can pre-calculate the maximum speed the AI cars are allowed to drive within each sector. The speed depends on the sharpness of the angle towards the next waypoint.
Doing this prevents the cars from flying out of the corner. The other thing I changed was letter the car jus drive the maximum speed that was allowed in the sector (with some interpolation towards the next sector.) Instead moving the rabbit around the track I changed it to letting the car project the rabbit on the track between the waypoints. The distance of the projected rabbit in front of the car depends on the speed of the car. If the car drives slow the rabbit is projected closer to the car. This makes the car follow the track more closely.
Next thing was determining the position of the cars. I implemented this by calculating how far each car has driven. In my ‘Sector’ struct I have a ‘SectorVector’ which is the vector from the start of the sector to the end. The magnitude of the vector is the length of the sector. After a car has passed a Sector boundary I add the sector length to a property in the ‘RaceCompetitor’ struct. I also calculate the length within the current sector every frame.
I implemented this by calculating a vector from the start of a sector to the car and project this onto the ‘SectorVector’. This roughly determines the length within the current sector. Then just sort all RaceCompetitors on the total distance.