This is an overview of how I made an event system in Unity for my Business Ethics Management Simulator project and what changes I might want to add later.
The Aim of the Event System
The aim of the event system in my project is to have pop up events where the player makes choices that could affect the story or the events they get in future.
The events could be ones that happen as part of the overall story or randomly selected. I also want some events and choices to be linked, so choices you make could trigger related events later. The random events would be probability weighted so some are rarer than others.
Approach
Scriptable Object Events
For the events themselves I made a Scriptable Object template that each one would follow. The template included things like the event name, description, whether the event had happened etc.
I’d not used Scriptable Objects before in Unity. One drawback I hadn’t realised earlier was that changes made to the object at runtime (e.g. setting an event to “has happened”) wouldn’t persist between game sessions. However there are ways to save the changes to a separate file and read that back when starting the game. I’ll give this a try, but if I run into problems I’ll change the system to not use Scriptable Objects.
I saved the events into subfolders under “Resources” so I could load them all into arrays when the game starts.
Probability Weighted Events
For the random events, I made pools of events based on their probability ranging from “No Event” and “Common Events”, to “Ultra Rare”.
The probability weighting for each event pool is stored in the event management script. When its time to select a random event it will:
- Roll for a random number between 1-100
- Look through the list of probabilities and compare against the random number one by one:
- If the random number is lower then one of the probabilites, that event pool will be selected.
- If the random number is higher, it will take that probability away from the random number until eventually it is lower then one of the probabilites.
- On selecting a category (e.g. Common Events), the script will then look through all the events in that pool to play. It will look for an event that hasn’t happened yet and doesn’t have a predecessor event.
Once an event has played, the event manager will play all events linked to it before selecting another random event. This ensures the player gets to the end of an event chain, instead of starting a number of random events and potentially not seeing how they end.
Probability: Mistakes Were Made
Originally the event manager would select an event pool by seeing if the random number was lower than one probability but higher than another.
After I revisited it though I realised this wouldn’t reflect the true probability of the events, as some numbers overlapped so they’d have a different probability of happening to what I’d set. I was unsure how to work this out properly, so I was grateful to find this Unity post which had the same problem and the great response. I used the approach they made in their other post here.
My customer spawn system had the same problem as it also used probability weighting, so I went back and changed this too.
Next Steps
- Story events: these will be an extension of the current system and will be simpler to implement then random events. They will mostly follow on from each other and trigger based on the in-game date or meeting an objective.
- Writing up the events and how they link together. After I add these in game I’ll see if the current system works or if I need to add more functionality.
- Non-UI based events: this is a ‘Nice to Have’ but I liked the idea of having an event happen in game and not through UI (e.g. a special NPC appearing).