Created
February 27, 2018 15:31
-
-
Save selfsame/6474fa911fb2769ba42e99bcb6ced602 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[data] | |
Game entities are hashmaps. | |
{:id 5 | |
:hp {:max 100 :current 50} | |
:sentient true | |
:name "frog" | |
:color :green} | |
mud.data/DB is a flat map of {id data}. The id space is global for all | |
types of entities (room/player/item). | |
IEntity protocol will work on id numbers or the data literal. Cross references | |
to entities should use the integer id. | |
(!set 5 :color :red) | |
(!update-in some-ref [:hp :current] inc) | |
Entity definitions are loaded from edn files. Definitions are referred to | |
by unique keywords :items/chest | |
When definitions are instantiated into the game, they are given an :id entry | |
and registered into the DB. | |
[Component Systems] | |
An entities top level key/values are considered components. | |
Components can have lifecycle methods. | |
(:init :destroy :merge :copy :serialize :deserialize :validate) | |
These allow configuring new components, cleaning up, and handling | |
special data types. The first argument is the entity instance, from which | |
the component data can be derived by it's name. | |
validate is called when a component has been changed, or possibly for | |
each component on initialization (which can handle schema changes for the DB) | |
(fn [o value] | |
(if-not (int? value) 10 value)) | |
{:name :items/chest | |
:capacity 10 | |
:contents [:items/dagger :rodents/mouse]} | |
(component :contents | |
(init [o] | |
(mapv instantiate (-> o :contents))) | |
(destroy [o] | |
(mapv destroy (-> o :contents)))) | |
Game logic leans heavily on dispatching behaviour for an object based on its | |
components. | |
[dialogue] | |
Dialogues represent state machines for a player, they are declared | |
by a hashmap. | |
{:state :start | |
:start | |
(fn [this client input] | |
(write client "enter your name") | |
(assoc this :state :name)) | |
:name | |
(fn [this client input] | |
(if (valid-name? input) | |
(do (write client "welcome " input) | |
nil) | |
(do (write "invalid name, try again") | |
this)))} | |
State functions return a modified dialogue map. Usually this means changing | |
the :state. Returning nil ends the dialogue. | |
When a player has a :dialogue entry, input handlers are routed. | |
(defn dialogue-input [client input] | |
(let [dialogue (:dialogue client)] | |
(if-let [f (-> dialogue :state)] | |
(!set client :dialogue | |
(f dialogue client input))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment