Global - theRAPTLab/gsgo GitHub Wiki

See !110, !181


[[TOC]]

Overview

Global properties are maintained by a global agent. The global agent is just another GAgent and has all the capabilities of the GAgent.

There are two ways to access global properties:

  1. Via the global context

  2. Via global prop methods

global context is by far the easier method. (Global prop methods are a historical artifact: they were added prior to the global context approach and still work.)

global context -- Recommended Approach

!181

A global agent context is passed to all scripts. This means that any script can reference global properties directly by using global.

For example, let's say you've defined a global property sparkCounter, in a Moth script you can now do this:

prop global.sparkCounter add 1

NOTE for Population methods lke agentsForEach that pass agent context, global is still available, e.g. this works:

// 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 }} [[ ... ]]
]]

Deprecated: Global Prop Methods

(Global prop methods are a historical artifact: they were added prior to the global context approach and still work. But the recommended method is to use the `global context' method described above.)

In order to plot properties that span agents, e.g. summative properties like "number of light moths", we've added the ability to add and track properties for a Global Agent.

This is still a very rough early take as we figure out how the Global Agent should and should not be used. Expect this to change.

addGlobalProp method

Adds a GVar property to the global agent.

Syntax

featCall Global addGlobalProp <propertyName> <GVar Type> <value>

where <propertyName> is the name of the property, e.g. "darkMoths", <GVar Type> is Number||String||Boolean, and <value> is the initial value to set the property to.

globalProp method

Access the GVar methods of the global property.

Syntax

featCall Global globalProp <propertyName> <GVar Method> <...params>

where <propertyName> is the name of the property, e.g. "darkMoths", <GVar Method> is a method such as value or setTo or add etc, and <...params> are any parameters the method requires.

Example

featCall Global globalProp darkMoths add 1


Global Agent Properties

roundTime

The roundTime property reflects the current Round timer counter. e.g. if time elapsed in round is 5 seconds, then roundTimer = 5.

How it Works

  1. During sim-rounds' StageInit, a roundTime property is added to the global agent.
  2. At StartRoundTimer, the global roundTime property is set to 0.
  3. With each tick, the roundTime property is updated to match the TIMER_COUNTER.

Getting the Property

Since roundTime is a property of the global agent, any agent can access it by adding the Global feature. Usually we use this in the context of an expression, e.g.:

ifExpr {{ agent.callFeatMethod('Global', 'getGlobalProp', 'roundTime').value > 5 }} [[
  // do something  
]]

See !165


Full Example

The key to using Global Properties is figuring out where to define them.

In this example, we define the global properties with the reporter instance "Light Moths" line graph agent, but update the property value whenever a new moth is triggered.

# BLUEPRINT Reporter
# PROGRAM DEFINE
useFeature Global
// note we do not define the global property here

We define the global property in the instance initScript. This way it is created by the instance. (We could define it in the # BLUEPRINT Reporter script, but this makes the connection between the global property and the instance clearer.

// Light Moths Instance Init Script
{
      id: 1402,
      name: 'Light Moths',
      blueprint: 'Reporter',
      initScript: `
featCall Global addGlobalProp lightMoths Number 0
featCall AgentWidgets bindGraphToGlobalProp lightMoths 30
`
}

So the reporter should now display line graph updates whenever the global property lightMoths changes.

We want to change lightMoths count when a new Moth is spawned. So this code goes into the Moths script:

# BLUEPRINT Moth
# PROGRAM UPDATE
when Moth centerTouches TreeTrunk [[
  every 1 [[
    ifExpr {{ agent.getProp('energyLevel').value > 90 }} [[
      // SPAWN!
      featCall Population spawnChild [[
        // new spawn init script (not current agent)
        // spawn randomly darker
        featProp Costume colorValue subRnd 0.5

        // add point to global graphs
        ifExpr {{ agent.prop.Costume.colorValue.value < 0.5 }} [[
          // add a point here so the graph shows a new point with no change in value
          // this is also needed if we have a `darkMoths` graph that we want to synchronize with
          featCall Global globalProp lightMoths add 0
        ]] [[
          featCall Global globalProp lightMoths add 1
        ]]
      ]]
    ]]
  ]]
]]

Issues

  • Be careful about where and when you define global properties. It is easy to inadvertently redefine the same property (e.g. if you define a particular global property whenever you spawn a new agent, the duplicate definitions will trigger an error.

  • Be careful about where and when you update global properties. It is easy to try to set a property before it has been defined.

We probably need to rewrite Global Properties better address these situations. Perhaps it needs to be explicitly defined with its own script as a root agent.

⚠️ **GitHub.com Fallback** ⚠️