# How do I store and handle time in social game?

I intend to develop a social game on flash like farmville. I have got a problem in event time handling though. For Example, if I breed a horse in game and I don't feed it every hour then its health points will decrease. If I log out of the game for 3 days, when I log in again the horse will be dead. I was thinking I would save the last time the user fed the horse in a database, then when the user logs in again I will compare the current time with the time stored in the database.

The problem is, I think this is not an efficient way of doing it. Can anyone show me a more efficient way of doing that?

I'd appreciate anyone who could show me a way.

• I think this belongs on GameDev – Mahmoud Hossam Mar 25 '11 at 4:48
• Why isn't it efficient? You don't use any resources when the user is offline, and calculate everything as soon as it's needed.. Sounds very efficient to me. – vstrien Mar 25 '11 at 8:02
• I think It's not efficient because I must save time in database any action of user. For example, time when user feed horse, time when user wash horse, time when user plant a plant,...Many queries will be excuted in database at the same time. What if we have 5000 users then that's really a mess! – justin Mar 25 '11 at 8:23
• If you need this data you'll have to store it. That's the easy part. If this becomes a mess depends only on your database design. You'll have a record for the plant anyway and it won't give problems to have a few additional fields like time_planted, last_watered and so on. In business applications this kind and amount of data is quite common. Having fields like created_at, last_edit, booked_at is quite common for much more than 5000 users and millions of records with bookings or similar actions. – thorsten müller Mar 25 '11 at 8:56
• I don't see why this is inefficient either. If you're already storing user actions in the database then adding a Timestamp field is trivial. (If you're not storing user actions, you might consider doing that for logging and metrics purposes anyway.) – Ian Schreiber Apr 1 '11 at 19:48

First where do you store the current state of their entire "farm". It's obviously not on the user side. It must be on the server side. If you are storing the entire state of the farm which would include each horse and the amount of energy they have then you are correct.

This is how I would handle it.

You store the farms current status which is made up of everything and their current decaying energy value. The rate of decay is where time comes in. It is a function based on how much they were fed and how fast the energy from said food decays. You don't store their feed times, you store their current state and the last time of update for the entire farm.

When they send a request for an update then you look at their last overall update time and then send back the new state of the farm and all of the decayed energies.

The update request is going to be the same whether it be right when they log in, or in a polling situation every 10 seconds. Client side if you want a finer time window than 10 seconds you can have their client update the decayed values, but always verify when the new server update comes in 10 seconds. (Or whatever time frame you choose)

So Old Solution:

New Solution:

EDIT: Just to clarify to anyone that didn't get his concern, he probably didn't like storing a last update time for each and every object in the farm. My optimization is to store a global one and instead store energies and user their respective decay functions on global updates

If I am understanding your question right, while the user is logged in and playing, time moves in normal, real-time fashion. If that is the case, you could rely on a wrapped time source where you can manipulate the current reference point in time.

I know your question specifically mentions Flash and my code example here is in Java, but I believe it should be easily adaptable for your needs:

  public class TimeSource {
private static Long staticStart = System.currentTimeMillis();
private static Long fixPoint = System.currentTimeMillis();

public static void setCurrentTimeMillis(Long currentTimeMillis) {
staticStart = System.currentTimeMillis();
fixPoint = currentTimeMillis;
}

public static Long getCurrentTimeMillis() {
Long offset = System.currentTimeMillis() - staticStart;
return fixPoint + offset;
}
}


Basically when the application starts up, we initialize to the current time in millis. However, if we set an alternate time as our "current" then the offset is calculated and used to generate the time whenever it is requested.

In the case of your game, you can set the current time to 0 when the game is very first initialized for a new user. Then, time will proceed as normal during play. When the user ends their session, you can store the current game time and restore that when the user logs in again.

Now all of your elapsed time logic can be based just on in-game time.

Thanks for your replies. I have an idea that I will store info of time in files. Everyboy have a separate file store their "last-times". How do you think about that? would reading and writing file speed is faster than call in database?

• You shouldn't answer your own question with another one. – Jonas Byström Mar 28 '11 at 9:23
• Use the DB, for the same reason you use a DB. Speed of the DB can be "configured" if ever necessary. – Jonas Byström Mar 28 '11 at 9:24
• Files will perform much worse if you have to query stuff (eg. get me the last time user X fed the horse). – bummzack Mar 28 '11 at 11:55

Having such restrictions on your players would get extremely annoying for them very quickly. You're effectively forcing them to be online and playing your game nearly 24/7.

What will happen when a user can't log on for a few days because they're on a vacation? All their animals and plants would die, there might be other disasters. Not very userfriendly.

Better to stop the timer when the user logs off, and start it again when he next logs on. Effectively their farm only exists when they're on the server (except of course that noone can buy land on its area, if you're working with such a system).

• I disagree. It's a question of what game he wants to design. Some are more involving, some are less. Not every game that doesn't appeal to the casual players who only have 1 hour a day is non-user-friendly, it's just less casual-user-friendly, which is completely fine if that's what the game designer wants. If you have to log in every day to "survive" in the game it's fine if that's what the game designer wants. About the vacation thing some games have special systems for exactly that purpose, like when a friend takes over your account for a while with limited privilages :) – Zaky German Mar 28 '11 at 16:03

If you are concerned with the volume of operations in the database, you should have a look at a databse that supports sharding well. As your query path is essentially a key lookup you are free to choose from a number of databases. I would recomend MongoDB as it has native drivers for many languages, and is extremely easy to manage.

I would not recommend you store this in files, as a database system can better optimize performance by keeping part of the data in ram and apply indexing on keys (depending on file system file access performance can degrade quite dramatically as the number of files in a folder increases). Also, when you need to distribute load to more servers it is much easier when you have a database that can do sharding and balancing for you.