Every agent has a private state. Is the agent of height 1 or height 2? Is the agent's name "foo" or is its name = "bar"? These properties are expressed and saved on the agent's state.
Your agents can have any fields you want. Here's an agent that uses the Monte-Carlo method to approximate the value of pi via randomness:
// LeaderAgent{agent_name: "leader",behaviors: ["spawn_samples.js", "estimate_pi.js"],spawned_datapoints: 0,neighbor_points: 0,pi_estimate: 0,position: [0, 0, 0],search_radius: 1,}
Notice how we use multiple custom fields to store data in the agent.
The state object has accessor methods for getting and setting state.
state.get(field_name)
: returns the value of the field
state.set(field_name, value)
: sets the field as the value
Example:
This behavior takes in the current state and context of the agent, adds 1 to the age property stored on the state, and then returns the state.
const behavior = (state, context) => {let age = state.get("age");age += 1;state.set("age", age);}
def behavior(state, context):age = state.get("age")age += 1state.set("age", age)
Important: Only the agent can modify its own state. If an agent wants to prompt another agent to perform a state change, it can send a message to trigger an update.
Agents can read one another's state - for example if agent "foo" is a neighbor of agent "bar", agent "bar" can access the fields of agent "foo", it just can't make any changes to those fields. That's what makes the state private.
HASH also has a "modify" helper function which allows you to make certain state changes a one-liner:
state.modify(field_name, function)
will allow you to pass a function that will be run on the given field in the agent's state. The above example can now be written like so:
const behavior = (state, context) => {state.modify("age", age => age + 1)}
# We haven't yet enabled this helper function for Python
The state value will be set to the return value of the function. If you use a method that modifies a variable in place, likeArray.push(x)
the return value is x
and not the modified array.
While an agent can store arbitrary data in its own state, some state values have special meaning in HASH. The fields below are all reserved, in addition to fields tied to visualization which can be found here.
{agent_id: string // auto-created identifier. Agents receive messages to their ID.agent_name: string // optional identifier. Agent's receive messages to their name.behaviors: [] // Filenames of the behaviors that the agent apply to advance their state every simulation step N to N+1.messages: [] // Outbound messages from agentposition: [x, y, z] // displays agents in the viewer and used to calculate neighborssearch_radius: number // context.neighbors() will return a list of all the agents within the search radiusdirection: [x, y, z] // Will affect the visualization of the agent. Can be used for custom logicvelocity: [x, y, z] // Will affect the visualization of the agent. Can be used for custom logiccolor: string // Color of the agentrgb: [r, g, b] // Color of the agent represented as an rgb arrayheight: number // Height of the agent in the 3D Viewerscale: [x, y, z] // Agent model will be scaled along the corresponding axesshape: string // Determines the shape of the agent in the 3D Viewerhidden: boolean // Determines whether the agent is hidden in the 3D Viewerposition_was_corrected: boolean // Used by the agent whenever agents reach topology bounds}