Kekouan

Have I talked to you about Quake?

2024-03-17

I'm not entirely certain when I was introduced to Doom or Wolfenstein 3D. Long after their respective releases, no doubt. Quake) though, I got to experience when it was new. It was impressive as heck. Then people started making modifications for it. Grappling hooks appeared early on, there were versions that had rudimentary vehicles. What a delight. The people who created some of the initial QuakeC mods ended up being pretty prominent game developers.

At any rate, I found a Quake BSP import plugin for Blender and that unlocked some exciting new possibilities:

“Eternal Dismemberment Complex” by Kevin Shanahan aka Tyrann as seen in QuakeSpasm “Eternal Dismemberment Complex” by Kevin Shanahan aka Tyrann

Quake levels had a theme alright. Classically the palette of Quake has been described as "brown-ish". Still it beats the stuff I could create at the moment.

Quake Level in SceneKit

There's no lighting implementation at the moment so everything gets the same degree of light.

Particles

The next thing I wanted to sort out in my project was a way to have weapons. I figured why not make use of the particle system in SceneKit for this end:

A particle system can perform limited collision detection and resolution with geometries in the scene. If a moving particle intersects a geometry attached to one of the SCNNode objects in this array, SceneKit resolves the collision, either by removing the particle from the scene or allowing it to bounce off or slide along the geometry’s surface.

So I setup a simple scene to work with:

A simple particle systems test scene in SceneKit, featuring a white cone emitting red cubes towards a large green cube, passing through it

So I want those particles to stop at the green cube.

A simple particle systems test scene in SceneKit, featuring a white cone emitting red cubes towards a large green cube, stopping at it's surface

Now I need to be informed that they have collided with the cube.

![A simple particle systems test scene in SceneKit, featuring a white cone emitting red cubes towards a large green cube, which is on fire or exploding

Haha. Neat. (The cube “explodes” after getting hit by 10 particles.)

Truly we're cooking with particles here.

Next up, try it with the model I have created:

A simple particle systems test scene in SceneKit, featuring a white cone emitting red cubes towards a green Marten model A simple particle systems test scene in SceneKit, featuring a white cone emitting red cubes towards a green Marten model, which is on fire or exploding

Let's make it complicated

I had working particle collision and detection, but when you're only dealing with a single object it's very easy to know which object was collided with. In what I was imagining you'd have multiple enemies at any given time. So it was key to figure out which object was getting hit.

I am only informed of where the collision happened, so my first solution was to just iterate through all the objects that could be hit, and see if that position was within their bounds. That worked well enough:

A simple particle systems test scene in SceneKit, featuring a white cone emitting red cubes towards many green Marten models, some of which are on fire or exploding

A simple particle systems test scene in SceneKit, featuring a white cone emitting red cubes towards many green Marten models, some of which are on fire or exploding

Then I considered how it would work in reverse. I added a target for my enemies to shoot at:

A simple particle systems test scene in SceneKit, feautring many green Marten models, rotated and firing towards a white sphere

A simple particle systems test scene in SceneKit, feautring many green Marten models, rotated and firing towards where a white sphere was

Neat.

Spin, Spin, Sugar

Things were working great with just one target, but adding a second target caused some problems:

A simple particle systems test scene in SceneKit, feautring many green Marten models, and two white spheres

They should be attacking the closest target, but it's not working. I had to spend some time figuring out how to make sure that the model was correctly rotated to face the target.

A simple particle systems test scene in SceneKit, feautring many green Marten models firing at two white spheres

A simple particle systems test scene in SceneKit, feautring many green Marten models firing at where two white spheres were

Much later, after figuring out the dot product I was able to have a Marten accelerate towards a target, reach a specified range, stop immediately, and start shooting:

A Marten model that has moved towards a white sphere and is firing at it

Adding things back in, I get a scene with multiple Martens rotating, moving, and firing: Scene with multiple Martens rotating, moving, firing at white sphere targets

It's a bit chaotic, but I like it.

Scene with multiple Martens rotating, moving, firing

States

The way I was trying to organize the behaviour of my enemies was into states, specifically I had

So initially the Marten would be in the RotationState, turn to face the target. Then it would transition into the PursuitState which would cause it to accelerate towards the target, until it reached a specific distance, and then transition into the attack state.

Rotation:

A Marten rotating to face the white spehre target

Pursuit:

A Marten moving towards the white sphere target

Attacking:

A Marten firing at the white sphere target now that it is in range

Adding this back in allows the multiple version to work, and since they have a physics body they collide with each other:

Many Martens rotating and firing Many Martens rotating and firing, after some have colided together

Teams, Red, Blue, Green

One easy way of re-using assets is to give them different colour schemes. Perhaps the green versions are the standard version, and red would be for an elite or stronger version. So I wanted to see if there was an easy way to add some colours:

A Marten model in Blender, except now it's blue and gold

This allowed me to try out a version with different coloured versions:

Scne with red, blue, green martens rotating, moving, and firing

Then I organized them into teams, and had them attempt to engage each other:

A scene with teams of  3 blue, 3 red, and 3 green Martens engaged in combat with the other teams A scene with teams of  3 blue, 3 red, and 3 green Martens engaged in combat with the other teams A scene with teams of  3 blue, 3 red, and 3 green Martens engaged in combat with the other teams

I was quite pleased with how this was working. It was time to finally get back to my original project instead of my simple test case:

A blue Marten in my level scene

It worked and it didn't cause everything to immediately explode. Great. Next up a new map design.