Population - theRAPTLab/gsgo GitHub Wiki
See !108
TABLE OF CONTENTS
[[TOC]]
The createAgent
Population method will create a new agent from any Blueprint.
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.
useFeature Population
- Specify a blueprint to use, e.g.
featCall Population createAgent Algae
- 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
]]
]]
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.
featCall Population spawnChild [[ <spawnScript> ]]
where <spawnScript>
is a script that will run in the child agent's context.
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
]]
The removeAgent
Population method will remove agents on the stage, for example, if a predator eats a moth, this will remove the moth.
featCall Population removeAgent
- The agent to be removed is the agent running the script.
useFeature Population
- 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 theMoth
has to have added thePopulation
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.
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.
featCall Population getRandomActiveAgent <blueprint>
where <blueprint>
is a blueprint name, e.g. "Moth",
Pick one random non-inert agent of type bpname and call SpawnChild.
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.
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
]]
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.
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>
]]
-
If you want to mutate a
prop
, just setspawnMutationProp
. -
If you want to mutate a
featProp
, set bothspawnMutationProp
andspawnMutationPropFeature
-
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.
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
]]
- During the spawn call (
agentsReproduce
,oneAgentReproduce
, orpopulateBySpawning
), the spawnMutation properties are read from the agent executing the spawn call andspawnChild
is called. -
spawnChild
creates a spec for the new agent to spawn and saves it to an AGENTS_TO_CREATE array. - Regular execution resumes...
- 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.
- All props and features are copied from the parent to the new agent.
- 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). - Any spawn script is then run after the mutation.
agentsForEach
allows you to iterate over all agents of a given blueprint. This is primarily intended for use in round scripts (initScript
and endScript
).
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 }} [[ ... ]]
]]
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
is the same as agentsForEach
, except that the script is only run for active (e.g. non-Inert) agents.
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.
featCall Popuation releaseAllAgents
See 9a6c1094c24b7ffb31b510b16f6091a0b38f0e5e
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.
featCall Popuation releaseInertAgents
Returns the number of active (non-inert) agents of a particular blueprint type.
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.
// Stop sim if no more agents
ifExpr {{ Moth.callFeatMethod('Population', 'getActiveAgentsCount', 'Moth') < 1 }} [[
featCall Predator.Timer stopRound
]]
See Histogram
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.
featProp Population monitoredAgent setTo 'Plant'
featProp Population monitoredAgentProp setTo 'energyLevel'
featCall Population countAgentProp
is the equivalent of
featCall Population countAgentProp `Plant` `energyLevel`