121 lines
3.4 KiB
Plaintext
121 lines
3.4 KiB
Plaintext
|
|
Effect Monoids
|
|
==============
|
|
|
|
Idea
|
|
----
|
|
Conceptually, a collection of stacking effects can be considered a monoid.
|
|
|
|
Definition
|
|
----------
|
|
An effect monoid should have the following defined:
|
|
|
|
A set of values that can represent an effect in this group (domain)
|
|
|
|
At least one of the two:
|
|
|
|
A combining function: should be a binary operation that forms a monoid on
|
|
the domain (i.e. is associative, and has an identity)
|
|
|
|
A folding function: combines all the elements in a table, according to
|
|
some monoidal combination. Now you get a combining function, just put
|
|
the two elements in a table. Using that combination function to combine
|
|
all the values in the table should be equivalent to just applying the
|
|
folding function.
|
|
|
|
If both are defined, then the combining function should give the same
|
|
answer as putting the two elements in a table and folding.
|
|
|
|
For optimal performance, you should define both.
|
|
|
|
An identity: Something in the domain, that when combined with another element,
|
|
always results in the other element.
|
|
|
|
A function to apply effects to the player (A function for cancel is unneeded,
|
|
just apply the identity). Using the identity should put the player in some
|
|
sensible default state.
|
|
|
|
Optionally, it can have
|
|
|
|
A function ran on every change, in case special effects or messages should be
|
|
displayed. This will probably only be run when the player in question is
|
|
online.
|
|
|
|
|
|
Effect Types
|
|
============
|
|
|
|
Definition
|
|
----------
|
|
Perhaps there can be two kinds of effect types, static and dynamic.
|
|
|
|
A static effect type should have the following properties
|
|
|
|
A name
|
|
A display name
|
|
A set of string tags
|
|
A map from monoids it is in to associated values
|
|
A set of players it applies to (possibly include a special value for global?)
|
|
Whether it is hidden from the players it applies to
|
|
Whether it should be cancelled on death
|
|
|
|
A dynamic effect type should have the following properties
|
|
|
|
A name
|
|
A display name
|
|
A set of string tags
|
|
A set of monoids it can apply to
|
|
A function for serializing the table of monoid things it has
|
|
(Default minetest.serialize)
|
|
A set of players it applies to
|
|
Whether it is hidden from the players it applies to
|
|
Whether it should be cancelled on death
|
|
|
|
|
|
Effects
|
|
=======
|
|
|
|
Definition
|
|
----------
|
|
The following properties:
|
|
|
|
A unique ID
|
|
A type (static or dynamic)
|
|
An associated effect type
|
|
A duration (can be permanent)
|
|
|
|
If its type is a dynamic effect type, it can also have a table of values
|
|
to use. Any value not in the table will be treated as the identity. The default
|
|
is an empty table.
|
|
|
|
|
|
API
|
|
===
|
|
A way to get an effect's information by id
|
|
|
|
A way to get a relational table of effects (with operations like Haskell's ixset)
|
|
|
|
Indexed by:
|
|
|
|
Effect monoid (many-to-many)
|
|
Player name (many-to-many)
|
|
Tag (many-to-many)
|
|
Name (one-to-many?)
|
|
Whether it is permanent
|
|
|
|
Simpler operations on top of the relational interface
|
|
|
|
|
|
Implementation
|
|
==============
|
|
Effects can be arranged in a relational table like an ixset, but ordered only on
|
|
their unique ids. A set with id ordering can be represented with a map from id
|
|
to effect record. To serialize, can additionally keep another map from id to
|
|
record, that just holds all the effects.
|
|
|
|
When a player is on the server, the temporary effects they have should be kept
|
|
track of and updated, otherwise should be removed from activity.
|
|
|
|
Only allow effects with a duration of a second?
|
|
|
|
Configurable effect update timestep? |