All HASH simulations begin life in the init
file found in the root of a HASH project. In this file we generate the starting state, or initial conditions of the simulated world.
There are three ways to populate the initial state of a simulation. You can:
init.json
init.json
with behaviors that will generate agentsinit.js
or init.py
file.In init.json
you'll explicitly define all your agents as JSON blobs in an array. Here's what that might look like:
You can create whatever field names you need on your agents, but be aware of setting incorrect value types on protected fields we mentioned previously.
init.json
[
{"position": [0,0],
"behaviors": ["foo.js"]},
{"position": [0,0],
"behaviors": ["foo.js"]},
]
When you make a change to the file, you'll need to reset your simulation to see updated agents appear in the 3D Viewer.
The default init.json
approach has some limitations. Because it's compliant JSON, you can't set dynamically set properties on the agent. If you want to generate random values, or run loops to generate your agents, then init.js
or init.py
will give you that functionality.
You can transform the init.json
file into a JavaScript or Python file by right clicking it and selecting "Convert to..." your desired language.
When you do, any defined agents will be added as objects in an array named agents
.
Now you can write JavaScript or Python in the file and use it to set agent properties.
const init = (context) => {
let agents = [
{
position: [0, 0],
behaviors: ["custom.js"],
foo: Math.random(),
data: context.data()["/somedataset"][1],
},
];
return agents;
};
init.js
and init.py
must return an array of objects
To programmatically create agents, you can add loops and similar logic to append agents to the array.
const init = (context) => {
let agents = [];
for (let i = 0; i < 100; i++) {
agents.push({
position: [i, i],
});
}
return agents;
};
Within an init.js
or init.py
file you have access to the context of the simulation, where you can access the data and global variables attached to the simulation. You can use them to seed values in your initialization.
/**
* @param {InitContext} initialization context
*/
const init = (context) => {
const data = context.data();
const globals = context.globals();
let avg_age = hstd.stats.mean(data["ages.json"]);
let std_age = hstd.stats.stdev(data["ages.json"]);
let agents = [];
for (let i = 0; i < globals["num_agents"]; i++) {
agents.push({
behaviors: ["add_one.js"],
age: Math.floor(hstd.stats.normal.sample(avg_age, std_age)),
});
}
return agents;
};
The context
object in the init file is slightly different from the
context available during a simulation run. Neighbors and messages won't be
available as they don't exist before a simulation starts.
You can also make use of functions in HASH's standard library to generate agents in predefined patterns.
const init = (context) => {
const topology = context.globals().topology;
const template = {
behaviors: ["grow.js"],
color: "yellow",
};
const agents = hstd.init.grid(topology, template);
return agents;
};
You can learn more about all the init functions in the standard library in this section of the docs.
Previous
Next