This is the first article in a series of articles on the subject of game mechanics for PBBGs. In each article I will take up one interesting "take" or "example" of a game mechanic which I hope can serve as inspiration to you as a game developer.
In this first article, we're going to cover what I've have found to be an very cost efficient way to process game progression when dealing with a multitude of characters across an entire player base.
I am currently working on a project where I had to ensure progression was occurring on an ongoing basis with a system where each player could have anywhere from 1 to 30 characters. One character at first and progressively more and more as you continue to play the game. In my initial approaches, I calculated player progression every 6 seconds. But when I had to deal with character progression, the number of calculations increased significantly. Trying to scale this up to an estimate active player base of about 300 players within a couple of months became tricky.
I am personally very fond of idle games that run on a 6 second game loop, so that was my initial approach. I tried to tweak this to longer durations but it didn't seem to solve the core of the problem: too many processed actions per player in a short time span.
I realized that in idle games with a 6-second tick, players never watch every tick go by, but instead the combination of those ticks over a longer period of time yields enough resources and progression to allow meaningful interaction within the game. The idea of a 6-second tick gives players a sense of constant progression, but increasing the tick speed to a minute and offsetting the rewards would not work for me.
To address this, I came up with a solution. Each character has a progress value that gets incremented by 1 every 6 seconds. I run a separate query to check which characters have built up enough progression points to go above the threshold for their current activity (in my project it was various types of jobs). Any character that returns as eligible to complete their job gets processed and moved onto the next job, removing the threshold value from their current progress value.
I took it further by adding individual stages within each job and storing the character progression on the job model itself. I even allowed jobs to be attended by multiple characters, which allowed jobs to stay idle until multiple characters signed up to participate. Any job progression not achieved on the 6-second turns is progressed toward a buffer stored on the character, which players can use to speed up jobs or perform extra duties.
Step by Step
Here is a breakdown in sequence of the approach I took for calculating this:
- Calculate how much time has passed since last tick. Divide that by your tick speed and call that value for "TicksToProcess". I added this approach so that in case of any potential server lag, players would not loose any progression.
- Increment all active jobs "ProgressValue" by the value stored in "TicksToProcess".
- Increment all idle characters "IdleValue" by the value stored in "TicksToProcess".
- Do a database query to check for any active jobs that has it's progress greater than the threshold for completion and/or any stage within that job that has reached the threshold greater for it's completion. I went with stages due to the nature of the game design, but this is not required.
- I then process each completed job/stage and reduce from the "ProgressValue" the amount consumed (the threshold value).
- At this point in time, I then decided to go with updating the active job to whatever the next job is set to, and the cycle begins anew.
Its worth it to note that the processing of each of the completed jobs can be abstracted away into being calculated by other processors. I went with NodeJS and a system of workers which communicate through a queue system. This allowed me my main node instance to stay free of clutter and focus solely on handling communication to all clients and dealing with the very minor database input/output as described in point #1, 2, 3 &4.
Optional: On points #3 & 4, you can add limiting factors such as only active players who has been online in the last 12 hours, or you can implement an action system where players have to increase their daily actions regularly)
PRO'S & CON'S
There are several benefits from this approach, here are some:
- Minimizes calculations needed to track player and character progression.
- Offers a constant sense of progression for players, as they see something happening all the time.
- Flexibility to allow players to participate in jobs and progress through stages at their own pace.
- Potential to add further customization through individual stages within each job.
- Allows for multiple characters to participate in jobs, which could lead to new gameplay opportunities.
However there are also some negative aspects of this:
- May be confusing for some players to understand the concept of a 6-second tick.
- Could limit players who want to actively participate and see progression in real-time.
- The separate queries for character progression could potentially slow down the overall game performance. There are ways to counter this through intelligent database design so as to not having the tables locked down by tons of processed jobs.
- The added complexity of individual stages and multiple characters participating in jobs could be challenging to implement and balance.
I believe this approach works well in my above circumstance, however it might not work well for all games and this specific implementation may not be what is right for your game.
They key thing that lead me to look into this approach and which ultimately swayed me to go with it, was that for the great majority of idle games you're not reliant on watching the monitor for every 6 second tick to go by, and most of the time "playing" the game you're actively doing something else in your life.
From this fact I extracted the concept of hiding the actual progression through a plain increment of numbers and allowed to minimize the amount of processing to be done every single turn, and decreases the number of completed functions to run from "# of Characters" multiplied by "# of players" every 6 seconds into a couple of jobs per player every minute. I further expanded upon this and allowed more difficult jobs to require more than one character decreasing the amount of records to update every 6 seconds in my database.
I hope this mechanic and this train of though has been an interesting read for you and hope you find usefulness in it for your future endeavors.
This article was one in the first of many to come on the subject of game mechanics. The next article will cover how to implement rarities into your game and an unique twist on it.
If you have any particular game mechanic you want me to cover feel free to reach out to me either in the PBBG Discord (Vuy), or send me an email on [email protected]
Opus Vrye is an idle incremental PBBG in development that is set in the Steampunk theme, with both active and passive aspects. It's currently in a very early development phase, but with the majority of all mechanics and features already detailed out.