Population - theRAPTLab/gsgo GitHub Wiki

See !108


TABLE OF CONTENTS

[[TOC]]


POPULATION MANAGEMENT


createAgent method

The createAgent Population method will create a new agent from any Blueprint.

Syntax

featCall Population createAgent <blueprint> [[ <initScript> ]]

  • <blueprint> is the name of any blueprint defined in the project.
  • You can specify an <initScript> with the call. Like Instance Editor initScripts, this will be run after # PROGRAM INIT. Keep in mind the context of the script is the newly created agent, so stack operations do not work like you would expect.
  • Children are spawned at the same position as the parent by default, so you can use the initScript to move the position of the child.

How to Use It

  1. useFeature Population
  2. Specify a blueprint to use, e.g. featCall Population createAgent Algae
  3. Specify an init script to run after the agent is created.

Example:

useFeature Population
# PROGRAM UPDATE
every 1 runAtStart [[
  // spawn
  ifExpr {{ agent.getProp('energyLevel').value > 90 }} [[
    featCall Population createAgent Algae [[
      // newly spawned Algae's initScript
      prop energyLevel setTo 40
      featCall Costume setGlow 1
      prop x add 25
      prop y add 25
    ]]
    prop energyLevel sub 50
  ]]
]]

spawnChild method

The spawnChild method will essentially clone an agent and then run an initScript on the clone.

All agent.prop properties are copied, as are all agent Features and Feature properties (though this may need a little more testing to make sure there aren't weird interactions).

NOTE the inferred agent context in the spawnScript is the child agent, not the parent. The child's properties will have already been set to the parent properties before the script is run. This is so you can mutate the parent color.

NOTE the parent agent is not removed.

Syntax

featCall Population spawnChild [[ <spawnScript> ]]

where <spawnScript> is a script that will run in the child agent's context.

Example

      featCall Population spawnChild [[
        // context is child agent
        // spawn randomly darker
        featProp Costume colorValue subRnd 0.5
        prop x addRnd -50 50
        prop y addRnd -50 50
      ]]


removeAgent method

The removeAgent Population method will remove agents on the stage, for example, if a predator eats a moth, this will remove the moth.

Syntax

featCall Population removeAgent

  • The agent to be removed is the agent running the script.

How to Use It

  1. useFeature Population
  2. Specify an existing agent to remove, e.g. featCall Population removeAgent

Typically this will be used in a conditional, so you would also pass the agent context, e.g. featCall Moth.Population removeAgent

Example:

# BLUEPRINT Moth
# PROGRAM DEFINE
// support removal by Predator
useFeature Population
# BLUEPRINT Predator
# PROGRAM UPDATE
when Predator touches Moth [[
  featCall Moth.Costume setGlow 1
  every 2 [[
    featCall Moth.Population removeAgent
  ]]
]]

NOTES:

  • Note that this script is in Predator, but the Moth has to have added the Population feature.
  • The idea behind every is to delay the removal by 2 seconds so have to hold the position and it doesn't immediately disappear. This becomes especially important with jittery PTrack inputs.

getRandomActiveAgent method

Returns a random agent of blueprint type that is not inert. This is generally not used directly by students but by other Population feature methods.

Syntax

featCall Population getRandomActiveAgent <blueprint>

where <blueprint> is a blueprint name, e.g. "Moth",


GLOBAL POPULATION MANAGEMENT


oneAgentReproduce method

Pick one random non-inert agent of type bpname and call SpawnChild.

Syntax

featCall Population oneAgentReproduce <bpname> <spawnScript>

where <bpname> is the name of a blueprint, e.g. "Moth", and <spawnScript> is a gemscript that will be run by the newly created agent.

Example

featCall Population oneAgentReproduce Moth [[
  prop x setTo 0
  prop y setTo 0
  prop colorIndx addRnd -1 1 true
  propPush colorIndx
  featPropPop Costume colorScaleIndex
  prop frame setTo 0
  prop vulnerable setTo 1
  featProp AgentWidgets text setTo ''
  featCall Movement setRandomPosition
  featCall Movement wanderUntilInside TreeTrunk
]]


populateBySpawning method

When called, populateBySpawning will generate n number of agents.

n is defined by the Population targePopulationSize prop.

If Population deleteAfterSpawning is true (default), any parent agents that spawn will be immediately deleted.

The agents are spawned by walking down existing non-inert agents and cloning them. Depending on the targetPopulationSize and the number of non-inert agents, some agents may get cloned multiple times. Use the initScript to mutate the cloned agents.

Syntax

featCall Population populateBySpawning <blueprint> [[
  <initScript>
]]

where <blueprint> is the name of a blueprint, e.g. "Moth" and <initScript> is a GEMSCRIPT that will be immediately run in the context of the newly created agent. Use this to do things like set position and size and other instance-specific values.

Typically you would also set targetPopulationSize and deleteAfterSpawning first, e.g.

featProp Population targetPopulationSize setTo 10
featProp Population deleteAfterSpawning setTo false
featCall Population populateBySpawning <blueprint> [[
  <initScript>
]]

targetPopulationSize property (GVarNumber) Default 1

deleteAfterSpawning property (GVarBoolean) Default true


spawnMutationProp property

spawnMutationPropFeature property

spawnMutationMaxAdd property

spawnMutationMaxSubtract property

  • If you want to mutate a prop, just set spawnMutationProp.

  • If you want to mutate a featProp, set both spawnMutationProp and spawnMutationPropFeature

  • You can still also call the automated spawn scripts (populateBySpawning, oneAgentReproduce, agentsReproduce) without setting spawnMutation props and handle the mutations by hand.

IMPORTANT: The properties are set ONLY for the agent calling the script. So generally you'll want to set the properties right before you call the spawnScript. If you want to get fancier than that, pay attention to contextual agent that you're setting the properties for and make sure the spawnScript is called by the same agent. e.g. if you set the spawnMutation props in a round initScript (which is run in the GlobalAgent context), but call populateBySpawning from a Moth or Predator script, no mutation will occur because the spawnMutation props were set for the GlobalAgent, not the Moth or Predator.

Example

This is a round initScript (that runs in the GlobalAgent context):

// Spawn New Moths
featProp Population spawnMutationProp setTo 'colorScaleIndex'
featProp Population spawnMutationPropFeature setTo 'Costume'
featProp Population spawnMutationMaxAdd setTo 1
featProp Population spawnMutationMaxSubtract setTo 3

featProp Population targetPopulationSize setTo 2
featCall Population populateBySpawning Moth [[
  // spawn near the parent
  prop x addRnd -64 64
  prop y addRnd -64 64
  // show the color index label
  featPropPush Costume colorScaleIndex
  featPropPop AgentWidgets text
]]

How it works

  1. During the spawn call (agentsReproduce, oneAgentReproduce, or populateBySpawning), the spawnMutation properties are read from the agent executing the spawn call and spawnChild is called.
  2. spawnChild creates a spec for the new agent to spawn and saves it to an AGENTS_TO_CREATE array.
  3. Regular execution resumes...
  4. At the next SIM/CREATE phase, m_Create is called, which loops through the AGENTS_TO_CREATE array, creating new agents based on the specs.
  5. All props and features are copied from the parent to the new agent.
  6. For each agent, if the spec includes a spawnMutation record, the system will mutate the spawnMutationProp randomly, within the range defined by the spawnMutationMaxAdd and spawnMutationMaxSubtract values. It uses addRndInt for the operation. (Since the props were already copied, the mutation should be applied to the inherited parent values).
  7. Any spawn script is then run after the mutation.

agentsForEach method

agentsForEach allows you to iterate over all agents of a given blueprint. This is primarily intended for use in round scripts (initScript and endScript).

Syntax

featCall Population agentsForEach <blueprint> [[ <script> ]]

Where <blueprint> is a blueprint name, e.g. "Moth", and <script> is the GEMSCRIPT you want to run on each agent.

NOTE the context that is passed to the <script> is that of the individual <blueprint> instance and NOT the parent agent/round that is running the agentsForEach method. For example:

featCall Population agentsForEach Moth [[
  featProp Costume colorValue sub 0.1
]]

...would run featProp Costume... call on each Moth agent.

NOTE with !181, the global agent is now passed to all script blocks, so scripts can access global properties. This enables calls like this:

// ROUND INIT SCRIPT
// Global Prop
addProp roundCounter
// Round Init Processing
featCall Population agentsForEach TreeTrunk [[
   // 'global' here would refer to GlobalAgent, not TreeTrunk
   ifExpr {{ global.getProp('roundCounter').value > 1 }} [[ ... ]]
]]

Example

This will darken all the non-inert TreeFoliage objects as part of an initScript.

featCall Population agentsForEach TreeFoliage [[
  featProp Costume colorValue sub 0.1
]]

agentsForEachActive method

agentsForEachActive is the same as agentsForEach, except that the script is only run for active (e.g. non-Inert) agents.


releaseAllAgents method

Used to release all agents from cursors. Typically used in a round initScript after a round is completed and you're preparing for a new round and want all users to select a new character.

You can also release after a round is stopped if you want student-controlled cursors to stop moving agents around.

Syntax

featCall Popuation releaseAllAgents

See 9a6c1094c24b7ffb31b510b16f6091a0b38f0e5e

releaseInertAgents method

Used to release only inert agents from cursors. Non-inert agents will remain attached to their cursors. Typically used in a round initScript after a round is completed and you're preparing for a new round and you want only users whose characters have "died" to select a new agent.

You can also release after a round is stopped if you want student-controlled cursors to stop moving agents around.

Syntax

featCall Popuation releaseInertAgents


STATISTICS


getActiveAgentsCount method

Returns the number of active (non-inert) agents of a particular blueprint type.

Syntax

featCall Population getActiveAgentsCount <blueprint>

where <blueprint> is the name of a blueprint, e.g. "Moth".

Since this returns a value, most likely you'd use it in an ifExpr. See the example below.

Example

// Stop sim if no more agents
ifExpr {{ Moth.callFeatMethod('Population', 'getActiveAgentsCount', 'Moth') < 1 }} [[
  featCall Predator.Timer stopRound
]]

countAgents method

countAgentProp method


minAgentProp method

maxAgentProp method


countAgentsByPropType method

countExistingAgentsByFeatPropType method

See Histogram


monitoredAgent prop

monitoredAgentProp prop

These properties are used by countAgentProp to set the agent and property to be counted. Call countAgentProp without parameters to use these values.

The monitoredAgent and monitoredAgentProp properties are an alternative to passing a ton of parameters to the countAgentProp method. Specifically, they were designed for students to use the Script Wizard UI to change the monitored agent.

You can still call countAgentProp with explicit parameters to temporarily override the monitoredAgent and monitoredAgentProp values.

Example

featProp Population monitoredAgent setTo 'Plant'
featProp Population monitoredAgentProp setTo 'energyLevel'
featCall Population countAgentProp

is the equivalent of

featCall Population countAgentProp `Plant` `energyLevel`
⚠️ **GitHub.com Fallback** ⚠️