"Not So Random Randomness" in Game Design and Programming
In game design there is a kind of love-hate relationship with randomness. On the one hand it allows for variety with many types of content, on the other hand one can't "design" true randomness. How about a technique that provides random outcomes but within parameters that can be influenced to fit the game design?
- Limits of HTML5, Javascript and canvas with developing a "Hidden Object Game for learning languages"
- "Not so random randomness" in game design and programming
- Using a "Leitner system" to track a players exposition to content and mechanics
- Postmortem: "Pavel Piezo - Trip to the Kite Festival", a game for learning languages
Does "randomness" have to be really random?
In game design there is a kind of love-hate relationship with randomness. On the one hand it allows for variety with many types of content, on the other hand one can't "design" true randomness. How about a function that provides random outcomes but within parameters that can be influenced to fit the game design? It's little effort compared to what is gained in control, it can easily be abstracted in code and only requires holding a few more variables for every not-really-random-randomness. A quick example: how I have previously dealt with rolling dice for calculating "loot" in a "chest". (It was something different, but the mechanics are the same and the concepts of "chest" and "loot" are instantly recognizable to any game grognard.) Let's say the chance of finding a golden ticket, alongside the usual sell-loot, in a chest should be 1:10000. If you use true randomness the player may eventually find a ticket in three consecutive chests and after that she will find no ticket in three months of play. What we do first is to reduce the number 10000 by 100 with every chest opened, store this value in howLikelyIsPlayerToFindTicket and use this variable to calculate our random chance. 1:9900, 1:9800 and so on. The chances get better with every chest until, after 100 tries, a ticket is granted. Remember, it is still possible that the player finds a ticket with a chance of 1:8400 or all other combinations, the odds simply get better with every try. Additionally, when the player has found a ticket, we want her to not find another ticket again, too shortly after. We set another variable absolutelyNoTicketFindable to, say, 10. With every chest looted we make sure that no ticket is in there and decrease the variable by 1. Once absolutelyNoTicketFindable reaches 0 we go back to our initial 1:10000 chance and to reducing it by 100 with every chest opened. We introduced a few additional values: Base Chance (10000), Increase Chance (100), Blocker (10), Current Chance (X, between 10000 and 0) and Current Blocks (Y, between 10 and 0). If you are a programmer, you can already see where this is headed. I would hold BC, IC and B as statics (or in a parent class) and CC and CB as variables (or within an object or in a derived class). A function MyRandomSuccess() processes these statics and variables (or gets the classes and objects as parameters). It calculates the success with the current values, modifies the variables accordingly and simply returns true or false. Depending on how you want to influence the outcome, you can introduce as many additional values as you wish.- You can influence the success withs buffs, power-ups, in-game events or what-have-you.
- You can reduce or increase "Increase Chance" with a buff or power-up
- For a level that is playing in a "poor" area, the player never finds a ticket and finds fewer of the lootable "rare" items.
- You don't have to define a completely different lootable for every occasion. Simply tag the area or the specific chest as "poor".
- If it fits better, the value of absolutelyNoTicketFindable can be an amount of time that counts down.
- You can influence variables for e.g. "hard hit" and "critical hit" depending on the level-difference between opponents to even out the playing field in a MOBA.
- You can generate filler enemies with not-so-random-randomness strengths and weaknesses based on the players performance in the game thus far.
Related Tutorials
Lesson 1 — What C# Actually Is
Why is C# the language driving the production of thousands of indie games using Unity and custom engines all around the…
Steps to Make a Simple Game in Unity
if you’re diving into game development, Flappy Bird is basically the ‘hello world‘ of the gaming universe. It is the ul…
Automatic Tutorial Creation for Unity | No AI | No more time waste
Automatic Tutorial Maker (ATM) for Unity is a tool that automates in-game tutorial creation by recording developer acti…
Save and Load System for Godot 4 – Tutorial
Saving and loading game data is a crucial feature for any game, as it allows players to continue their progress even af…
Unity Finite State Machine Tutorial
Comprehensive tutorial on utilizing finite state machines (FSMs) in Unity game development. It explains the concept of …
Project Structure - Guide to Cocos Cyberpunk Source Code
In my previous post, I mentioned that I would be write a series of articles on Cocos Cyberpunk. So let's kick off with …
Discussion
More from Carsten Germer
Postmortem: "Pavel Piezo - Trip to the Kite Festival", a game for learning languages
Our game
Ensuring Fluent Gameplay in MusiGuess - Forward-Caching JSON/JSONP with Nginx
Querying a third-party API one of our games gets data from was sometimes getting slow. The solution: Forward-caching th…
Using a "Leitner System" to Track a Player's Exposition to Content and Mechanics
Using flashcards with the "Leitner system" is typically used by students to learn vocabulary or other facts and pieces …
Discussion