Stay and Slay
Timeframe: 16 weeks (20h/week)
Team: 5 programmers, 2 designers, 5 artists
Engine: Our improved version of TGE, the school's in-house game engine made in C++ and DirectX11
Using an entity-component system library EnTT.
Inspiration: Anger Foot
Contributions
Camera
This was my first attempt at implementing an FPS camera. I learned a lot and experimented with two different ways of applying mouse input. Initially, I calculated the delta screenspace position of the mouse movement between frames by setting the mouse in the middle of the screen and then moving it. However, this approach proved error-prone, and I had to convert between screen space and client space to get accurate values. Despite my efforts, this method had a lot of flaws, and the camera's movement felt rough and jagged, especially when moving diagonally. For my second attempt, I utilized Raw Input from the Windows API, a more effective solution.
Kick
The kick went through many iterations and tweaks, such as finding the optimal position and rotation concerning the camera. Initially, the leg mesh looked small when viewed in the first person. After scaling the leg it looked quite funny from a bird's-eye view.
To create a sense of weight behind the kick, I added a rough flinch at the beginning that gradually dissipated after reaching its peak.
Deadly props
Apart from using the kick mechanic to take down enemies and kick open doors, another enjoyable aspect was using it to interact with props. Our level designers suggested we make physically based objects lethal to enemies when kicked at a certain velocity. As a result, kicking props became an even more satisfying way to dispatch foes.
Breakable Door Physics
The doors in the game were composed of two meshes: a complete static door and a set of broken door pieces.
The "physics-based" door, which lacks a visual component, functions as an interface with a container holding all of its door pieces, allowing for easy iteration through them.
Upon revisiting this system, I realized that I could have eliminated the intermediate "physics-based" door and instead had the standard door manage all its door pieces and logic.
I loved the result of these doors, especially in combination with the sound design when broken.
Player Movement & Recoil
I implemented movement mechanics consisting of acceleration, deceleration, and jump height. We opted not to include a crouch.
The recoil of the sub-machine gun had a similar recoil to the kick, but after feedback from the group, I made it simpler. Randomized spread is also present for the SMG.
On the other hand, the pistol recoil remained unchanged, with only minor adjustments to the values after I reworked the recoil system.
Damage Indication & Death Camera
I tested various post-processing values to scale with health. In the first iteration, I used red tint and a vignette to indicate damage taken, but due to the game already having such a heavy tone of red, the visuals were not pleasant. I landed on saturation and vignette instead. And an explosion of red at the moment of death.
The death camera adds an immersive element to the gameplay experience. Once dead, the camera falls to the ground, leaving the player looking around.
Node scripting
I created most script functionality for the tutorial elements in the game. This was a valuable experience collaborating with level designers to create the nodes they requested.
Blackboard nodes were also available for our level designers, which made it possible to set and get variables in runtime through scripting.
The level completion was also made through scripting, although I had to tinker with the scene stack to determine which level should be loaded next.
Technical Details & Closing Thoughts
The second project with EnTT (entity-component system) under my belt, this time around, I had a better understanding of the workflow, which made the whole process smooth. I thoroughly enjoyed developing using ECS, and I'm leaning more and more toward data-oriented programming as opposed to object-oriented. I expanded my usage of features provided by EnTT, such as the ability to exclude specific components and the use of the blackboard, known as ctx (context). Because it was my first time using NVIDIA PhysX, I'm glad we did not create a wrapper around PhysX. This allowed me to gain a more in-depth and comprehensive understanding of its structures and their workings. A better learning opportunity put simply.
______________________________________________________________________________________________________
It was fun and educational to create an fps camera and implement various recoil rotations. During the process, I quickly realized that I needed to separate the up and down rotation of the camera from the left and right. Otherwise, the player model would rotate around its right axis when looking up and down. To achieve this, I created a separate "head" matrix that represents rotation up and down, which I then multiplied with my player matrix and additional recoil rotations. By doing so, I was able to apply rotation to the camera while keeping the player model fixed in place.
©2023 by Viktor Rissanen Resumé LinkedIn rissanenviktor@gmail.com