Sunday marked the 4th and final day of the Game Jam. Presentations for the various games that had been made were not slated to occur until later in the afternoon/evening, so the morning became an “all hands on deck” dash to get everything put together and working as much as possible.
I woke up early on Sunday in order to try and maximize the amount of time I had in order to get everything ready on my end for the enemy AI setup, as I still had at least one more enemy to fully implement, the “Frightened” enemy type. Once I got to my desk to start coding, however, I was informed that the rotational system I had previous implemented was actually something that should be left in for only certain enemy types that needed to be marked as doing that type of behavior (i.e. the spider and the yet to be added mouse enemies). Along with that, I was asked to set up the enemies Unity Scriptable Objects, which was a system I had never used before.
Putting the rotational system back in place was not as much of a challenge as I had originally anticipated, as I was able to grab the code from a previous version thanks to the power of source control. I simply took the old rotational code I had made, cleaned it up a bit, and merged it with my new rotational code and used a Boolean value to determine which rotational code needed to be used to rotate the character.
Using a Boolean value to determine which type of rotation system the NPCs should use was also made easier with the use of Unity Scriptable Objects. While it took me a while to figure out what a Unity Scriptable Object was, and I got a bit confused on how they worked, after being shown how to roughly set them up and use them by a fellow team member I quickly understood their use. I transitioned most of the settings from the original script to the Unity Scriptable Objects code file, and linked the two together such that updating the settings in the Scriptable Object changed the way different NPCs performed. Using this system also allowed the Game Designers to create multiple different NPC types that follow the same general behavior patterns, which became very useful even in my own testing as I created a “SUPER Angry Spider” NPC that I made incredibly fast and powerful in order to test various systems. When I needed to refine pre-existing systems by adding more variables into the mix to alter the way things functioned (such as adding different types of speed the enemies would use depending on what they were doing), adding this in such that it could be understood and editable by an outsider became much easier.
Once the Scriptable Objects had been fully setup the way I needed them to be and the rotational system was fully reimplemented, I began working on finishing up the frightened mouse NPC that I had only barely started working on the day before for 10 minutes at best. I coded the mouse to,as with all NPCs, utilize the wander function to travel within a certain area when there are no players nearby. Beyond that, however, I setup a “FleeFromPlayers” function to accomplish the behavior of having the mouse, as the function title implies, run away from nearby players.
Setting this script up was actually relatively simple once I was able to plan out what I wanted to happen on a pencil and piece of paper. Essentially what happens is the NPC checks the location of nearby players, and when players enter the “aggro zone” that got setup for aggressive NPCs, instead of chasing after them they will instead add them to a list object for nearby players. Once the nearby players are added to the list the method then builds an average direction vector the mouse should travel towards in order to get away from the players by getting the positions of the players in relation to the mouse and turning that into a directional vector. I also made it so that the mouse would use a “Charge Speed” variable I had setup for the aggressive NPCs as the speed at which the mouse runs away from the players. Once this was implemented and functioning properly, I then went into the task of setting up the rotations in the event the mouse was marked as being one that should rotate. This was not entirely that difficult, I only needed to take a step back and go through what the code I had written was doing to find the places I needed to make code changes for flee rotations to work smoothly.
After the mouse was setup, I then went about the task of seeing how it would work in one of the actual levels that had been built as opposed to my own personal test scene that I had setup. One problem I noticed almost immediately was that the mouse was able to easily fly off the map and go through the walls when chased to that point. I then decided to try and find a solution to this, and in order to do this I had to look into the Unity Tilemap system, as it was used to build the level maps. I found that there was a way to get the bounds of the Tilemaps, much like you are able to get the bounds of various colliders. One thing that I did initially get confused by with the new system though was that instead of using Vector 2s and Vector 3s, it insead used Vector Ints, which was a data type I had not previously used. It took a bit of trial and error and digging, but I found out there was a way to convert a Vector2 into a Vector2Int. Once I had gotten that setup, I tried making it so that the mouse would stay within the boundaries of the “Wall” Tilemap that the designers has put in place to keep the players from moving beyond the map. This was moderately successful, as I employed a similar tactic for making sure the other enemies stayed inside their wander zones when not chasing the player, however the mouse would go just beyond the wall so that it was still out of the player’s reach. Initially I thought this would be an issue but then thought it was like the mouse escaping through cracks in the walls, as the setting for this game was in an old dungeon. I discussed it with the other developers and the designers are we decided it was a cool feature, so the players had to be quick and strategic in order to get the mouse.
Once the mouse NPC was completely setup, we decided to merge the branches together to see how everything worked on a singular branch. Initially things were looking good, but then after merging one branch in particular that had many changes to core systems, we realized things were no longer functioning properly. There was a huge miscommunication issue that seemed to crop up in the last couple of hours as a team member tried to redo a lot of systems that had been put in place the night before the final day. Unfortunately, the team member that made many changes to the core mechanics was unable to get everything straightened out in time and get everything working in unison before the end of the game jam, although some things were thankfully able to return to a functional state.
Once the time came for work to finish on all the projects, we went down a few floors for all the teams to present their games. The games that were presented all looked amazing considering the limited amount of time and resources available to work on them. I was particularly impressed by the fact that the “Strike Counter” game was able to get networking setup, and the amount of detail and presentation of the game “Beat the Boss”. While I did not do the presentation for our game, those who were presenting had to restart the game an unfortunate number of times due to bugs that popped up in the last minute due to the breakdown in communication on how the systems worked together. Overall though, they were able to present the game all the way through (without going into any of the enemy AI mechanics due to some of the issues) and we got some great feedback on how the game could potentially be brought over to either Nintendo Switch or Mobile devices.
After the Game Jam presentations were done, we all gathered outside to take a group photo with all those who participated in the Game Jam to go on a wall of fame for the lab. Unfortunately, I was unable to locate a copy of this photo as of yet.
After the Game Jam was over, we headed back to the hotel to rest up for a bit, but then set out to go find dinner. We headed over to a burger restaurant called Road House. I was informed on the way over to the restaurant that there was a triple-patty burger that could be eaten, and felt I had been issued a challenge. Soon after getting there however, I learned that not only was there a triple-patty burger but also a five patty burger, and those who fully ate it were placed on a wall of fame in the restaurant and got a hoodie.
I decided in the end not to order this burger, and instead went with this three patty burger. It quickly turned out that my eyes were bigger than my stomach, as I was not even able to finish the three patty burger, and in the end had to box it up for later. Along with that, I also had the opportunity to try a hot sauce called “100% pain”. Being the brave lad that I am, I decided it would be an excellent idea to dunk an entire french fry in the sauce then immediately put it in my mouth. Within seconds my face felt like it was getting exponentially hotter and tears started forming in my eyes. Luckily a good friend that was with us ran to go get me some milk for instant relief, and I decided it would be in my best interest to not try that sauce again.
After dinner concluded, we decided to go on a trip to get Ice Cream, but learned that all of the nearby Ice Cream places had closed. So, instead of getting a delicious frozen treat, we instead went for a long walk reminiscing about the past week and ended up in a beautiful section of the park in the center of Paderborn where we sat by the river continuing to talk. After spending some time at this park, we then returned to the hotel so we could rest up for our trip to Frankfurt (after a very tearful farewell to those who would not be joining us in Frankfurt).
Game Jam thoughts: Overall, I feel like I performed well in the Game Jam. I learned a lot about different systems present in Unity and how to better code with other people who may not know that much about coding in mind for those who will need to design levels. This particularly came to the front when I learned about using Unity Scriptable Objects. I spent most of my time this Game Jam working on the enemy AI, in addition to discussing with the other coders ways in which they could solve the problems they were having with things such as player controls. I was a bit disappointed that my hard work was not able to be showcased for the presentation, as a core element that enabled player and enemy AI interactions to function properly was altered to the point that the enemies no longer detected the player, no were consumed when the player crashed into them. Along with that, systems that the other developers had made for various things the player was supposed to be able to do were also rendered non-functional, and when I sat down with them to try and get them working we were unsure how we could go about bringing them back up in time as many of the core files for the game had been significantly altered. I did, however, learn a lot about quaternion math in Unity and how to go about programming different enemy AI interactions. I would be very interested in fixing up the project from its current state in the future, and go ahead with building it up more and maybe even move it to console.