On 05/09/2010 03:38, Metin Akat wrote:
I asked this on #couchdb but it seems like the middle of the night is
not the best time for having such discussions there :)
I can imagine - a few sleepy people, not wanting to get in to a deep
subject.:)
Imagine Farmville, although my use case is not exactly the same.
Players in Farmville plant some crops and they grow up after some
time. Let's say 5 hours.
If we want to implement something like this in couchdb, how would you
do it, in a crash proof way? It's something like a _changes listener,
but well, happening some (long) time after the change has happened.
Your requirements appear to be very close to those of simulation.
I would divide the activities up in to two classes: starts and finishes.
For example your crops start growing only when someone plants. They
become ready 5 hours/months later and rot in the field unless the player
has the resources to harvest them before 6 month/hours.
In a real simulation of something like a factory or a road network, your
starts always require resources. If the resources are available the sim
starts them. If not the work waits. Later when the processes finish, the
finishing process release resources. A finish cannot require a resource,
becasue it may not be available.
In your case you may not need to handle resources at all, because you
are not waiting to start work, you are starting something when the
player requests it.
However, you have a takt time (http://en.wikipedia.org/wiki/Takt_time)
and you may need to progress various processes every clock tick.
I think you need a queue, in couchDB, of when things will happen in the
future. The time is not real clock time, but game time, so if the server
crashes, all clocks stop.
As part of the click tick event, you check the queue and take all the
actions queued for this time tick.
For the processes you add the processes to the list of tasks you have to
do this time tick, until it is finished, and then remove it from the list.
When your player plants, you add two events to the queue. One in 5
"months" to set the crop ripe, and one in 6 to set the crop rotten, and
away it goes. When it ripens you mark it ripe. If it is not harvested,
then the "is rotten" event marks it rotten.
If and when the player starts to harvest the crop, you set a process to
harvest an amount every tick, until it is done or the crop becomes rotten.
There are many ways to handle the rotting. You can add it at the
beginning, or when recording the crop as ripe. You can remove it from
the queue when the crop is harvested, or let it fire and ignore it if
the crop has gone. Letting it fire and ignoring it is usually more
reliable.
If harvesting will take some time, and you don't want the overhead of
acting each tick, you might start the harvest and queue up the end
harvesting event. Then you must calculate the result of the harvest when
the first of "harvest end" or "is rotten" events go off, and either
remove the other or ignore it when it fires.
Regards
Ian