ID:1817699
 
(See the best response by Ter13.)
Code:
mob
var
list/cds = list()
dt

proc
setCD(cooldown, delay=0, time=0)
if(delay)
time = world.realtime + delay
cds[cooldown] = time
return time

getCD(cooldown)
if(cooldown in cds)
cdc = cds[cooldown] - world.realtime
return cds[cooldown] - world.realtime
else
return 0


Trying to make a cooldown system, but I can't get it to be perfect. Worldtime only seems to change every 50 seconds, making it completely unreliable for small cooldowns. I could use server time, but if the server crashes/reboots etc, the cooldowns will be based on when the server crashed(If someone used a skill that has a 2 second C/D when its 20:00:00 server time, the CD is up at 20:00:02 but if the game crashes during the CD the server time will be 00:00:00 and the CD will still be 20:00:02). I can reset the C/Ds upon login, but they players can relog to reset cooldowns. Inconsequential for the small C/Ds, but 1min+ C/Ds can be really abused by this. I realize I could use world time for long cooldowns and server time/reset on login for small cooldowns, but the 50 s difference between worldtime changes is still too much for 1min - 5min c/ds. Is there any other way of making cooldowns much more efficient?
World.realtime isn't very accurate. World.timeofday is more accurate. However, if your cooldowns don't carry over between character logs, all you would need to use is world.time, it relies on server ticks.

Best response
Store cooldowns in delta format.

mob
var/tmp
list/cds = list()
proc
setCD(id,delay)
. = world.time + delay
cds[id] = .
getCD(id)
. = cds[id]
if(.==null)
return world.time

Write(savefile/F)
..()
var/time = world.time
var/val
var/list/l = list()
for(var/v in cds)
val = cds[v]
if(val>time)
l[v] = val
F["cds"] << l

Read(savefile/F)
..()
F["cds"] >> cds
var/time = world.time
for(var/v in cds)
cds[v] += time


That way, you only store how much time is left on the cooldown, and when you load the savefile again, it's trivial to use world time anyway.

Edit: Forgot to mark cds as temp so manual saving will work.
Personally, I'm not a fan of the idea of saving cooldowns on world exit. Generally when people log off it's for a duration longer than typical cooldowns so there isn't much point to it. And it's a lot less messy.
Personally, I'm not a fan of the idea of saving cooldowns on world exit. Generally when people log off it's for a duration longer than typical cooldowns so there isn't much point to it. And it's a lot less messy.

Many MMOs have 30 minute, hour, 2 hour, 4 hour cooldown abilities.

Sure, there's not much point to saving a 15 second cooldown, but all it takes to abuse it is binding a macro to .reconnect.

Never trust your players.