mirror of
https://github.com/evennia/evennia.git
synced 2026-04-03 22:47:16 +02:00
Continue reworking/refactoring the tutorial docs
This commit is contained in:
parent
b97d3581eb
commit
77e78573ca
18 changed files with 741 additions and 926 deletions
|
|
@ -1,30 +1,27 @@
|
|||
# Command Cooldown
|
||||
# Adding Command Cooldowns
|
||||
|
||||
> hit goblin with sword
|
||||
You strike goblin with the sword. It dodges!
|
||||
> hit goblin with sword
|
||||
You are off-balance and can't attack again yet.
|
||||
|
||||
Some types of games want to limit how often a command can be run. If a
|
||||
character casts the spell *Firestorm*, you might not want them to spam that
|
||||
command over and over. Or in an advanced combat system, a massive swing may
|
||||
command over and over. In an advanced combat system, a massive swing may
|
||||
offer a chance of lots of damage at the cost of not being able to re-do it for
|
||||
a while. Such effects are called *cooldowns*.
|
||||
a while.
|
||||
|
||||
This page exemplifies a very resource-efficient way to do cooldowns. A more
|
||||
'active' way is to use asynchronous delays as in the [](Howto-Command-Duration.md#blocking-commands), the two might be useful to
|
||||
combine if you want to echo some message to the user after the cooldown ends.
|
||||
Such effects are called *command cooldowns*.
|
||||
|
||||
## The Cooldown Contrib
|
||||
```{sidebar}
|
||||
The [Cooldown contrib](../Contribs/Contrib-Cooldowns.md) is a ready-made solution for command cooldowns. It is based on this howto and implements a [handler](Tutorial-Peristent-Handler) on the object to conveniently manage and store the cooldowns.
|
||||
```
|
||||
This howto exemplifies a very resource-efficient way to do cooldowns. A more
|
||||
'active' way is to use asynchronous delays as in the [Command-Duration howto](./Howto-Command-Duration.md#blocking-commands) suggests. The two howto's might be useful to combine if you want to echo some message to the user after the cooldown ends.
|
||||
|
||||
The [Cooldown contrib](../Contribs/Contrib-Cooldowns.md) is a ready-made solution for
|
||||
command cooldowns you can use. It implements a _handler_ on the object to
|
||||
conveniently manage and store the cooldowns in a similar manner exemplified in
|
||||
this tutorial.
|
||||
## An efficient cooldown
|
||||
|
||||
## Non-persistent cooldown
|
||||
|
||||
This little recipe will limit how often a particular command can be run. Since
|
||||
Commands are class instances, and those are cached in memory, a command
|
||||
instance will remember things you store on it. So just store the current time
|
||||
of execution! Next time the command is run, it just needs to check if it has
|
||||
that time stored, and compare it with the current time to see if a desired
|
||||
delay has passed.
|
||||
The idea is that when a [Command](../Components/Commands.md) runs, we store the time it runs. When it next runs, we check again the current time. The command is only allowed to run if enough time passed since now and the previous run. This is a _very_ efficient implementation that only checks on-demand.
|
||||
|
||||
```python
|
||||
# in, say, mygame/commands/spells.py
|
||||
|
|
@ -49,7 +46,7 @@ class CmdSpellFirestorm(default_cmds.MuxCommand):
|
|||
"Implement the spell"
|
||||
|
||||
now = time.time()
|
||||
last_cast = caller.ndb.firestorm_last_cast # could be None
|
||||
last_cast = caller.db.firestorm_last_cast # could be None
|
||||
if last_cast and (now - last_cast < self.rate_of_fire):
|
||||
message = "You cannot cast this spell again yet."
|
||||
self.caller.msg(message)
|
||||
|
|
@ -58,22 +55,21 @@ class CmdSpellFirestorm(default_cmds.MuxCommand):
|
|||
# [the spell effect is implemented]
|
||||
|
||||
# if the spell was successfully cast, store the casting time
|
||||
self.caller.ndb.firestorm_last_cast = now
|
||||
self.caller.db.firestorm_last_cast = now
|
||||
```
|
||||
|
||||
We specify `rate_of_fire` and then just check for a NAtrribute
|
||||
`firestorm_last_cast` and update it if everything works out.
|
||||
We specify `rate_of_fire` and then just check for an [Attribute](../Components/Attributes.md) `firestorm_last_cast` on the `caller.` It is either `None` (because the spell was never cast before) or an timestamp representing the last time the spell was cast.
|
||||
|
||||
Simple and very effective since everything is just stored in memory. The
|
||||
drawback of this simple scheme is that it's non-persistent. If you do
|
||||
`reload`, the cache is cleaned and all such ongoing cooldowns will be
|
||||
forgotten.
|
||||
### Non-Persistent cooldown
|
||||
|
||||
## Persistent cooldown
|
||||
The above implementation will survive a reload. If you don't want that, you can just switch to let `firestorm_last_cast` be a [NAtrribute](../Components/Attributes.md#in-memory-attributes-nattributes) instead. For example:
|
||||
|
||||
To make a cooldown _persistent_ (so it survives a server reload), just
|
||||
use the same technique, but use [Attributes](../Components/Attributes.md) (that is, `.db` instead
|
||||
of `.ndb` storage to save the last-cast time.
|
||||
```python
|
||||
last_cast = caller.ndb.firestorm_last_cast
|
||||
# ...
|
||||
self.caller.ndb.firestorm_last_cast = now
|
||||
```
|
||||
That is, use `.ndb` instead of `.db`. Since a `NAttribute`s are purely in-memory, they can be faster to read and write to than an `Attribute`. So this can be more optimal if your intervals are short and need to change often. The drawback is that they'll reset if the server reloads.
|
||||
|
||||
## Make a cooldown-aware command parent
|
||||
|
||||
|
|
@ -154,5 +150,5 @@ you can have all fire-related spells store the cooldown with the same
|
|||
`cooldown_storage_key` (like `fire_spell_last_used`). That would mean casting
|
||||
of *Firestorm* would block all other fire-related spells for a while.
|
||||
|
||||
Similarly, when you take that that big sword swing, other types of attacks could
|
||||
Similarly, when you take that big sword swing, other types of attacks could
|
||||
be blocked before you can recover your balance.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue