Sometimes we want an event to change as the player is enjoying the game, like a fruit tree that grows from a seedling or a building being remodeled. And while we can tie those event changes to story beats, what if we tied them to time instead?
Now before we get into the tutorial itself, let’s keep in mind that these time-based events are best used sparingly. It’s a nice treat for players to find out that the hour they’ve spent enjoying your game has also unlocked a treasure or secret scene, but forcing them to wait a few minutes for every single thing to happen can be boring. Another thing to keep in mind is the methods we’ll be using to keep track of time. Switches and variables will be our best friends in this tutorial, so the more time-based events we have the more switches or variables we'll need. So a farming game where each plant needs its own timer would probably be better off with a plugin to help keep track of every single plant.
Keeping that in mind, let’s get to the eventing!
Our first method is using a custom move route in our event’s Autonomous Movement. Move routes have a built-in wait command, so we can use that to take some time before activating a switch to make the event change.
For this example, let’s set up a bush that will bloom after 10 seconds. Our bush’s event needs two pages, the first one being where the move route happens.
The move route only needs two things: the wait and a script call to turn on a self-switch. Our wait can be however long we want, we just need to keep in mind that each frame is 1/60th of a second so if we want the wait to be a full second we need a wait of 60 frames. Waits have a maximum of 999 frames (roughly 16 and a half seconds), but we can put multiple waits in a row if we need a longer wait; for example, three 600-frame waits in a row turns into 30 seconds.
Once the wait is over, we need a script call to turn on/off a self-switch, $gameSelfSwitches.setValue([mapId, eventId, 'A-D'], true/false); . Since we want to turn on our bush’s self-switch A, we know that we want our ‘A-D’ part to be ‘A’ and the true/false to be set to true. That leaves us with our mapId and eventId left to fill out. Now, normally we’d need to check our event ID and our map ID, but there are some little tricks we can use instead of those numbers.
Since the script call is happening in the event’s custom Autonomous Movement, we can use $gameMap._mapId to get the current map ID and this.eventId() to get the bush’s event ID. So we can stick $gameSelfSwitches.setValue([$gameMap._mapId, this.eventId(), 'A'], true); into our bush’s move route to have it turn on the event’s self-switch.
Our bush’s second page shows once its self-switch A is on, showing off the bush’s bright flowers.
In this example I’ve added the ability to turn the bush back into its non-flowering self when the player clicks on the event with a simple control self-switch event command so that we can see the move route in action more than once.
Now we can playtest to make sure it all works.
As we’ve learned, it’s pretty straightforward to set up but has a few major issues that we’d need to keep in mind. Event move routes reset when we leave the map, which means if we had a minute wait and our players leave the map after only 45 seconds then the timer would reset back to the full minute when they returned to the map. Move routes also pause if the player moves too far from them on a map, so on a big map it’s possible for our players to wander off and the events won’t update.
So if our player is going to be spending a lot of time on the same map or if we’re not too concerned about the exact timing of the event (such as if we’re using it just as a decoration), this method could work fine. Otherwise, we’d be better off using our next method.
Another way to make time-based events is to base it on play time. While the game is being played the play time keeps increasing so we can use it to check the passage of time for events. But setting a variable to the player’s current play time and comparing it with the play time in the future, we can set up events so that they’ll change in 30 seconds, 5 minutes, or even a full hour later.
Play time can be easily set to a variable using the Game Data section of the control variable command. If we use that then the play time in seconds can be stored, so all we need is to do a little math to figure out the time in minutes or hours.
To see a simple example of this in action, let’s make a sleeping man who will eventually wake up and start moving around. His event’s first page is both where we let the player know that the event will change later and where we set the current play time.
Since we don’t want the man’s play time variable being reset each time the player tries to talk to him, we can stick the control variable command in a conditional branch that only activates if the variable is zero. That way, once we’ve set the variable the branch won’t activate again.
His second page shows when the ‘man has woken up’ switch is on, letting the man wander the map.
With his event ready to go, we need an event that will keep track of the current play time and compare it to the man’s saved play time. In this case, setting up a common event where we can keep track of all of our time-based events seems like the best option.
We can set up a conditional branch to check if the man’s play time variable doesn’t equal zero (since if it equals zero then the player hasn’t activated the timer yet), and set up the timer checks inside that. To see how much time has passed we can set a separate variable to the game’s current play time and subtract the man’s play time from that.
Once we know how much time has passed since the man’s event was activated, we can use a conditional branch to check if enough time has passed. In this case, if at least 30 seconds have passed then we’ll turn on the ‘man has woken up’ switch as well as set the man’s play time variable back to zero so that this section of the common event will no longer run.
Now we just need to call the common event when we want to check it. One way we can do that is to call the common event at map transfers. By checking at map transfers, we can make the changes to events without the player realizing exactly when those events are updated. All the player will know is that the man was sleeping when they were on the map before and when they visited again he was awake.
But what if we want the event to update while the player is on the same map as the event? In that case, we could use an event on that map set to parallel process to call the common event as often as we want. We just need to make sure to include a wait so that the event isn’t being run multiple times a second, since that could cause lag.
With the common event being called, we can test and make sure the man wakes up in-game.
This method works great with a single change, but what if we wanted a multi-stage event like a growing flower? It’ll use the same concept with a time-keeping variable, but instead of turning on a switch we’ll be increasing another variable when the play time has passed certain points.
We can see this in action by making an event where the player can plant a seed that will grow into a small plant when the stage variable is at 2 and then a bunch of flowers when that variable hits 3.
Then all that’s left is to add some conditional branches to our time-checking common event so that our plant’s stage changes, first growing into a small sprout after 5 seconds and then into full flowers after 15 seconds. We could make the times much longer, but for testing it’s easier to keep things short just in case we’ve done something wrong.
Once our additions are in, we can see the plant properly grow as time passes in our playtest.
And with that, now we can add time-based events to our games! How would you use time-based events in your game, would you reward players with secret areas that are excavated after an hour of playing, or would you include a garden that ends up overgrown while the hero is off adventuring?