Monthly Archives: November 2021

Developing Randomness in our Game: Dynamic Scaling and Relative Probability

Introduction to Randomness in Games

A brief introduction to randomness in games comes from looking at games without it. Chess is the most common example of this where every move can theoretically be calculated and optimized based on the opponent’s actions. This means that the game itself can be deterministic, as in who wins or loses is known before the game is actually played. Fortunately Chess is complex enough that humans struggle to fully enact this, but that’s why computers are often better than humans, because they can compute all the possible outcomes of each move and pick their move based on the sequence that allows them to win regardless of their opponent’s actions. Tic-Tac-Toe is a much more trivial version of this where if both players are playing optimally then the game always ends in a draw.

Situations where the end is known before the game starts tend to not be fun and people tend not to play them for long. This is why randomness is important. Even the slightest bit of randomness ensures that the outcome of a given game isn’t deterministic and therefore everyone involved has a chance at achieving the desired outcome regardless of skill level. This chance is beneficial in both winning and losing because it ensures that everyone has a chance to win, but also ensures that there’s risk of losing so that even skilled players have a reason to play and make an effort to win the game.

Randomness in Our Game

Our game is a tower defense where the player is fighting against an AI. Since it’s a single player game, there isn’t so much a focus on leveling the playing field as we generally want the player to win in this scenario or to at least feel like they had a fighting chance. In this case the major concern is that the player will figure out a strategy that will allow them to effectively ‘solve’ the game. This could potentially be a tower that is way stronger than the others, or a particularly effective combination that when replicated always defeats the enemy AI. Once they’ve found this particular strategy then the rest of the game becomes boring because it’s either not stimulating enough to force them to think or it becomes so trivial that they don’t even really need to make an effort to win the game. Our solution to this issue was to introduce randomness in the form of tower availability.

Our game will have a shop with a limited inventory where the player must purchase their towers. The current plan is to have it cycle on every wave and bring in a new inventory of options to purchase. This forces players to utilize the tools they have available to them through the shop, meaning that very rarely will they ever have the same set of options in a given level or even wave. While they can still have favorites that they prioritize through this system, it removes their ability to repeat the same strategy over and over, forcing them to think critically at every stage of gameplay and ensuring that repeated attempts at a given level will produce different results. The randomness also adds an extra avenue for strategic planning in that players will have to consider whether or not it’s worth it to buy a potentially worse tower now, or hope they can survive another wave and purchase a better one when the shop resets.

Designing the Random Inventory System

When I set out to build the shop inventory system I had two main goals in mind: dynamic scaling, where we can add new towers over time and the system would automatically adjust, and relative rarity where we could simply specify a value and the difference in that value from the other towers would determine how rare it is overall.

The dynamic scaling problem was probably the most important goal I set out to achieve as I knew we had an undefined number of towers and we would gradually add more over time. I knew it would be a nightmare to manage balancing the rarity over time, so I wanted to develop a system that simply required adding a tower type to a catalog and giving it some value for rarity and everything else would just work.

I ended up making the ‘catalog’ an array of structs containing references to the towers and their rarity. All we need for the shop to handle a new tower is to make an entry in this table

Relative rarity was the way to make an autonomous balancing system work so that we could specify how frequently a tower should spawn relative to any other towers we include. This system would gradually adjust the spawn chance of each tower over time, but would maintain the same relative frequency for each tower. For an example of how this works in the existing system we can look at a tower with 20 rarity and 100 rarity (with higher numbers being more common). In this case the 100 rarity tower would appear 5 times more frequently than a 20 rarity one (100/20 = 5) and in this case the 20 rarity tower would have 20/120 odds of appearing. If we added another 100 rarity tower then obviously the odds of the 20 rarity tower would drop significantly (20/220), however so does the rarity for the first 100 tower. The end result is that the ratio between the two spawn rates is equal in (20/120)/(100/120) = (20/220)/(100/220). What this means is that while overall spawn rates will drop across the board when we add new towers, their spawn frequency relative to each other will remain the same. With this system in place we can specify that we want a new tower to spawn five times more often than an existing baseline one simply by giving it a rarity that is five times higher than the existing tower.

This is the process by which a single tower for the shop inventory is chosen. This can be performed any number of times depending on how big we want the shop to be.

With the two major components in place, we have a rarity and selection system that will dynamically accommodate any number of towers we decide to add over the course of the project. This will enable us to worry less about managing the generation process and focus more on developing cool towers for players to use in our game.

Starting Your Project in Unreal Engine 4

Making a game is hard. It is challenging and time consuming and draining and it can feel like work at times. If it was easy then everyone would be out there making every little thing that came to their mind and there would be a lot more high quality games on the market. Getting over that first step of getting a project up and running scares away most people, but it doesn’t have to be as difficult as it might seem at first. With a bit of determination and planning you can absolutely get yourself started using an engine like Unreal Engine 4 even without any knowledge of code and game development in general.

While it can be fun to jump right in and start making things, especially if you’ve never made a game before, the key to starting a long term game project is to start in the planning phase. Without doing so it is extremely easy to get sidetracked developing a few systems while leaving yourself with an unplayable mess. This might be fine in traditional development where a finished system could exist for a long time, but in game development there’s an expectation that things will change and you could end up throwing a lot of that work and time away later if things don’t work out how you envisioned them.

The initial goal for your project should be a Minimum Viable Product or MVP. This is the bare foundation of the game with the few mechanics you need to actually play and test the core idea. The goal of developing this product first is that you’ll be able to test and iterate early so that you can find the ones that work the best or are the most enjoyable to interact with. This means you throw out less work and find a good direction as quickly as possible so you don’t find yourself restarting in the future. The process of planning your MVP can be fun as it forces you to come up with tangible ideas for what the game should look like and how each system should function. You can also use this time to categorize longer term goals and ideas that you can eventually build up to from the MVP.

When I start planning a MVP I think about my vision for the project and pick out the few fundamental systems that the player will interact with. The systems that the player controls or interacts with directly are likely to be the most important ones for your game and the ones you should develop first so that you have some basic gameplay elements to build upon. Once I’ve come up with these mechanics I’ll use a tool like Trello to map out and really drill down and figure out what the most basic components of those mechanics will look like. The image below is one such example of this with me breaking down every function the player could take to control their ‘generals’ which is the core mechanic of a game I’m developing around necromancy.

Each element in the list is mapped directly to a key or action the player would regularly take while playing the game

While that list is long for a MVP, it also makes up almost the entirety of my initial goals for the project. Once that list is completed then I’ll be able to test and iterate on the basic systems as well as start implementing some of the more complex elements like character customization and progression. This list essentially gives me a tangible goal to work through while trying to get to the ‘fun stuff’ which is actually implementing the game’s unique mechanics and elements and seeing the world come to life.

From here I simply went down the list and identified which mechanics are reliant on each other in order to eventually find my starting point. In this case ‘Move To’ was my first step because it required the least amount of moving parts since many of the other aspects required AI/behavior tree implementation. Thinking about how to implement that basic ‘Move To’ command basically led me right to where I needed to start: First the player so that they can give ‘Move To’ commands, then a system so they can aim and target where they want their minion to go, and finally the ability for the minion to receive that command and actually follow it to the targeted location. By following this pattern and really digging down into how each system works you can avoid getting stuck and unsure of what to do next because you always have that list to refer back to and to tell you exactly what else is needed to move forward.

Once that MVP checklist is completely filled out then you’re essentially free and ready to start actual development. At this point you have a functional (if very rough) game where you can test and see if your initial mechanic is actually fun to play. If not then you can try different things or add some additional features to try and find the experience that makes your game enjoyable. 

This whole process can be applied to additional features as well, giving you a clear map of how to implement a system, but at this point it’s really up to you where you go and what’s the most important part to build next. In my opinion, this is the most fun place to be in terms of development because you’ve essentially built your canvas so that now you can have fun actually implementing your cool ideas and seeing how they play and feel, you just have to power through that initial MVP phase where everything is being set up. While there are certainly more pitfalls farther down the road in game development, getting to this point can often be the hardest part. Once you’re here with a MVP and some groundwork in place, even if you don’t finish you’ll still have something functional and cool you can show off and potentially build upon later on down the line.

One final note; don’t be afraid to have a bit of extra fun, even in the MVP phase. Obviously don’t let it majorly sidetrack you from your initial goals, but if you’re making a game for yourself then you should want to work on it. It’s important to remember this and to embrace the little things you can do to make the game and the development experience more fun.

Some things are more important than others. Like skeletons. With hats.

Learning to Cook, From Someone Who Couldn’t

(BBQ chicken with cheesy bagels, I could never get over the fact that it looked like a face)

Up until last August I couldn’t cook (I was 25 at the time I started). I was never taught how by my parents as they were rarely home and I never took the initiative to learn myself because I was scared of it. I would eat out or just eat junk food instead of meals, which on top of being unhealthy was also really expensive. Then late last year my dad ended up having to make a shift in his business which left him getting home even later than before and often not having time to eat an actual meal at home (I caught him eating Ruffles covered in blue cheese dressing once and I’ll never let him live it down). This was the push I needed to teach myself how to cook, and now I cook four meals a week for both my dad and I.

(Homemade mozzarella sticks and curry)

While cooking can be intimidating if you haven’t done it before, once you start making things and developing things you’re comfortable with, you’ll always have something you can make without too much thought or effort. One thing that helped me at first was just to make things where you could buy most of the ingredients from the store so there were only a few actual steps for cooking. I started with some really simple tacos because most of the toppings you can just buy and the only thing you really need to cook is the meat. You can obviously make more than that if you want to, but you can make really good ones without having to hand make every ingredient.

The tacos I started with simply involved browning ground beef (something that is visually easy to do), which takes about five minutes at medium heat on a stove. After that I just followed the directions on the ‘Taco Seasoning’ packets you can buy at the store and mixed it into the meat with some water. That’s really it, that’s the only thing I did at first that would be considered actual cooking, but from there you can come up with all kinds of different meals depending on what ingredients you use and how you put everything together.

One of the first ‘recipes’ I would ever actually come up with was just a slight change to that process, but it made a world of difference. Instead of using water when mixing in the seasoning, I used some salsa instead and let it simmer until the liquid boiled off and the beef was thoroughly coated in whatever salsa I was using (my preference is mango habanero).

(Ground beef cooked in salsa with a bit extra on top)

We had a lot of ‘taco’ derivatives at first which led me to eventually expand my repertoire into sauteed chicken. I was super uncomfortable at first because raw chicken was scary, but I was just really cautious and if I didn’t think something was cooked enough, I would just cook it more even if it meant part of it got over done. Over time (and lots of YouTube videos) I would get more and more comfortable cooking chicken on the stove and eventually managed to figure out the right amount of time and temperature to cook it just right. Now chicken and rice with some random sauce from the store is my go to when I don’t have much time and everyone in my family has me cook the chicken whenever we’re making some at home because I’ve had so much time and practice getting everything just right.

(Chicken and rice with some sweet Thai chili sauce I bought from the store)

I’ve come up with more recipes since then like my Meat Bowl (it’s a bread bowl full of meatballs) and homemade mozzarella sticks with curry (near the top of the post, this one was incredible), but it was a gradual process that took some time and a lot of mistakes. If you had asked me a year and a half ago to cook you something, the best I could have done was probably that taco meat and even then I probably would have messed it up somehow.

(Meat Bowl, note: difficult to eat without making a mess)

In that short amount of time I’ve gone from completely terrified of anything to do with cooking, to making my own recipes (which people sometimes actually like!). If you put some effort into it and keep trying you can almost certainly reach the same point even if you were at the same place I was a year ago, barely able to cook for myself, let alone other people. Just try new things, look up recipes, and find things you’re comfortable with so you always have something to fall back on. It really is something that anyone can do as long as they put in the effort to learn and grow as a chef. The more comfortable you get making things, the more exotic and experimental you can get over time. As an example I’ll leave you with tonight’s dinner, something I came up with on the spot at the store when I wasn’t sure what to make tonight: Naan Pizza!