Let's take plants growing as an example.
Suppose you have a tomato plant that grows in 4 hours. While the player is in the game you're probably calculating it like this:
tomato_grow_time = 4 * 60 * 60; /* 4 hours */
function update(seconds_since_last_draw) {
tomato_plant.age += seconds_since_last_draw / tomato_grow_time;
if (tomato_plant.age >= 1) {
/* plant is finished growing */
}
}
and you're calling update
every frame. What would happen if you instead called it only when the player next logged in, instead of every x seconds? It'd still work, except the if
condition would occur too late.
Instead of thinking of it in imperative terms, think of it as a function:
function tomato_plant_age(time) {
age = (time - tomato_plant.start_time) / tomato_grow_time;
}
Now you can calculate when the age exceeds 1 (e.g. the plant is finished growing), using simple algebra:
age = (time - start_time) / grow_time
solve for time when age = 1
...
time = (age * grow_time) + start_time
You don't really have to update every x seconds. You go through each of the plants and compute the time when they're finished growing. Take the min() of these to figure out the first plant that will trigger a notification. That's the only notification the app has to send out (unless your app repeatedly notifies, in which case you take all of them instead of the min() of them).
On Facebook, Farmville doesn't even notify you, so it's even simpler. They just update the plant ages when you next log in, or if someone visits your farm. If nobody looks at the farm, there's no update.
This approach only works when the updates are simple. It's one of the reasons these types of games tend to be very simple — it makes it easy to scale.