January 27th 2023

Planning and Starting the Final Game Jam


Set-up

On Monday the 12th of December, I first met up with my assigned group 12 members during my code studio session. During this session, we watched all the pitches that the upper students had created in order to vote and decide on which one we wanted to make over the coming months. After some discussion, we settled on the 'Don't miss the bell'.


Don't miss the bell is described as a first-person parkour street runner, where you play as a rebellious teen attempting to make it to class before the time runs out. It would have basic 3D first-person movement, with jumping, sliding, vaulting and dashing, as well as any additional mechanics we wanted. The art style was to be low-poly with a style similar to hello neighbour, in order to cut down development times. There would be 31 levels for 31 days in a month, each level will increase in difficulty and will feature a variety of objects such as cars, people, traffic, trains etc. Also within levels, there would be powerups which will temporarily boost the player.

Once we had decided on the game, we waited until after Christmas break before getting started.

Planning

The day before the second semester started, the whole group had a meeting on discord. The point of the meeting was to go over the pitch again and come up with an idea of what we wanted to keep and change from the pitch. The next day during the code studio session we also all met again and discussed further. We wanted to make some changes to the pitch in order to make the game more our own, and also match it better to what we would want to make and play.

By the end of both meetings, we had a rough idea of the changes we wanted:

The final planned product seemed very similar to the Mirrors Edge games, which feature similar first person parkour mechanics but instead focuses on a story-based adventure rather than a time-trial game.


With a good outline of the game done, the designers in the group got started making some design docs, the artists began making concept art, and the programmers began coding.

Mirrors Edge Catalyst Screenshot

Development

I immediately began work programming after the idea was finalised. This started with setting up the GitHub repository with the unity project which took forever because GitHub sucks, and I hate GitHub, as well as all the code people assigning themselves roles on the project's Jira. We settled on using both Jira and GitHub as they are both the most commonly used and professional options, so it's a good way to prepare for the industry. They are also both free for what we needed, whereas many other options weren't.

The plan for the first 2 weeks was to create a rough prototype, featuring basic versions of all the main mechanics of the game, such as the movement, powerups and game loop.

I assigned myself the task of creating a template for all the powerups, as it sounded fun and I had a good idea of how I would do it.

The general idea for what I had to do was:

The first task was done very easily, all I had to do was create the powerup object as a 'prefab'. A prefab is perfect for this, as it allows you to place templates of unique objects multiple times within the same scene, so I can place as many powerups as I want without having to copy and paste the same object lots. They also allow you to change attributes on each object without altering all the others, allowing for each powerup to have different properties. It also means if I alter the main powerup prefab, then all versions of the powerup are also changed. This is incredibly helpful as it means I won't have to go through all the levels and change all the powerup objects if I need to make any adjustments.

Next up was detecting if the player touches the power-up. There were two potential ways I thought of doing this, either using collision boxes and triggers or using a ray cast. Having the powerup be a trigger seemed like the obvious option, as there would be no real benefit to using a ray cast in this situation, and having it be based on the powerups collision box would allow it to be very easily adjustable, and have very few lines of code. By giving the powerup a collider and making it a trigger, it means that the powerup has a collision box, but can't actually be collided with. This combined with the built-in OnTriggerEnter function creates a perfect system for checking if an object overlaps with another.

With the detection done, I next had to create the system within the function which would give them the right powerup effect. To store the powerup type on each object, I settled for just using a simple public integer from 1+ which could be easily adjusted within the editor. When the player hits the powerup, it checks the integer and runs the correct function. This method is easy and efficient, however, it does come with a major downside, that being it's not readable at all. If someone is trying to change the powerup type and doesn't know the number of it off-by-heart, then they will have to check the code to see which number to set it to. I decided this was fine to ignore, and added a comment to the variable declaration which would outline what each number represents

Now that there was a variant system in place, all the trigger function had to do was check the number stored in the powerup, and run the according function. An IF statement seemed like a very easy way to achieve this, so that's what I did. Looking back, however, I'm not so sure, and I may end up changing this in the future. This is because, while for just 1 or 2 variants, this is only 2 if statements. If there end up being 10-20+ powerup variants, then that will be tons of unnecessary code.

One workaround to this could be storing all the effect functions inside a list or array and then calling the function by accessing the list and using the variant as the index. Not only would this reduce the lines of code to only 1, but it would also help justify the use of having the variant being an integer, as it can be used as an index as well. For now, I have left the code as two if statements. In the future if they begin piling up though, then this may be an option I consider switching to.

The final main aspect I had to create was the powerup effects themselves. The original idea was to just use a function, which would set some variables and then perform things over time in the update function. However, after doing some research, and with the help of gamedevbeginner.com, I discovered the amazing coroutines. These are essentially functions which can be executed over multiple frames. This comes in very handy for this specific tasks since it makes it very easy to delay the next line of code, which can work as a timer. I used this to apply the speed boost effect by doubling the player speed, delaying 5 seconds, and then reverting the speed back.

Reflecting on this code, however, there are definitely some negative aspects I should improve. Firstly, collecting another power-up of the same type while the effect is active will double the speed again, making you go way too fast. To counteract this, I should store the original player's speed at the start of runtime, and add on the player's speed, which would be double that original value. This allows for multiple speed effects to be overlapped while this effect still remains the same. Another issue which may come up, in the long run, is that the WaitForSeconds method doesn't allow for the time elapsed to be measured. As a result, if I want a visual display of the timer such as a UI, then I'll have to add a few more lines of code to perform a while loop which will count up, allowing me to store the time elapsed in the variable while still performing the same effect.

With this, the powerups worked perfectly as intended and were ready to be pushed to the GitHub repo. I did want to add some visual flare first however, as it looked a bit bland (this ended up taking longer than everything else combined).

First, I wanted an idle animation for the powerup, where it would spin around in circles while bobbing up and down. This would help make the game feel much more lively, as well as make the powerup stand out from the environment much more and have it obvious to the player where they are. Originally, the way I was going to do this was just adjusting the rotation and position components of the powerup over time and using the lerp function to smoothly interpolate it. However, it was at this point that I discovered an epic new game dev technique named tweening.

Tweening is a linear form of animation, which allows you to easily interpolate between two values over time with just one line of code. Not only does this make life far easy as tweening packages come with all sorts of built-in functions and features, but it's also far more efficient as it means I don't have to modify the powerups transform component every frame, manually.

To use tweening, I needed to find a good Unity package to add to the project. There were two main options, LeanTween and DOTween. While I found LeanTween to be far easier to use, I also found it to be quite buggy and as it was no longer maintained by the creator, I settled for DOTween because that reliability was important.

Finally, I wanted to add a particle effect when the powerup is collected. For this, I watched a Brackeys video to learn the basics of Unity's complex particle system, and then just experimented until I found the look I wanted.

While the plan was to play the particle and then delete the power-up object, I quickly ran into an obvious issue. Deleting the object would also delete the particle component, meaning the particles couldn't play. I was unsure, so I did some research and this forum question gave me a smart solution. This involved moving the particle system component from the powerup object onto a new empty object instead, and making that a child of the powerup object. Then, once the powerup is collected, I can set the particle object's parent to null, removing it as a child. This means that once the powerup is deleted, the particle object will remain. I then schedule that child to be destroyed after a second, so that the object wouldn't remain in the scene forever.

This system seemed to work perfectly, and everything was done.

However, I wasn't happy with the fact that the particles were barely visible in the first person, and I didn't want my new-found particle knowledge to do to waste. So I decided to implement one final thing, which was a particle screen overlay which would signify that a powerup was active.

This ended up being quite easy to do, all I did was add a new object to the player camera with a particle component which would have the visual effect I wanted. I then just temporarily activated it during the effect, and then disabled it.

There was one major issue caused by this method, however. To achieve the effect I wanted, I had the particles move at different distances to the player's camera, however, this would cause them to be blocked by other objects in the scene...

The solution to this was very simple actually. All I did was change the material of the particles to a new custom one and changed the shader of said material. I tested loads of different shaders to find one which would render through walls as I needed, and finally, I found the GUI/TextShader which did exactly that.

And boom, the powerup prototype was finished.

Conclusion

So, overall I think these past few weeks went quite well. Looking back at the code I had made I have noticed many potential ways I could have improved it, but I see that as a positive rather than a negative since it shows that I am improving my programming capabilities and learning quickly. I think a lot of this is helped by the fact I am also developing my own personal Unity game on the side now, so that is helping me expand my knowledge greatly in order to improve more for Don't miss the bell.

These weeks also felt much different to any of the other dev-diary entries so far as I really felt as though I was creating my own thing, rather than following guides and other help online. This made it much easier to reflect upon certain decisions and point out certain flaws in my execution.

I'm excited to work more on this and hopefully create a game I can be much prouder of compared to my recent attempts.

Media