The game was a 3D platformer consisting of two levels. The first level you were in a slaughterhouse and your goal was to platform your way out of that place, and the next level was a larger level set outside that in the end took you up to the top of a mountain where the owner of the slaughterhouse you escaped from lived. That person was the boss you needed to defeat in order to win the game. The battle consisted of waves of smaller enemies you had to defeat before the boss came down and you could deal damage to him.
So an average platformer, you say? Where lies the twist that makes it fun? That twist is a mechanic called “Ram”. The cow could walk and rotate. That was its basic movement. But if you pressed the sprint button, the cow started to sprint. Or as it is a cow, it started to ram. Whenever the cow was in that state, it could interact with stuff. Running into enemies made them a non-threat for a short while. Running into trees or pillars made them fall and built bridges (and crushed any enemy that was beneath them). You could also run into barrels and haybales in order to launch them as projectiles. They could also be moved slowly without ramming to help players progress in the level. Jumping on a haybale gave a great jump boost.
First of all every coder created their own 3D physics system using State Machines. Then a group was formed, an idea was generated, a GDD was written and then development began. During this project, Trello was used to keep track of tasks and the project’s progress.
As it was my physics system that worked the best, we chose to use that and develop further on that one. It was a State Machine that had different states depending on if the player is walking, running or jumping, and those states were derived from a physics state in which gravity was added and collision was checked.
A lot of my time was spent with the character (the cow). First of all, we had difficulties coming up with how the controls for the cow should feel. During early playtests, most of the critique on the programming was about how the character felt. You could run in any direction, your ram had a cooldown and such things. In the end, I made that you could only walk in any direction other than forward, and you could ram for as long as you wanted, but when you released the button you got a cooldown in order to prevent unlimited ramming. I also fixed so you had much less control when you were ramming. Before you could rotate immediately when sprinting, but in the end you had a much larger turning circle when ramming. We got it to feel like it actually was an angry cow that ran. We also decided that you could walk with the cow without rotating the camera, and the camera could rotate freely when the cow was stationary. But if the cow was moving and you rotated the camera, the cow also rotated with it.
I also spent a lot of time on the camera. Sometimes when there was a minimum amount of headroom between the ceiling and the cow, the camera clipped into the ceiling. And when the cow stood next to a wall with the camera placed between the wall and the cow, it either clipped the wall or clipped the cow. I ended up fixing this so that the camera always kept distance from the wall and the cow was hidden completely if you got too close to the wall.
Now, how do you rotate a cow? I asked myself, my classmates and my supervisors that, because a human character can be rotated along its middle as its shape resembles a cylinder, but a cow has one side that is longer than the other. It is more long than it is wide. So when rotating it would rotate into the wall half of the times, when the long side hit the wall. Because of time constraints, my solution was to put the collision on a cylinder and parent it to the cow model. The downside of this is that the head and butt of the cow often rotates into the wall, but as the game had quite large areas, it was deemed okay for this project.
The falling objects (trees, pillars) of the game was one thing I did. It wasn’t an easy task to make an object rotate from the bottom edge on the side where the cow hit the tree, make it fall the same direction the cow ran into, and check as it is falling if it hits an enemy or if it has hit any object that would stop the rotation. I sat with that a lot and after creating many different types of raycasts and doing some debugging, I made a falling object that worked pretty well.
I also did the movable stuff in the game. That you could launch a barrel at an enemy or move a haybale to use it as a platforming tool, that was me. I also helped a bit with the enemies when the other programmers in the team needed help.
To access one area of the second level, you needed to defeat a miniboss and get its key. You then had to ram through a gate in order to open it and progress. I created the model for the gate and the key, and I coded the script that rotated the gate doors. Now in hindsight I wonder why I sat fought with rotation issues depending on the way the parent was rotated when I simply could have created an animation clip to do that instead, but I wasn’t that well wandered in animations back then. I eventually got it working and it looks really satisfying running into it!
I also programmed the saving/load game-function, complete with a loading screen.
Custom physics and collisions are difficult to do.
Many of the major bugs in our game was directly inherited from the custom physics system I developed. Whatever I did I could not guarantee that the player wouldn’t fall through the ground at some random points in time. It didn’t happen often, but at rare occasions it did. None knew why, not my classmates, not my supervisors, none. We just had to live with it. We put killzones under the terrain so if it happened, the player would spawn at the nearest checkpoint. It was not ideal, but I couldn’t sit with it any longer. I had other things that needed my attention. Like making trees fall.
Doing animal characters is not as easy as it seems.
As stated above in “My Work”, doing an animal character proved difficult in many ways. How do you rotate a character that is more long than it is wide? How do you check for collisions when the asymmetrical character is rotating? Where do you rotate your camera around? The head? The middle? The butt? How do you make the animal feel like an animal and not a bad human copy? All those questions we, and especially I, had to focus on a lot. Because of time constraints, I ended up treating the character like a cylinder and made that cylinder a parent to the mesh. Then I rotated the camera around the top-middle of the cow. More details are explained under “My Work”.