Agent Birth & Death

By default agents within FLAME GPU cannot die or create new agents. In order to enable the checks and processing required for either of these operations, they must be enabled first.

Agent Death

When an agent in FLAME GPU is killed, it is removed from the simulation and all data held in the agent’s variables is discarded.

Enabling Agent Death

By default in FLAME GPU 2 agents do not die. To enable death for a particular agent function, use the setAllowAgentDeath() method of the AgentFunctionDescription that you would like to enable death for:

flamegpu::AgentFunctionDescription agent_fn1_description = agent.newFunction("agent_fn1", agent_fn1);
// Allow agent_fn1 to kill agents
agent_fn1_description.setAllowAgentDeath(true);

When this agent function is then added to a layer or dependency graph, it will support agent death.

Killing Agents via Agent Functions

To have an agent die, simply return flamegpu::DEAD (pyflamegpu.DEAD in Python) instead of flamegpu::ALIVE (pyflamegpu.ALIVE in Python) at the end of a death-enabled agent function. You can use conditionals to only have agents die according to a certain condition:

FLAMEGPU_AGENT_FUNCTION(agent_fn1, flamegpu::MessageNone, flamegpu::MessageNone) {
    // Get the 'x' variable of the agent
    int x = FLAMEGPU->getVariable<int>("x");

    // Kill any agents with x < 25
    if (x < 25) {
        return flamegpu::DEAD;
    } else {
        return flamegpu::ALIVE;
    }
}

If flamegpu::DEAD (pyflamegpu.DEAD in Python) is returned by an agent function whilst agent death is not enabled the agent will not die. If FLAMEGPU_SEATBELTS error checking is enabled an exception will be raised.

Agent Birth

The agent creation interface usable in agent functions is only able to create a single agent per existing agent per iteration. Additionally, the type (and state) of the agent being created must be earlier specified as part of the model description (a single agent function can only output one specific agent type and state). Agent’s can also be created via host functions, that may be more applicable in cases where many agents must be created from a single source.

Agent birth from agent functions is always considered optional, any agent which sets an output agent’s variables will cause the output agent to be created.

Note

Agents created by agent functions do not exist until the next layer.

Enabling Agent Birth

To create agents from agent functions, you must specify the type of agent the function produces when defining your agent functions, by passing it a reference to the AgentFunctionDescription. If using states you can additionally specify the state the agent should be created within:

// Create a new agent type 'example_agent'
flamegpu::AgentDescription example_agent = model.newAgent("example_agent");

...

// The agent type 'example_agent' is set as the agent output type
// To be output in the default state
agent_fn1_description.setAgentOutput(example_agent);

// The agent type 'example_agent' is set as the agent output type
// To be output in the state 'living'
agent_fn2_description.setAgentOutput(example_agent, "living");

Creating Agents via Agent Functions

When agent output has been enabled for an agent function, the FLAMEGPU->agent_out (pyflamegpu.agent_out in Python) object will become available within agent function definitions. This can be used to initialise the properties of the newly created agent.

Much like the agent’s variables, setVariable() can be used on this object, to set the new agent’s variables. Additionally, getID() may be used to retrieve the new agents future ID.

Agent variables which are not manually set will be initialised with their default values.

Agent creation is always optional once enabled, a new agent will only be marked for creation when either setVariable() or getID() are called.

FLAMEGPU_AGENT_FUNCTION(OptionalOutput, flamegpu::MessageNone, flamegpu::MessageNone) {
    // Fetch this agent's id
    flamegpu::id_t id = FLAMEGPU->getID();

    // If its id is even, output a new agent, otherwise do nothing
    if (id % 2 == 0) {
        // Output a new agent with its 'x' variable set to 500.0f
        FLAMEGPU->agent_out.setVariable<float>("x", 500.0f);
    }

    // Other agent function code
    ...
}

If FLAMEGPU->agent_out is used in an agent function which has not had agent output enabled, no agent will be created. If FLAMEGPU_SEATBELTS error checking is enabled, an exception will be raised.