Rounds - theRAPTLab/gsgo GitHub Wiki
See !113
TABLE OF CONTENTS
[[TOC]]
Mini-Rounds support was built for the Moths activity. It involves MANY features scattered across the system.
See !113 Mini-Rounds for testing procedure.
You can define rounds in the project script file, e.g. aquatic.js
.
Rounds have two options:
(Not currently implemented)
Default: 'true'
If set to 'true' the "RESET STAGE" button will be available at any time. If set to 'false' the "RESET STAGE" button will only be shown during PRERUN.
Default: false
If set to true
, rounds will stop after all predefined rounds have been run.
If set to false
or not defined, rounds will loop, going back to round 1 once you've reached the last round.
You can define as many rounds as you want.
If you don't define any rounds, the system will by default let you run and endless round, and allow you to re-run the round after stopping.
time
defines the length of the round, in seconds. Each round can have a different timer setting.
If time
is not set, the timer will not be used and the round will continue until someone presses "STOP ROUND".
Each round can have an optional intro
and outtro
message.
intro
is shown at PRERUN.
outtro
is shown at STOP.
Each round can have a separate initScript
and endScript
.
initScript
runs when the user presses "PREP NEXT ROUND".
endScript
runs when the round is stopped either by the timer, script command, or if the user presses the "STOP ROUND" button.
Scripts are run in the context of the GlobalAgent. By default GlobalAgent has the Population feature enabled. Any other features need to be added manually. They can be added in the initScript
.
You can use the initScript
, for instance, to remove dead Moths and spawn new Moths from any remaining Moths.
export const MODEL = {
label: 'Moths',
rounds: {
options: {
allowResetStage: false,
noloop: true // stop after last round
},
roundDefs: [
{
time: 10,
intro: 'First generation',
initScript: `dbgOut 'Round1!'
// demo: add AgentWidgets so we can stuff more messages into the intro text
useFeature AgentWidgets
featCall AgentWidgets showMessage '1. Press "PREP COSTUMES" to put on costumes.'
featCall AgentWidgets showMessage '2. Press "START ROUND" when ready!'
`,
outtro: 'What happened?',
endScript: `dbgOut 'END Round1!'`
},
{
time: 60,
intro: 'Spawned and mutated!',
initScript: `dbgOut 'Round2'
// Release Cursors from Dead Moths
featCall Population releaseInertAgents
// Remove Dead Moths
featCall Population hideInertAgents
// Spawn New Moths
featCall Population agentsReproduce Moth [[
prop x addRnd -64 64
prop y addRnd -64 64
featProp Costume colorScaleIndex addRnd -2 2 true
// featCall Costume randomizeColorHSV 1 1 1
]]
featCall Population agentsForEach TreeFoliage [[
featProp Costume colorValue sub 0.1
]]
`,
outtro: 'What happened to spawn?',
endScript: `dbgOut 'END Round2!'`
}
]
},
}
Agent colors can be assigned to a predefined series of colors in a graded scale. To use this feature, you need to:
- Define the colorscale:
intHSVColorScale
- Set a Costume property:
colorScaleIndex
featCall Costume initHSVColorScale <baseHue> <baseSaturation> <baseValue> <type> <count>
where
-
<baseHue> <baseSaturation> <baseValue>
defines the starting color of the scale. -
<type>
defines the color dimension to vary:hue
,saturation
, orvalue
-
<count>
is the number of steps in the scale.
featCall Costume initHSVColorScale 0 0 1 'value' 11
This will create a scale of 11 gray values. 0 0 1
is white, since there is no saturation and value is maxed.
To set the agent to a color, just set the colorScaleIndex
property. The corresponding color will be automatically applied during the VIS_UPDATE
cycle.
colorScaleIndex
is a GVarNumber, so you can use GVar math.
We implemented this as a featProperty so that you can easily do math with it.
For example, this will set the agent to the 9th color in the scale.
featProp Costume colorScaleIndex setTo 9
For example, this will change the colorScaleIndex
value by a random value up to +/-2.
featProp Costume colorScaleIndex addRnd -2 2 true
In order to support integer random numbers, we've introduced a new flag that can be used with the GVarNumber random number routines. Passing true
will force the random number to be an integer.
e.g. colorScaleIndex addRnd -2 2
might result in adding 1.8593234
e.g. colorScaleIndex addRnd -2 2 true
might result in rounding up 1.8593234 to 2.
agentsForEach
allows you to iterate over all agents of a given blueprint. This is primarily intended for use in initScript
and endScript
.
NOTE: agentsForEach
only operates on non-Inert agents. It skips over inert agents.
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.
This will darken all the non-inert TreeFoliage objects as part of an initScript
.
featCall Population agentsForEach TreeFoliage [[
featProp Costume colorValue sub 0.1
]]
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
]]
- Agents now have a
visible
property so that they can be both inert and hidden from view, but still available as a data object for inspection.
showMessage
will display a message in a popup modal dialog window with an "OK" button.
If you send multiple messages before the user has clicked OK, each subsequent message will appear on a separate line in the dialog window.
NOTE: No formatting is allowed in the message. If you want separate lines, send a second message.
featCall AgentWidgets showMessage '<string>'
where <string>
is your message.
featCall AgentWidgets showMessage 'Hello World'
You can stop a running round via script using the stopRound
method.
featCall Timer stopRound
This will stop a round after all Moths are gone:
useFeature Timer
// Stop sim if no more agents
ifExpr {{ Moth.callFeatMethod('Population', 'getActiveAgentsCount', 'Moth') < 1 }} [[
featCall Predator.Timer stopRound
]]
See !117
You can edit a previously-defined round using the Main SETUP editor. This is rudimentary functionality for students to be able to edit how rounds are run. The focus of the functionality is providing students with a UI to tweak existing parameters for a round. It's ugly but functional.
- Go to
http://localhost/app/main?model=moths-sandbox
- Click on "SETUP"
- The rounds editor should appear in the upper left. You should see two rounds you can edit.
You can change any value, save it, and see the results with the next round.
For example:
- Change "time" to 5
- Click "SAVE"
- Click "PREP ROUND" and the time should update to show 5 seconds.
- Click "START ROUND" to play the round. The round should only play for 5 seconds.
You can change other parameters the same way.
Try modifying the intro and outScripts to handle different conditions.
- label -- A human-friendly label. This is only used in the "EDIT ROUNDS" UI to help you remember what the round is about.
- time -- Number of seconds to run for the round.
- intro -- A short message that will be displayed when the user clicks "PREP ROUND"
- outro -- A short message that will be dsiplayed when the round ends.
- introScript -- A GEMSCRIPT that will run when the round is initialized when the user clicks "PREP ROUND". Use this to clean up old agents from the previous round and generate/mutate new agents.
- outScript -- A GEMSCRIPT that will run when the round ends. Do any post-round processing here. NOTE: Don't reset agents yet if you want students to review existing agent conditions -- use the introScript for that.
- You cannot add new rounds via the UI. -- To add a new round, edit the script in the project file.
- You cannot add new script lines via the UI. -- To add a new script line, edit the script in the project file.
- You cannot change the existing script lines beyond changing
prop
andfeatProp
keywords. - Currently, any nested script lines (e.g. in an
when
orifExpr
condition) can not be edited as well. Hopefully this will be fixed with #233 - The UI is very rough -- it's a small panel and can be difficult to navigate to view all of the information hidden in it. We will adjust this in a future pass if we have time. The current goal was to get something operational out the door.
- As with the rest of the ScriptEditor, script changes are not currently saved to a database.