64
Multi-Agent Modelling with MARS A Handbook Julius Weyl

Multi-Agent Modelling with MARS A Handbook

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS

A Handbook

Julius Weyl

Page 2: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Contents

1 Foreword and Installation 1

2 MARS Models 3

2.1 MARS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.2 From Technical Model to MARS Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.2.1 Starting Position . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.2.2 Creating the Model Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.2.3 Advanced Model Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.3 Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.3.1 Creating Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.3.2 Using GIS Data in Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.4 Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.4.1 Creating Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.4.2 Agent Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

Agent States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Life and Death . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.4.3 Tick: Step based execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.4.4 Agent Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Positions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Moving Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Exploring the Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Finding other Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Interactions between Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Passive Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Active Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Message Passing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

Interactions with the Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.4.5 Creating new Agents during Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3 Local simulations 13

3.1 Creating a simulation config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.1.1 Globals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.1.2 Data layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.1.3 Agent parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.1.4 Agent initialization files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.1.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4 Cloud simulations 16

4.1 Preparing the Model for Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4.1.1 Opening a Command Prompt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

Mac . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4.1.2 Changing Directory to the Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4.1.3 Model File Structure and LIFEStarter . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

4.1.4 Building the Model with Dotnet Core . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

4.1.5 Creating a Model Zip File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

4.2 MARS Cloud Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

Page 2 of 60

Page 3: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

4.2.1 Creating an Account . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.2.2 Login to the System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.2.3 Working with Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.3 Importing Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.3.1 Uploading Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

4.3.2 Uploading GIS Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

4.3.3 Uploading Agent Init Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

4.4 Scenarios and result configs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

4.4.1 Creating Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

4.4.2 Filling out Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

4.4.3 Creating Result Configs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4.5 Conducting Simulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.5.1 Simulation Plans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.5.2 Running Simulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.6 Analyzing Simulation Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.6.1 Agent Populations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

4.6.2 Spatial Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

4.6.3 Agent Attribute Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

4.6.4 Download Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

5 Language Reference 30

5.1 agent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

5.2 distance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

5.3 explore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

Explore basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Explore with predicate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Null Reference Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

5.4 external . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

5.5 initialize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

5.6 kill me . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5.7 layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5.7.1 Layer Attributes and Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5.8 move . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

5.8.1 Coordinate System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

5.8.2 Movement Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

5.9 nearest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

Null Reference Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

5.10 observe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

5.11 pos at . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5.12 random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5.13 raster-layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

5.14 simtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

5.14.1 Simtime Example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

5.14.2 Simtime Example 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

5.15 spawn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

5.16 static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

5.17 tick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

5.18 ts-layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

5.19 val . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

Page 3 of 60

Page 4: Multi-Agent Modelling with MARS A Handbook

5.20 var . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

5.21 vector-layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

5.22 x-cor and ycor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

6 Cookbook 50

6.1 Example Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

6.1.1 Wolf, Sheep, Grass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

6.1.2 Chatting Agents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

6.2 Useful Code Snippets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.2.1 Agent Evolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.2.2 Agent Live Stages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.2.3 Random Walk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

6.2.4 Biomass Removal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

6.2.5 Agent Interaction: Buying Goods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

6.3 Data Usage Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

6.3.1 Agent Init Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

6.3.2 GIS ASC Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

6.4 GIS GeoJSON Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6.4.1 Time-series CSV Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6.5 Programming Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6.5.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6.5.2 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

6.5.3 Enums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

6.5.4 Maps/ Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

6.5.5 Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

for loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

foreach loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

while loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

Example: Observer agent use loop to iterate over all raster cells. . . . . . . . . . . . . 59

Page 5: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

1 Foreword and Installation

Welcome to the modeling handbook on agent-based models with MARS. This will be an introduction to

multi-agent modeling, the technical details during model implementation and the simulation execution. In

order to work with the handbook you will have to install the following things:

• Dotnet Core https://dotnet.microsoft.com/download

• JAVA SDK https://www.oracle.com/technetwork/java/javase/downloads/index.h

tml

• Eclipse https://www.eclipse.org/downloads/

• MARS Plugin https://mars.haw-hamburg.de/mars-dsl/

All programming is going to be done in Eclipse. Before you can use Eclipse to build MARS models you have

to install the JAVA software development kit. Once JAVA has been installed and Eclipse opened you can

add MARS functionality to it by installing our Eclipse plugin.

Figure 1: Eclipse: installing new software

After programming the model in Eclipse, Dot-

net Core will be needed to build and exe-

cute the model. But lets install the plu-

gin first: On both MacOS and Windows you

can find the ’Install New Software’ menu un-

der ’Help’ as shown in figure 1. Once you

open the window it will look like figure 2 with-

out the pop-up. The first step is to add

the MARS plugin URL to Eclipse. Click on

the ’Add’ field marked with a red one in fig-

ure 2. Step number two is to add the URL

specified above as ’MARS plugin’ to the field

marked with two. For ’name’ you can put MARS

(marked with three), then press ’ok’. Now you

should see the entry above the red number five

where it says ’MARS DSL’. Check the checkbox

and press ’next’ marked by the red six. Af-

ter this you will be lead through the installa-

tion process by Eclipse. It might be required

to restart Eclipse but then the plugin should

work.

If you encounter any problems you can contact us through our Slack system. You can join via the following

link:

mars-explorers.slack.com

Page 1 of 60

Page 6: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 2: Installing the MARS DSL plugin to Eclipse part 2

Page 2 of 60

Page 7: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

2 MARS Models

Agent based modeling derives from the field of artificial intelligence. This simulation paradigm incorporates

individuals, so called agents, who interact with each other and their surroundings. The behavior is pro-

grammed on an individual level to follow a set of rules and interactions between them are studied to gain

insights into collective behavior [2]. Note that an agent isn’t restricted to be an individual but can also be

a group, community or other entity that acts and reacts to outer conditions [4]. The way of creating results

bottom-up from an individual levels actions leading to complex effect makes it especially suited for research

on social sciences [1].

This handbook is designed to be an introduction for people who are new to multi-agent modeling, program-

ming in general and the MARS framework.

2.1 MARS

The multi-agent framework MARS (Multi-Agent Research and Simulation) is a research project, developed at

the University of Applied Sciences Hamburg [5]. Incorporating newest concepts of agent-based and individual-

based programming [6]. The frameworks targets both simple and complex models by using specifically

designed approaches tailored to the respective disciplines like for example social ecology [3].

2.2 From Technical Model to MARS Model

Throughout this workshop we are going to use a custom domain specific language (DSL) for programming.

Daniel Glake, a member of the MARS group, created this language which targets socio-ecological models.

To make the introduction easier, we will implement an example model throughout this handbook. This

model is going to be a simple predator-prey scenario consisting of two agent types: wolves and sheep. Each

Agent is considered a living entity that has to eat in order to stay alive. For the wolves this means that

they have to eat sheep. The sheep have to eat grass. Grass will be added to the model later on as GIS file.

Wolves and sheep agents can reproduce. If they have eaten enough, they eventually hatch a juvenile wolf or

sheep. The grass periodically grows back on its own.

2.2.1 Starting Position

Every model needs to start somewhere. This is usually a class diagram which already covers the models

agents and layers. The authors expect that you are familiar with conceptual modeling at this point of reading

and have a valid design model at hand. For the layers the modeler should know the type and for the agents

he ideally has a set of attributes and rules describing the agent behavior. From there he can follow this

handbook to transform the existing technical model, that is what the model ideas on paper are being called,

to a working piece of code. This is the actual model which will be executed on the MARS platform.

Figure 3: Class diagram of the models agents

Page 3 of 60

Page 8: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

2.2.2 Creating the Model Structure

New models follow a set of formatting rules that enable the computer to understand them. Generally

speaking the models are divided into three groups:

1. model definition

2. layer definition

3. agent definition

This is also the basic structure the model idea has to be brought to when implementing a model. So when

you as a modeler start implementing your model with the MARS DSL, this is the pattern you have to stick to.

Model definition happens in the first line of every model. Listing 1 demonstrates this by creating a model

in line 0 with the name wolf sheep model. When creating your own model, this is where the name of your

model is going to be put.

Line 2 proceeds to create the layers. For this simple model it is going to be a single layer with the name of

AgentLayer. While implementing models every layer should be created after the model definition and before

the agent definitions.

The agent definition happens in line 4. Agents are defined by giving them a name and specifying on which

layer they are going to live. In this first, simple model the agent has the name wolf and will be managed by

the layer with name AgentLayer that has been created before.

0 model wolf_sheep_model

1

2 layer AgentLayer

3

4 agent wolf on AgentLayer{}

Listing 1: Basic model structure

2.2.3 Advanced Model Structure

Models don’t have to be written in the same file anymore. As long as the source files (.mars) are con-

tained in the solution and have the same model name in the first line, they will work together

2.3 Layers

Layers in MARS are an instrument to fulfill the tasks of agent management or data management. This

differs by their type. Depending on your model, you’ll use different layers. Baseline is the so called basic

layer for managing agents which is always used in models since multi-agent models always contain agents.

Therefore this layer is present in every model. GIS layers and time-series layers are designed to provide GIS

and time-series functionality. They can be included to access such data during simulations.

1. Basic Layer Used to manage agents

2. GIS Raster Layers Used to provide access to rasterized GIS data, cannot manage agents

3. GIS Vector Layers Offer access to vector GIS data and time-series data, cannot manage agents

Page 4 of 60

Page 9: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

2.3.1 Creating Layers

Now that you know the basics about layers, it is time to create the ones that your model includes. First we

define a basic layer which will handle everything agent related. Think of a name that describes the agents

surroundings and create such a layer as shown in listing 2 in line 0. In the example the layer has the name

AgentLayer, you name yours according to what you have thought of. The name has no effect on the model

behavior.

Once that is done, we continue with the optional GIS layers and time-series layers. If your model doesn’t

contain such data, you can skip ahead.

GIS layers can be created like shown in the 2nd and 4th line in listing 2. The keyword for GIS raster

layers is raster-layer followed by the name the layer should have and an alias which we will use to refer to

the layer later in the model. For these two names (GisGrassLayer and gisgrasslayer in the example) it is

customary to give them the same name. Write the first one in camel case and the second one in lower case.

Again, the names have no effect on the model. For GIS vector layers the procedure works accordingly with

the vector-layer keyword.

Time-series layers are created similar to the GIS layer since their functionality is provided through the

vector-layer . Line 6 of listing 2 shows a vector-layer that is being used to provide time-series data about

temperature values to the agents during the simulation. More information about the use of time-series can

be found in the next section.

0 layer AgentLayer

1

2 raster-layer GisGrassLayer as gisgrasslayer

3

4 vector-layer WaterPointLayer as waterpointlayer

5

6 vector-layer TemperatureLayer as temperaturelayer

Listing 2: Available Layer types

2.3.2 Using GIS Data in Models

The GIS layers ( vector-layer and raster-layer ) allow to use a range of GIS files in the simulation. At

the moment these are ASC files and GeoJSON. Data in other formats has to be converted to one of these,

otherwise you cannot make use of them.

To use the GIS data in your model you first have to create either a raster-layer or a vector-layer as shown

in listing 2. If you’re unsure which one to use, you can read up on each of them in the language reference

at 5.13 for raster-layer and at 5.21 for the vector-layer . In addition to the name of the layer you have to

specify an alias by which the layer is referred to in the code. The actual GIS file will be added later when

the model gets uploaded to the MARS cloud system or has to be specified in the simulation configuration.

For now it is important to note that the information of raster-layer can be accessed in a reading as well as

writing manner while the vector-layer only allows for reading access.

0 gisgrasslayer.GetNumberValue(xcor, ycor)

1 gisgrasslayer.GetIntegerValue(xcor, ycor)

2

3 gisgrasslayer.Increase(xcor, ycor, 3)

Page 5 of 60

Page 10: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

4 gisgrasslayer.Reduce(xcor, ycor, 5.0)

5

6 nearest on GisGrassLayer

7

8 waterpointlayer.GetNumberValue()

9 waterpointlayer.GetIntegerValue()

10 nearest on WaterPointLayer

11

12 temperaturelayer.GetNumberValue()

13 temperaturelayer.GetIntegerValue()

Listing 3: Available methods for using the GIS layer

Once the layers have been created in the model, the agents will be able to work with the GIS and time-series

layers in the following way. If you take a look at listing 3 you can see three basic ways of working with

them. Lines 0 and 1 show the reading process on the raster-layer . Here the agent wants to know the

current value of the grid cell it is standing on. The result is a number which is either coded as floating

point (’GetNumberValue’) or as an integer (’GetIntegerValue’). Lines 3 and 4 show the writing operation on

the raster-layer where the value of the agents current position is altered. The ’increase’ function increases

the current value by the amount specified in the third parameter. This is same with the ’reduce’ function

with the difference that this one decreases the current value. A special function can be seen in line 6 which

returns a coordinate of the nearest grid cell with a value that is not equal to the ’noData’ value specified in

the ASC file. This is specific to the raster-layer.

Lines 8+9 and 12+13 look the same at first glance (and even at second). The difference between them can

only be seen in context which will now be explained. The ’waterpointlayer’ is used in the model as a GIS

layer. It contains information about the positions of waterpoints while the ’temperaturelayer’ is used to

provide time-series information. This might be confusing at first but it bear with me. If you wan’t to use

time-series data in your model you will be using a vector-layer to represent that information. For every

simulation step the layer will return the current value for that point in time. Depending on the used method

this number is either formatted as float (’GetNumberValue’) or as an integer. So if you call the method in

line 12 your agents can get the current temperature value for that simulation step. This temperature value

is not bound to a location but the same for the whole simulated area. At the same time the vector-layer

can also be used to represent GIS data. In that case the methods shown in lines 8 and 9 return the value

for the closest point to the agent, contained in the input file (GeoJSON).

More information about the raster-layer can be found in the language reference chapter in the raster-

layer (5.13) section. The vector-layer is to be found in the vector-layer (5.21) section.

2.4 Agents

Agents are the second main part of every model (besides layers). Once the layers have been created, we can

start with the agent specification. For this step you, as a modeler, need to know what your agents are going

to be, what attributes define them and what their actions will look like. When all this is present, we can

start with the agent creation.

To illustrate the agent creation process, we will continue with the wolf, sheep, grass example model

that was described in the introduction. First this model will be described in detail, then the agents are

going to be created throughout this part of the handbook.

Page 6 of 60

Page 11: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

The wolf, sheep, grass model consists of two agent types and two layers. One basic layer to manage the

agents and one GIS layer to represent the grass. Wolf and sheep agents will live on the basic layer:

Wolf Agent This agent moves around the simulated area and tries to find sheep agents in order to feed on

them. When he catches one, he eats it, thereby increasing his energy level. If the wolf can’t find sheep

for a period of time, he dies. If the wolf eats enough sheep agents, he can reproduce which leads to

new wolf agents in a juvenile state. This juvenile state lasts for a fixed amount of time. Wolf agents

in that state have a reduced amount of energy and are therefore more likely to die.

Sheep Agent This agent type moves around the simulated area as well. His objective is to find grass that

he can eat. Once grass has been found, the sheep increases its energy level by eating it. Like the wolf

agent, the sheep agent can reproduce when he eats enough grass. New sheep are created in a juvenile

state where they move slower. If the sheep agent can’t find grass for an extended period of time he

dies.

2.4.1 Creating Agents

With the wolf, sheep and grass model as demonstration use-case in place, it is time to create the agents.

Listing 4 shows this step. It starts with a model definition in line 0, this should be familiar from the

introduction. Next we define a basic layer with the name AgentLayer that will serve to manage the agents.

From line 5 on we create the two agent types, starting with the wolf. The keyword for creating agents is

agent . It is followed by the name of the agent and a layer allocation. This layer allocation tells the model

on which layer the agents are going to live. For the wolf this is going to be the AgentLayer that we defined

before. Note the curly braces at the end of line 5. The agent’s attributes and behavior is going to be enclosed

by these. More about this in the next section. For the sheep agent we do the same as for the wolf. It is

defined, receives a name and is told to live on the AgentLayer.

0 model wolf_sheep_model

1

2 layer AgentLayer

3 raster-layer GisGrassLayer as gisgrasslayer

4

5 agent wolf on AgentLayer{}

6 agent sheep on AgentLayer{}

Listing 4: Creating wolf and sheep agents

2.4.2 Agent Attributes

Agents have a set of attributes that define their state. These attributes are defined through variables inside

the agents curly braces. Variables can be thought of as little boxes that store information. For each of the

agents attributes like age, energy etc. we define one of those variables that can later be worked with or

altered during simulation execution.

Variables can be of different types. MARS supports integers, floating point numbers, boolean values and

strings - for those familiar with programming. Listing 5 shows an example for these variables and how they

are defined in the MARS DSL. Integer variables can save integers (numbers without floating point) whereas

real variables can save floating point numbers. Boolean values allow a binary distinction between true and

false. The last type of variables are strings which are useful to store text or characters.

Page 7 of 60

Page 12: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

0 agent wolf on AgentLayer {

1 var Energy : integer = 10

2 var Weight : real = 70

3 var Name : string = "Wolf1"

4 }

Listing 5: Creating attributes of each available type

Agent States If an agent is designed to have various states like for example juvenile and adult in the

case of the wolf agent, this can be achieved through agent states. Depending on its current state, the agent

changes his behavior.

0 agent wolf on AgentLayer{

1 var agentState : integer = 0

2

3 tick{

4 i f(simtime > 50){

5 agentState = 1

6 }

7 //juvenile state

8 i f(agentState === 0){

9 //act as juvenile

10 }

11 //adult state

12 else{

13 //behave like an adult

14 }

15 }

16 }

Listing 6: Wolf agent with two states

Life and Death Agents will be removed from a simulation once they die. When it is desired that agents

can die, the agents can use the kill command. Code 7 shows the wolf agent dying when its Energy level

falls to 0 or below. In every simulation step the wolfs energy is reduced by 1. After 100 simulation steps the

energy will be zero and the wolf will be removed from the simulation.

0 agent wolf on AgentLayer {

1 var Energy : integer = 100

2 tick{

3 Energy = Energy - 1

4 i f(Energy<=0){

5 k i l l me

6 }

7 }

8 }

Listing 7: Wolf agent dying if its energy level falls below 0

Page 8 of 60

Page 13: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 4: Example grid with 100 by 100 cells

2.4.3 Tick: Step based execution

Agent-based simulations are executed time-discrete. In each simulation step the agents get to perform their

actions. This behavior is specified inside the curly braces of the agents tick method. Listing 8 shows an

agent creation with the tick method (line 2) to specify the agent’s behavior. All commands for the agent

will be stored there. Before the first simulation step is executed the agent’s have to be initialized to set the

initial values of all their variables. This is where the initialize method shown in line 1 comes into play.

0 agent my_first_agent on my_first_layer{

1 i n i t i a l i z e{}

2 tick{}

3 }

Listing 8: Agent definition with initialize and tick methods

Detailed information about these two agent methods can be found in the tick (5.17) and initialize

(5.5) sections.

2.4.4 Agent Behavior

All agents follow a set of rules that define their behavior. Therefore, the next step in programming agents is

implementing this. In general, the behavior can be divided in two groups: exploring and acting. Both have

different implications on the environment and other agents. Agent movement and environment exploration

have no direct impact on the outer world whereas anything that involves interactions does. But before agents

can do any of these, they have to know where they are.

Page 9 of 60

Page 14: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Positions Basis for the simulated space is a grid on which the agents are positioned. This grid can be

as big as the modelers makes it (that is you). Origin of the grid is the lower left corner which corresponds

to position (0/0). From there the grid spans in x- and y-direction to the specified size. Figure 4 shows an

example with 100 by 100 grid cells.

Moving Agents One of the most basic actions an agent can perform is movement. This is simply the

way of changing the agents position from one point to another. Movement actions can be performed in

various levels of sophistication ranging from changing position one grid cell at a time to complex pathfinding

operations to avoid obstacles. It is up to you as a modeler to decide on the level used.

The basic move command consists of the move me part followed by to and a coordinate specifying the

direction. Directions have to be written in the DSL specific coordinate notation as shown in listing 9. This

notation starts with a hash symbol and braces that enclose the x and y-coordinates, separated through a

comma. So in line 0 the agent is told to move to position (1/5). Optionally a distance in grid cells can be

specified, telling the agent how far he should move. This can be seen in line 1 where the agent is told to

move three grid cells in the direction of (10/15).

0 move me to #(1,5)

1 move me 3 to #(10,15)

Listing 9: Example move commands

Exploring the Environment Agents capable of moving around the environment usually do it for a

reason. Besides the possibility of moving randomly, most agents make out a destination they want to move

to prior to the movement. In the case of the wolf agent, this is the search for sheep agents. In order to eat

them, the wolf has to move to their position.

Finding other Agents Other agents can be found through explore or nearest operations on the

environment. Listing 10 shows the nearest command in combination with a variable. This variable

(nearestSheep) saves the nearest sheep position and is used as input for the move command afterwards. As

a consequence the wolf moves there.

The nearest command always provides the closest agent of the specified type. In listing 10 the desired type

was sheep. This works as long as there are sheep in the simulation. Once all sheep are gone, the nearest

command can crash the simulation. This happens because the nearest command can only return a valid

position if there is something to find. If there are no sheep left, the nearest command returns a useless

coordinate that the move command can’t handle. Since the ”there” doesn’t exist, the computer doesn’t

know what to do. More details on this topic and how to avoid the problems can be found in the explore

section (5.3).

0 agent wolf on AgentLayer{

1

2 tick{

3 var nearestSheep = nearest sheep

4 move me to nearestSheep

5 }

6 }

Listing 10: Wolf agent searching the nearest sheep and moving there

Page 10 of 60

Page 15: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Interactions between Agents As of yet we are able to locate other agents and move around the simula-

tion. The interesting part of multi-agent models starts when agents interact either with each other or with

their environment. In the final section of the handbook there are many examples showing you how this can

be used:

• Agent Interaction: Buying Goods (6.2.5): One agent sells apples, the other one buys them

• Chatting Agents (6.1.2): Agents exchange messages

Add more

example

models

Add more

example

models

Direct interactions between agents consist of an active and a passive part. The initiating agent does the

active part whereas the chosen partner-agent takes the passive role. Before the active agent can perform the

interaction, the passive agent has to specify what such an interaction means.

In the wolf, sheep, grass model, when a wolf eats a sheep, he is the active agent. The sheep, which is about

to be eaten, has to determine what that means. For us as humans it is clear that the sheep would die and

the wolf would eat. The computer/ the model has to be told that in detail.

Passive Actions define the implications of an interaction to the passive agent which the action is per-

formed on. To give an example we’ll program the passive action part of an wolf - sheep interaction where the

sheep will be eaten (listing 11). Passive actions are written in the agent and start with the passive keyword,

followed by the name of the interaction. Parentheses enclose potential input arguments. The main part of

the passive actions follows inside curly braces afterwards. In the case of the sheep we devise a passive action

with the name BeEaten that takes no input parameters. Enclosed by the curly braces follows the statement

that the sheep dies (line 4).

0 agent sheep on AgentLayer{

1 tick{}

2 passive BeEaten(){

3 k i l l me

4 }

5 }

Listing 11: Sheep passive action

Active Actions When passive actions have been defined, the other half of interactions can be performed:

the active part. Agents that wan’t to initiate an interaction must select an agent before they can interact.

In the wolf, sheep, grass model that means that a wolf has to select a sheep first before he can eat it. Listing

12 shows that process. In line 2 the wolf locates the closest sheep and then moves there. Note that we didn’t

check if the wolf and the sheep are close by, we’ll do that later. For now it is more important to look at line

4 where the just implemented passive BeEaten action of the sheep is being called. Thereby the wolf initiates

the interaction and the sheep reacts to it by doing what has been specified. In this case that means that the

sheep dies.

0 agent wolf on AgentLayer{

1 tick{

2 var nearestSheep = nearest sheep

3 move me to nearestSheep

4 nearestSheep.BeEaten()

5 }

6 }

Page 11 of 60

Page 16: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Listing 12: Wolf eating the nearest sheep

Message Passing Now that the agents know how to find and interact with each other, the ability to

communicate might be desired. Agents can either communicate directly or via a proxy in form of a layer.

Direct communication is best suited for scenarios in which two agents want to exchange messages. If more

than two agents want to communicate the latter approach is the way to go. Communication over a layer

follows the idea of a blackboard where agents can leave each other messages and react to them. If you want

your agents to use a message based approach, take a look at Chatting Agents (6.1.2) in the cookbook

section where an example model is explained. That model uses message-passing through a layer so that two

agent types can communicate with each other.

Interactions with the Environment aren’t the same as those among agents. The interactions consist of

predefined passive methods that the agents can call, offered by the raster-layer and vector-layer . Subsection

Using GIS Data in Models (2.3.2) is dedicated to handling GIS and time-series data during simulation. In

that subsection, a list of available passive actions can be found. More detailed information is located in

the language reference in section 5.13 for the raster-layer and in section 5.21 for the, time-series capable,

vector-layer .

2.4.5 Creating new Agents during Simulation

For situations where new agents have to be created during simulation, for example if agents reproduce, the

spawn command can be used. This creates a new agent with own variables, a complete, independent entity.

In the wolf, sheep, grass model this is used when wolves or sheep reproduce. Pre-requirement for such a

reproduction is that the wolf or sheep has eaten enough so that its energy level is high enough. Listing 13

shows the model code. In line 7, the wolf checks if he has enough energy and eventually spawns a new wolf.

0 agent wolf on AgentLayer{

1 var energy = 10

2 tick{

3 var nearestSheep = nearest sheep

4 move me to nearestSheep

5 nearestSheep.BeEaten()

6 energy = energy + 5

7 i f(energy > 12){

8 spawn wolf

9 }

10 }

11 }

Listing 13: Wolf spawns a new agent if he has enough energy

Page 12 of 60

Page 17: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Currently there a two ways of running simulations:

1. Execute the simulations on a local machine which is the default and easier method of doing

things. If you want to use this style of execution, read the Local simulations section.

2. Use the MARS servers to run the simulation in Hamburg. This way of running simulations is

only for large-scale models. Setting up a simulation in that way is complicated and involves

more steps than running locally. If you wan’t to run your simulation there, read the Cloud

simulations section.

3 Local simulations

Once the model has been written and the code compiles without errors, a simulation can be performed.

Please make sure that your code works by saving the model (cmd + s/ ctrl + s) and see if there are errors

shown in Eclipse. If so, please fix them prior to attempting a simulation as the model can only be executed

then.

3.1 Creating a simulation config

To run a simulation, a so called ”simulation configuration” or ”sim config” is needed. This is a JSON

configuration file that tells the MARS core how long the simulation is supposed to run, how many agents

should be created and which input files are to be used. Listing 14 shows an example file for the wolf-sheep-

grass model. The file itself is divided into three sections: 1) globals, 2) layers and 3) agents. Before any

simulation can run, such a file has to be created for your respective model that follows the shown scheme.

3.1.1 Globals

The first thing to specify is the desired simulation duration or, to be more precise, the period of time that

the simulation should cover. The process is straightforward as the start- and end-times have to be inserted

as as combination of date and time. In listing 14 the start time is January 1st of 2019 at 18:00 (6pm) and the

end-time is 18:10 (6:10pm) on the same day which gives us a simulation time of 10 minutes. The 10 minutes

don’t say anything about the amount of single simulation steps as these have to be calculated from there.

It is customary that each simulation model operates on its own time schedule as the tick method specifies

the behavior of an agent that can be performed in this time step. If your model describes what an agent

can do in an hour, you would divide the simulated time into hours. Should your tick method specify an

agents behavior for a second, you divide the simulated time into seconds. Dividing the specified time period

by this time unit gives you the amount of simulation steps. For the wolf-sheep-grass model the time unit

has been set to seconds so there will be 600 simulation steps as dividing 10 minutes into seconds equals 600.

Take a look at listing 14 to see the required parameters. startTime and endTime set the respective times

while the deltaTUnit parameter determines the unit of time. Change these values accordingly for you own

model. The last option(deltaT ) can be used to further refine the amount of simulation steps. In the current

configuration the 10 minutes of simulation duration are divided into seconds which gives us 600 seconds. If

you want your simulation to execute a simulation every two seconds instead of every second you can use this

parameter to change it. Setting the deltaT parameter to 2 would change the calculation as there would only

be a simulation step every 2 second which results in 300 simulation steps. This parameter is usually set to 1

as there is seldom the requirement to temper with the time resolution. If you want your simulation to run

longer or shorter, you should change the start- and end-times instead. It is very important to understand

that this only defines the inner clock for the simulation. The actual simulation execution time (real time as

we know it) will have nothing to do with what ever you set here. Even if you set the simulation execution

Page 13 of 60

Page 18: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

to many years it can still run in a few minutes. On the other hand your simulation might take several days,

even if your just covering a time frame of ten minutes.

The next parameter output specifies the desired way of persisting results. Here you can choose between

saving them to CSV files, storing them in a local MongoDB or to omit them all-together. The default way

for local execution is to save the results as CSV files as they allow for easy analysis afterwards. For each agent

type, a CSV file will be created which contains a line of output per agent and simulation step. The contents

of this lines are the current values for the agents attributes, marked with the observe (5.10) keyword. Since

most people prefer a certain style of formatting, the options parameter allow to specify this up to the desired

delimiter in the CSV file and the number format. If you want you entries to be separated by a comma set the

delimiter value to ”,” or any other separator you might like. The number format specifies how floating point

numbers (reals) should formatted. Using ”en-EN” should be kept as this specifies the standard computer

science formatting where a dot denotes the decimal place. If other formats are desired, you can read up

on them here https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard

-numeric-format-strings. Should you wish to store the results in a MongoDB, please use our slack

system to contact us as the setup is not as easy as with CSV files. If you don’t want to save any results at

all, you can set the ”output” parameter to ”none” and remove the ”options” part completely.

3.1.2 Data layers

Once the global parameters have been set, eventual data layers have to be configured. If you don’t use the

GIS layers ( raster-layer , vector-layer ) , you can skip this section.

Data layers receive their respective input files through the simulation config. In line 15 of listing 14 you see

this mechanism for the ”BiomassRaster” layer where the file ”grass 4 100x100 v4.asc” is assigned. Inside

the ”layers” section you have to add each layer in your model. The name of the layer has to match the layers

name in the model exactly, otherwise it won’t work. In the line beneath, the filename that should be used

has to be added in the same way. To avoid problems with file locations, it is best to place the input files

inside the ”src-gen” folder. More information about the supported file types can be found in the sections

about the GIS layers.

3.1.3 Agent parameters

Agents and their parameters can either be set in the model itself or from outside. For local simulations

these parameters can either be set for all agents or per individual agent. If set for all agents, all of them

will have the same parameter start-values. If this is desired keep reading here, otherwise skip to the next

part where agent initialization files are described that allow to give each agent its individual parameter values.

If all agents (of the same agent type) should receive the same input parameter values, this can be done as

shown with the wolf agent in listing 14. In line 27 the so called mapping allows the assign each parameter

a certain value. Inside the curly braces, each individual parameter that has been marked with the external

keyword has to be included. In the wolves’ case, these are the Energy and EnergyMax attributes. Each of

them has to be placed inside its own curly braces, following the notation shown. The value assigned can

either be integers, reals, strings or booleans. Please note that strings have to be enclosed in quotation marks

(”value”:”example”). For boolean values the correct way of formatting is lower case (true or false). Integers

and floating point numbers can be used as shown.

3.1.4 Agent initialization files

To assign each agent individual parameter values so called ”agent initialization files” can be used. These

are CSV files are described in detail in the cookbook part of this handbook ( Agent Init Files (6.3.1) ). To

Page 14 of 60

Page 19: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

use one of these input files, you have to put said file in the ”src-gen” folder and link them as shown in line

22 of listing 14. During initialization, each of the 10 created sheep will be assigned its individual parameter

values from the sheep.csv file. This works almost as with the data layers with the exception that you have

to provide the desired agent count. Without the ”count” parameter, no agents will be created.

0 {

1 "globals": {

2 "startTime": "2019-01-01T18:00:00.000Z",

3 "endTime": "2019-01-01T18:10:00.000Z",

4 "deltaT": 1,

5 "deltaTUnit": "seconds",

6 "output": "csv",

7 "options": {

8 "delimiter": ";",

9 "format": "en-EN"

10 }

11 },

12 "layers": [

13 {

14 "name":"BiomassRaster",

15 "file":"grass_4_100x100_v4.asc"

16 }

17 ],

18 "agents": [

19 {

20 "name":"Sheep",

21 "count":10,

22 "file": "sheep.csv"

23 },

24 {

25 "name":"Wolve",

26 "count":10,

27 "mapping": [

28 {

29 "parameter": "Energy",

30 "value": 100

31 },

32 {

33 "parameter": "EnergyMax",

34 "value": 100

35 }

36 ]

37 }

38 ]

39 }

Listing 14: Simulation config for wolf sheep model

Page 15 of 60

Page 20: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

3.1.5 Summary

1. Go to src-gen folder where all the generated code is being stored

2. Create a simulation config that specifies how long the simulation should run, which layer information

should be used and how many agents should be created. This must be a JSON file.

3. Run a simulation by adapting the following command to your individual model

dotnet run -sm config.json -project Wolves.csproj

In the shown example the name of the simulation config is config.json. The name of the project is Wolf-

SheepPredation.csproj. Change these names accordingly for your simulation.

4 Cloud simulations

All simulations with the MARS system are being run on our servers in Hamburg. Once you finish building

your model you will have to upload it there. This gives you the advantage of using our resources to run

models as big as you want.

4.1 Preparing the Model for Execution

Before models can be executed on the MARS platform, a couple of preparation steps have to be made.

These steps transform the model from your written description file to computer understandable code that

can be uploaded to the MARS cloud in order to be executed there. A tool necessary to build such a packet

is the command prompt (or terminal for the OSX users). From this command prompt the model code is

transformed to a ZIP file which can then be uploaded to the cloud.

4.1.1 Opening a Command Prompt

The procedure differs slightly between Windows and Mac. See the suitable paragraph for your operating

system below.

Windows To open a command prompt in Windows you have to go to the start menu and type the three

letters ”cmd” into the search bar. Windows will suggest the program ”Command Prompt”. Click on it to

open the program. Once the command prompt is running it should look like this:

Mac Mac users should open a terminal, that is what the command prompt is called in OSX. This can be

achieved by either opening the spotlight search and typing terminal or by going to the application folder an

double clicking on terminal. Result should look like this:

4.1.2 Changing Directory to the Model

For both Windows and OSX users the following step is going to be similar. It is assumed that you have

set your Eclipse workspace to the Desktop of your computer. That way you can follow this tutorial easily.

Those who chose another location will have to adapt.

cd directory

Changing directories over the command line works by using the cd command. This is the same on Windows

and OSX. First you write the keyword itself and then you specify the desired directory you want to change

to. Since you might not know every’s folders content by heart, the following commands might help: dir on

Page 16 of 60

Page 21: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 5: Command prompt on Windows

Windows and ls on OSX. Both show the contents of the current folder and thereby list the folders you can

change into.

As I said in the beginning of this paragraph I assume that you put you Eclipse workspace on the desktop.

Therefore the first command after opening the command prompt/ terminal is to change the director to the

Desktop. This is done by typing the following command into the terminal:

cd Desktop

If you did it right you should now be in the Desktop folder. This is indicated by the Desktop name in front

of the prompt (OSX). See figure 7 for details. If you are using Windows this change of directory is indicated

by the whole directory path as shown in figure 8.

The next step is to move inside the Eclipse workspace. This is where the models are located. To check if

the workspace is on your Desktop you can use dir or ls command after you changed the directory to the

Desktop. If you execute this command you should see something like whats shown in figure 9.

From there on use the cd command to move to the LIFEStarter folder inside your model. The general file

structure is discussed in the next section in case you need further information. To get there you have to go

through the following steps:

1. Change directory to the eclipse-workspace as discussed

2. In there you have to go to your model. You know the name, otherwise use dir or ls to look up the

available model names

3. Inside every model is a folder called src-gen, go into that

4. As last step you have to change the directory to the LIFEStarter folder which is located in the src-gen

folder

Page 17 of 60

Page 22: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 6: Terminal on Mac OS/ OSX

Figure 7: Desktop on OSX

4.1.3 Model File Structure and LIFEStarter

All models are to be found in the Eclipse workspace. You should be asked where this folder should go when

you open Eclipse. Set it to the Desktop so you can find your models easily. In there you’ll find all models

that you created. Each is contained in its own folder.

In these model folders you’ll find two sub-folders. One is called src, this is where the .mars files are located

that you programmed. The other one is called src-gen and contains the automatically generated code that

can be run on the MARS system. In there you can find the LIFEStarter directory in which you have to

change to before you can build the model. This is the last step you have to make before you can upload

your model to the cloud.

4.1.4 Building the Model with Dotnet Core

For this step to work you have to have a stable internet connection. This step downloads up to multiple

megabytes of data onto your computer. If you are not connected to the internet it won’t work

Page 18 of 60

Page 23: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 8: Desktop on Windows

Figure 9: List of folders on the desktop

If you want to understand why the step of building the model is necessary read-on, otherwise you can skip

this paragraph. Here it is going to get a bit more technical: The model you wrote using the MARS domain

specific language is a description of how your model should look like. From there the model is translated to

C#, a regular programming language that a computer can execute. You don’t see any of that because it

happens in the background every time you save your model. Before the model can be uploaded to our cloud

system you have to take that written code and make a package of it. This is what happens if you build the

model. Everything that the model needs in order to run is packed into one folder.

For every model the procedure is the same. As it has been described in the Changing Directory to the Model

(4.1.2) section, it is required to change the directory to the LIFEStarter folder inside your model prior to

this step. From there you can execute the following command:

dotnet publish -c release -o out

Once you typed this into the command prompt you have to hit enter. If you do this the first time it can

take a while. For repeated runs its going to work faster since most of the required things has already been

downloaded to your computer.

When the process finishes your terminal should look something like figure 10 (Windows). The most important

part is that you don’t see anything red on your screen. Red lines indicate that something went wrong in

which case these lines also contain the reason. This should only happen when your model has errors though.

Figure 10: Finished build process

Once the process finishes you should have a new sub-folder in the LIFEStarter directory with name out.

You need this folder for the next step.

4.1.5 Creating a Model Zip File

The last step before the model can be uploaded is to create a zip file that contains the just created out

folder. How this is done doesn’t matter so go ahead if you know how to create such a file. Those who aren’t

computer experts might use one of the following methods:

Page 19 of 60

Page 24: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

• Create the zip file right here using the terminal (OSX only)

• Use the explorer (Windows)/ finder (OSX) to create the zip file

The quickest way is to use the terminal. OSX comes with the needed program pre-installed, I wish I could

say the same about Windows. If you execute the following command, your Mac will create a zip file by the

name of model.zip right here in the folder. You can name your zip file in any way you want (e.g. replace

model.zip with wolves sheep.zip).

zip -r model.zip out

Way number two is to use the file explorer. This works on both Windows and OSX. Open the folder where

your model is and navigate to the LIFEStarter folder just as we did using the command prompt/ terminal.

Once you’re in that folder do a right-click on the out folder that we created. If you use OSX select compress,

this should create a zip file by the name out.zip. On Windows go to sent to and then select compressed

(zipped) folder which results in the same out.zip archive. It makes sense to name the file in a way that you

know what this folder contains so that you will still know in two weeks or so.

4.2 MARS Cloud Basics

The MARS cloud system is being run on the servers of the University of Applied Sciences. Its usage is free

so you can run as many simulations as you want. Please use the following link to get there:

www.mars.haw-hamburg.de

4.2.1 Creating an Account

Before you can use the system you have to create an account. This can be done by clicking on the Register

Now! button on the right side of figure 11. Please fill in your personal information and remember the

username. This in combination with the chosen password will give you access.

YOU WON’T RECEIVE A CONFIRMATION EMAIL. Someone of the Mars group will have to unlock

your account. Until this hasn’t happened, you cannot access the system.

4.2.2 Login to the System

Once your account has been unlocked you can log-in and use the system. To do this, you’ll need your

username and password. Please don’t use your email address instead of the username, this will NOT work.

After you have logged in, you can go ahead with the next steps and use the system as much as you want.

4.2.3 Working with Projects

The first thing to understand when working with the MARS system is that everything you do is separated

into projects. You can use them to work on multiple ideas at a time or just to structure your work. Figure

12 shows a view of the user interface with a couple of projects. Before you can work on a project you first

have to select it by clicking in the upper-left corner of the project itself (marked with ”1”). New projects

can be created using the Create button in the lower-left corner (marked with ”2”).

4.3 Importing Files

This section will cover the upload process to the MARS cloud. Once you have registered, are logged-in

and have created a project it is time to upload your model and potential input data for the simulation.

Everything upload related can be found in the import panel.

Page 20 of 60

Page 25: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 11: Login view of the MARS system

Figure 12: List of projects in the projects view

Page 21 of 60

Page 26: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 13: Upload process for a model

4.3.1 Uploading Models

The first thing you wan’t to do is to upload your model. Prerequisite for this are the steps described in

Preparing the Model for Execution (4.1) . Once you have created the described zip file you can upload it

here. To do so click on the choose file field marked with a red 1 in figure 13. This prompts you with a

file picker in which you select the zip file you created earlier. Next you select the type of the upload in the

drop-down menu marked with a red 2 in figure 13. Since this is a model, you’ll select model as type. Next

you press the green upload button. Once the process is finished the uploaded model will appear in the top

half of the window.

4.3.2 Uploading GIS Data

If your model contains a raster-layer you will upload that GIS data in the import panel. The process is the

same as for model uploads described above. Instead of the zip file containing the model you will upload the

ASC file with the raster. Read more about the supported file types in section raster-layer (5.13) . Click

the choose file field, select the ASC file and then select GIS as type. The last step is to click on the green

upload button.

4.3.3 Uploading Agent Init Files

The last type of data you can upload are so called agent init files. When parameterizing agents in bulk you

use these files. Read more about them in the Agent Init Files (6.3.1) section. Uploading them is the same

as described above. Select the desired agent init file which should be in csv format, choose the Agent Init

CSV type and press the upload button.

Page 22 of 60

Page 27: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 14: Scenario view

4.4 Scenarios and result configs

Scenarios and result configs specify the parameters of a simulation run as well as the results. They define

what is going to be simulated and what will be contained in the results . Main purpose of scenarios is to set

the overall simulation length and assign data to agents and layers. Data that has been uploaded previously

will be connected with the model during this step. Once the scenario is filled out, the result configuration

is produced to define the desired simulation output in terms of result data. Here you specify which agent

variables and layer information are going to be saved for a subsequent analysis.

4.4.1 Creating Scenarios

Everything scenario related is to be found in the Scenarios section which is shown in figure 14. New scenarios

are created by clicking on the Create button marked with 1 in figure 14. If you click it, a popup will show and

ask you to name the scenario and to select a model on which the scenario will be based. Choose a meaningful

name and describe the scenario if needed. The creation process works as well without the description. Now

you should see your new scenario in the center of the screen. In the example in figure 14 the scenario was

named wolf sheep scenario 1, yours will be named accordingly.

4.4.2 Filling out Scenarios

The overall structure of scenarios consists of three parts. Part one are the agents and their parameters. Here

you specify how many agents you want to have in your simulation and assign them values from previously

uploaded agent init files. Part two contains the layers. Layer input data like raster files or time-series data

will be assigned to the layers in that section. The last part is there to specify the simulation start- and

end-time as well as the duration of ticks.

Page 23 of 60

Page 28: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 15: Standard agent parameters in a scenario

Lets start with the agent parameters. For every agent in your model the scenario will display its name and

at least four fields as shown in figure 15. Here you specify the starting position, the desired amount of agents

and the frequency in which the agents are supposed to be simulated.

CoordinateX: x-value of all agents starting position (all agents = all agents of that type)

CoordinateY: y-value of all agents starting position ”

TickFrequency: This specifies the frequency in which the agent’s tick method will be executed. Agents

can be simulated in every tick, then the TickFrequency should be set to one. If the agents should be

simulated only every second tick, set the TickFrequency to two. Every third tick → set to three, you

get the idea.

InstantiationCount This is where you set the amount of agents you want to have in the simulation (of

that agent type). This number must be greater than zero so you have to at least create one instance

of every agent.

Other attributes your agents have will only show if you marked them as external in your model. See

external (5.4) section to learn all about that. To fill out the information you start by clicking on the small

pen symbol marked with 1 in figure 15 which opens up the input field as marked with 2. Once you typed in

the desired value you press on the arrow marked with a 3 to lock it in. Now the value should look like in the

box marked with a 4. After pressing the Apply button in the bottom left corner the values will be saved and

marked with a little checkmark to indicate that the agent mapping is finished and valid. An alternative to

filling out the parameters manually is to drag and drop field from an agent init file to the respective agent

parameter. The agent init files should appear on the right side as shown in figure 14. Before you can assign

values from an agent init file you first have to upload said file. See Uploading Agent Init Files (4.3.3)

section for more information.

Now we take a look at the layers of your model. Only raster-layer and ts-layer will be shown since

these are the only layer types that you can assign data to. As with agent files you will have to upload the

layer data prior to the scenario so that you can use them here. On the right side as shown in figure 14

you will find these files (marked with 2). In the example you can see a single raster file by the name of

grass 4 100x100 v4.asc. Figure 16 shows more details about the file. To map the file to a layer simply drag

the red colored oval onto the layer. The result should look like figure 17 where you see the completed mapping

of the grass ASC file onto the Biomass(-layer). Once the mapping has been completed and you clicked Apply

in the bottom left corner your input will be examined and tagged as valid (green checkmark) if it was correct.

Page 24 of 60

Page 29: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 16: Uploaded layer input data

Figure 17: Grass ASC file mapped on the biomass layer

The last step of the scenario is to set the global parameters for the simulation. They specify when the

simulation will start and end as well as the duration of a simulation step. For start- and end-time the

process is simple. You click in the value box and a time-picker will open that allows you to set the date

and time when the simulation starts. Same goes for the simulation end. Next you set the duration of each

simulation step. This might seem a bit tricky but it is straightforward if you understood the concept so bare

with me.

Example: You set the start time to now and the end time to one hour in the future. If you take a look at

the DeltaTUnit parameter shown in figure 18 you will see that it offers different time intervals ranging from

microseconds to years. This lets you choose the intervals that will be applied to the duration you specified

through start- end end-time. In this case we have an hour in total. If we set the DeltaTUnit to minutes, we

will have sixty simulation steps since one hour divided into minutes gives us sixty. If we would set it to hours

we would get one simulation step while setting it to seconds would give us 3600 steps. So far so good now

what does the DeltaT parameter do? In most situations you will set it to one (1). But in case you wan’t

your simulation to do a simulation step every three minutes instead of every minute as describe before, you

would set it to three (3). Instead of sixty steps as before when the DeltaT was 1 you now divide the hour

by minutes (60) and then you divide by three (3) which gives you twenty ticks. What this does is it spaces

out the tick execution interval thereby reducing the amount of simulation steps.

The most important thing to understand about this whole time thing is that it is only defining the inner

clock for the simulation. The actual simulation execution time (real time as you know it) will have nothing

to do with what ever you set here. Even if you set the simulation execution to many years it can still run

in a few minutes. You set the simulation time so that the simulation itself can run in any point of time.

This is necessary if you use time-series data that has a time constraints (is only valid for a specific point in

time). If you use the ts-layer functionality in your model you will have to select the start- and end-date

Page 25 of 60

Page 30: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 18: Global parameter determining the length of the simulation

carefully. For all other models it is only necessary to select the four parameters in a way that you get the

desired amount of ticks (simulation steps).

4.4.3 Creating Result Configs

Simulations calculate something and that something (simulation results) should be saved in a way that one

can analyze it afterwards. Since most models produce a lot of results it makes sense to reduce this amount

to the results you’re actually interested in. This is where Result Configs come into play.

But lets start with more information about simulation results in general. Every agent has a position and an

ID and in every tick this information is persisted. If you wan’t to save more information from an agent like

the current value of certain agent attributes you will have to enable this since this isn’t by default. Agent

attributes annotated with the observe keyword will be saved in every simulation step. More information

can be found in the observe (5.10) section. For raster-layers the concept is similar. The layer itself is

initialized with a file that you upload prior to the simulation execution. If the agents change the information

contained in that layer you can save these changes by storing the layers current values (whole grid) after a tick.

The way you save these things is to go to the Output section where you create a new Simulation Config.

If you open the section you will be asked to select the model you want to create the output configuration

for. Once you have done this your screen will look like figure 19 where you can see the agents and layers

in the model. This is marked with a red 1. For each agent you can open the tab where you will see the

agents attributes in on the right side. Each of these attributes will be saved after every simulation step. If

you don’t want this, you can deselect the respective attribute by clicking on the checkbox next to it. For

raster-layers the window will look exactly like figure 19. First of all you can select whether you wan’t to

output the layers values at all by using the big switch. And second you can decide how often this output

will happen. Marked with a red 2 is the little dropdown menu in which you can select either Read-Only or

Dynamic. With the first option the layers data will be saved once when the simulation starts (before the

first tick). If you select option two the layers data will be saved after every tick so that you can go through

the different stages during result analysis. The last step is to press the Save button so that the configuration

is saved. You can come back to existing configs at any time, change and re-use them.

Page 26 of 60

Page 31: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 19: Result configuration for wolf sheep grass model

4.5 Conducting Simulations

Once you have gone through the described steps you are ready to run the first simulation. This section will

include the last instructions on how to actually start a simulation and monitor the progress.

4.5.1 Simulation Plans

Simulation plans connect the model with scenarios and result configurations. When you open the Runs sec-

tion you will be presented with a view similar to figure 21. The figure shows a view for the wolf, sheep, grass

model with two simulation plans already created. To create a new one click on the Create button marked

with a red 1. This will open a popup shown in figure 20 where you will be asked to name the simulation

plan and choose a scenario or mapping configuration as well as an output configuration/ result config. After

entering these information press the Create button to save it and return to the main screen.

If you want to delete a simulation plan click on the delete button that looks like a trash-bin. This button

is marked with a red 3 in figure 21. Deleting the simulation plan will delete the simulations based on said

plan as well and the deletion will not work if one of these simulations is still running.

4.5.2 Running Simulations

Simulations can be started once a simulation plan has been created. In figure 21 you can see example simu-

lation plans from the wolf, sheep, grass model. Each of them has the Play button that is marked with a red

2. If you press this a simulation will be started in the MARS cloud system. These simulations are shown in

the lower half of the figure where you can see the plan they are based on, an ID, the start date as well as

status and the current tick of the simulation (marked with a red 4). To get an update on the current status

you can press the Reload button (red 5 mark). The view will NOT update itself.

Page 27 of 60

Page 32: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 20: Creating a new simulation plan

Figure 21: View of the simulation section

As with the simulation plans the simulation runs have two buttons to manage them. Marked with a red 6

is the stop button which aborts the simulation run. Once stopped, the simulation can not be resumed. If

you wan’t to delete a simulation run you can do this by clicking on the trash-bin symbol marked with a red 7.

The last two buttons marked with red 8 and 9 show the simulations logs and open the result view. More

about the result view and how to analyze simulations will follow in the next section. To get there click on

the button marked with 9. Simulation logs show the console output of the running simulation. If you click

on the icon marked with the red 8 a popup will open showing the logs.

Add new image with visualization button instead of figure 18

4.6 Analyzing Simulation Results

The MARS system offers a couple of ways to analyze simulations ranging from the logs to a visual analytics

dashboard.Add Jans visualization as third option of Analysis + add reference to his Springsim Paper

Probably one of the best features is that you can analyze while the simulation is still running so you don’t

have to wait until it finishes.

Page 28 of 60

Page 33: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 22: Result view of a wolf sheep grass model simulation run

4.6.1 Agent Populations

The result view looks like shown in figure 22 and is basically divided into four parts as marked with the

rectangles of different color. The red rectangle on top shows the agent population of a model. On the right

side of it you see the map legend of the agents and layers shown in the diagram. Said diagram displays the

agent count over the simulation runtime. For each agent type the total count for each tick will be shown. If

selected in the result config, the raster-layers sum of values for all grid-cells will be shown as well.

4.6.2 Spatial Analysis

The blue box in figure 22 shows a map of the simulated area. In the top of it you can select the raster-layer

that will be the surface for the agents moving around. On the right side you see a scale that depicts the

rasters values shown on the map. The agents themselves are the little points moving around. Directly below

the surface selection menu you’ll see the currently displayed tick. With the controls in the green box on the

left you can change that. This gives you full control to show certain ticks or to start an animation of a range

of simulated ticks.

4.6.3 Agent Attribute Analysis

The brown box on the right contains an analysis of the agent specific attributes. In this example the wolf

and the sheep agent both had two attributes hunger and energy which are displayed in blue and red. As

with the spatial analysis you can view the attributes for a specific tick. To do that you have to select the

tick on the right side in the green box.

4.6.4 Download Results

If the offered analysis tools aren’t enough you can also download the results. For this purpose the green box

on the left contains a Dataset Download button. Here you can select the agent and the tick you wan’t to

download data for. The field query is sent to our MongoDB where all the results are being stored. Feel free

to enter any query to our database, you’re not limited to the default entry shown. The resulting information

will be packed into a CSV file that you can download afterwards.

Page 29 of 60

Page 34: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

5 Language Reference

5.1 agent

Agents are the smallest entity in each simulation. They are the building blocks of it all. Creating them

works through the agent keyword. They live on layers and have therefore to be created with the following

syntax:

agent agent name on layer name {}

The first keyword ( agent ) tells the model that a new agent type will be created followed by the on keyword.

This defines on which layer the new agent-type will live. Layer name is the name of the layer where the

agent will be created on. Agent definitions end with curly braces {} which enclose the agents behavior.

Behavior is specified through the initialize and tick methods. See sections tick (5.17) and initialize

(5.5) for more details. Agent attributes are managed by variables on which you can read up in section

Variables (2.4.2) . More on layers can be found in here: layer (5.7)

5.2 distance

If you wan’t to calculate the distance between two agents, you can do this by using the distance command.

This returns a decimal number, specifying the gap between them. The command works by writing the

distance keyword and adding the agent ( other agent ) afterwards to which the distance should be calculated.

distance other agent

Listing 15 shows an example how this can be used in a model. The wolf agent tries to find the nearest sheep,

this isn’t new. But before he eats it, he checks the distance (line 5). If the distance is equal to zero, this

means that he is on the same grid cell as the sheep. In that case he eats the sheep, otherwise he doesn’t.

0 agent wolf on AgentLayer{

1 tick{

2 var nearestSheep = nearest sheep

3 i f(nearestSheep != nil){

4 move me to nearestSheep

5 var distanceNearestSheep = distance nearestSheep

6 i f(distanceNearestSheep === 0){

7 nearestSheep.BeEaten()

8 }

9 }

10 }

11 }

Listing 15: Wolf agent checking the distance to the closest sheep

5.3 explore

Exploration of the environment is a vital part of every model. The agents sense what is around them and

act based on that. For this purpose the DSL includes the explore and nearest keywords. In this part we’ll

exclusively talk about explore . The next section (5.9) is about the nearest command.

Page 30 of 60

Page 35: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Please read the null reference exceptions paragraph further down prior to using explore command in

your model. This will save you a lot of trouble later on.

The explore command is available in two stages of sophistication. Depending on your desired result one or

the other will be used. If you are trying to find a specific agent type the basic version is sufficient. Complex

queries can be used as well. For those, the second version has been build. See the next paragraph Explore

with predicate for details.

Explore basics The basic version of the explore is designed to find specific agents. The command

consists of two parts. Part one is the actual explore keyword, the second one ( agent type ) specifies the

desired agent type. By using this command you can find all agents of that type. The result of the operation

is an array of agents that is sorted in ascending distance to the current agent.

explore agent type

Listing 16 shows an example in which the wolf agent tries to find sheep. This is done in line 2 where the

explore command is used. As result of the explore operation, the agent receives a list of sheep in ascending

distance. This result is saved directly to a variable with the name sheep. In line 3 the agent uses the first

list element (the closest sheep) as destination for his movement. Without checking if the wolf is on the same

grid cell he then proceeds to eat the sheep by calling its BeEaten() method.

0 agent wolf on AgentLayer{

1 tick{

2 var sheeps = explore sheep

3 move me to sheeps[0]

4 sheeps[0].BeEaten()

5 }

6 }

Listing 16: Wolf agent exploring sheep agents

Explore with predicate More sophisticated explorations can be performed using a predicate. These

predicates allow to specify certain conditions that the desired agent has to meet. For example the wolf could

look for sheep with an energy level above 30 instead of just trying to find any sheep. For the latter request,

the basic explore command is sufficient. As the base version, the advanced explore operation starts with

the explore keyword followed by the desired agent type . Following up is the where and the actual

predicate enclosed in brackets.

explore agent type where [ predicate ]

The syntax for specifying predicates follows a certain scheme. Inside the brackets one has to define which

letter is going to represent the single agents viewed during the exploration process. Take a look at line 2 in

listing 17 for an example in which the wolf tries to find sheep with an energy level of at least 30. First the

wolf states that the sheep are going to be represented by the letter x. After this, the little arrow denotes

the start of the condition. No matter how conditions are defined, they have to evaluate to a boolean value

of either true or false. In the wolf’s case the check whether a sheep has an energy level of thirty or above

evaluates to true if the sheep has more than thirty energy points or false if the sheep’s energy level is below

thirty-one. This check is performed by calling the sheep GetEnergy() method as base for the comparison.

Note that you cannot access other agents variables directly and therefore have to define passive actions. In

line 16 of listing 17 the sheep agent implements the aforementioned method.

Page 31 of 60

Page 36: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

0 agent wolf on AgentLayer{

1 tick{

2 var sheeps = explore sheep where [x => x.GetEnergy > 30]

3 move to sheeps[0]

4 sheeps[0].BeEaten()

5 }

6 }

7 agent sheep on AgentLayer{

8

9 var Energy : integer = 40

10 tick{

11 move me to #(random(10),random(10))

12 }

13 passive BeEaten(){

14 k i l l me

15 }

16 passive GetEnergy() : integer {

17 return Energy

18 }

19 }

Listing 17: Wolf agent looking for sheep with an energy level of over 30

Null Reference Exceptions Caution is advisable when using the explore command. The yielded list

of desired agents might be empty. It is sorted in ascending distance to the current agent but only if there

are agents of that type. As long as agents of that type are available, the command works absolutely fine. If

there aren’t any agents of the desired type left or a predicate has been used to e.g. find only agents with

an energy level of over 30, the command can return an empty list. Until now, the explore operation itself

is completely safe. Problems arise from using the list of agents that has been returned without checking it

first.

If the result of a explore command is used as input for other commands like for example the move action,

the simulation might crash. This is due to the fact, that the agent then tries to move towards a non existing

agent which naturally leads to a so called null reference exception. Programmers reading this handbook

should be familiar with the problem. For those not proficient in coding: this is very bad!

Luckily there is a solution to it. Whenever we use the explore keyword we have to add a conditional

statement that checks if the list returned by the command contains at least a single entry. Listing 18 shows

an example from the wolf, sheep, grass model where the wolf looks for sheep and then moves to the closest

one. This is the safe version of listing 16.

We start inside the wolfs tick method. In line 2 the wolf explores its surroundings by using the explore

command. The results of that exploration are stored in a variable named sheep. Contrary to line 3 in listing

16 the wolf now revises the result of the explore command prior to using it as destination for the move

operation. This is done in line 3. If the first entry in the list of found sheep isn’t nil, then, and only then,

the agents proceeds with the move command. The word nil comes from the latin word nihil and means

”nothing”. So the agents checks if the entry is something else than nil (nothing) and then executes the

move operation. If the first entry is indeed nil, then the agents skips to the else path where an alternative

action should be placed.

With this check in place, the model will not execute potentially bad code and won’t crash. It is up to you

Page 32 of 60

Page 37: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

as a modeler to deal with the case where there is no sheep available appropriately.

0 agent wolf on AgentLayer{

1 tick{

2 var sheeps = explore sheep

3 i f(sheeps[0] !== nil){

4 mov me to sheeps[0]

5 sheeps[0].BeEaten()

6 }

7 else{

8 //specify alternative action

9 }

10 }

11 }

Listing 18: Wolf agent safely looking for sheep without risking a null reference exception

5.4 external

When an agent’s variables are defined, they have to be initialized with a value. This value can either be

set directly in the code or can be filled-in later from a file. The use-case for setting agent variables later is

that you can easily initialize a large amount of agents. Each of them with individual attribute values. For

that purpose it is possible to create agents from a CSV (comma separated value) file that includes these

individual attributes.

An example from the wolf, sheep, grass model would be if each agent should have its own set of starting

parameters. The standard way would be to create the agent’s variables and assign them either a fix value

or a random value. Wolfs could have a starting energy level of 100 and a random hunger level between zero

and fifty. Take a look at listing 19 where line 1 shows the assignment of a fixed value. No matter how many

wolf agents you use during the simulation, all of them will have a starting energy level of 100. The second

option is to assign a random value in between zero and fifty as starting point as shown in line 2. Using this

technique, every wolf agent would start with a random hunger level in between these bounds.

0 agent wolf on AgentLayer{

1 var Energy : integer = 100

2 var Hunger : integer = random(50)

3 }

Listing 19: Wolf agent variable definition

Every time you simulate, these random values would be set differently. If you want your simulations to

always start up with the exact same set of variables, but at the same time want your agents of the same type

to have different values you can use the external keyword. This enables you to (later-on during simulation

creation) initialize these values from a file. Another good thing about using these files is that they only have

to be created once. The general idea for the file is that every line represents a set of initial values for one

agent.

To use this in your model, you have to write the external keyword before each variable that you wan’t to

set from a file. Additionally the starting value has to be left blank. In listing 20 you see the exact same wolf

agent as in the code snippet above. Only this time the wolf agent variables Energy and Hunger are created

without an initial value.

Page 33 of 60

Page 38: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

0 agent wolf on AgentLayer{

1 external var Energy : integer

2 external var Hunger : integer

3 }

Listing 20: Wolf agent with external variable initialization

Please familiarize yourself with the syntax for using the external command during a variable definition. As

in a regular definition we write the var keyword, give the variable a name and specify the desired variable

type after a colon. The new thing, when initializing a variable from outside, is the fact that instead of

following up with an equals and an initial value, you write the external keyword at the beginning before

the var command.

external var variable name : variable type

You can mix the different ways of creating variables in an agent. Some attributes can be set fixed, some

can be created from a random value and the remaining ones from a file.

Now that you know how to use the external keyword, lets talk about the initialization files: There is only

one type of files support, and that are comma separated value files (CSV’s). You can use any text editor

to create such files since they are simple text files. The first line is used as header where you specify the

names of the variables in your model. Every variable name is separated by a semicolon. By separating

these names by semicolons you are basically creating a table. Each variable name is essentially a column

(just as in Excel). It is very important that you don’t leave spaces in between the names or the semicolons.

Additionally it is to be noted that the whole file to variable mapping process is case sensitive.

Let me give you an example: If your variable in the model has the name energy, then the first line of the file

must contain energy. It won’t work if you type Energy, eNergy, energy or anything else but the very same

notation.

Now that you have created the header and assigned each column a name you can go ahead and create as

many lines beneath as you want. Every line will be used as one set of starting parameters for one agent.

Depending of the type of parameter you want to put in the agent init CSV you have to use a slightly different

syntax. Integers and floating point numbers can be set directly, please note that for floats you have to use

a point instead of a comma. For strings you have to set the value in quotes (”value”). The most important

thing is that you separate each of the values by a semicolon. When you want to save the file, make sure you

specify the file ending as ”.csv” so that the comma separated value file is saved as such.

0 Energy;Hunger

1 10;14

2 12;40

3 24;2

4 5;80

5 70;5

Listing 21: Example initialization file for the wolf agent

In the first line of listing 21 you can see an example file of the wolf agent. Remember, it had two external

variables named Energy and Hunger. For that reason the CSV file has two columns named Energy and

Hunger. If you were to use that file to create wolfs, you could initialize five agents since the files has five

Page 34 of 60

Page 39: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

lines with agent parameter values. The first one would have an energy level of 10 and a hunger level of

14. Wolf number two starts with 12 energy points and a hunger of 40. This goes on until you reach line

number five which would be used to create the last agent with an initial energy level of 70 and a hunger of five.

Another example agent init CSV with different variable types can be found in the cookbook section of this

handbook. See section Agent Init Files(6.3.1) for details. For more information about how to upload these

files to the MARS cloud and how to use them in scenarios see sections Uploading Agent Init Files(4.3.3) and

Filling out Scenarios (4.4.2) sections.

5.5 initialize

The two most important parts of each agent are the tick and the initialize methods. While the tick

method defines what each agent does in a time-step and is executed over and over again, the initialize

method is only performed once. Before the first simulation step takes place, this method can be used to

set-up all the basics in an agent prior to the actual simulation start.

initialize (){}

The syntax is equal to the tick method. Write the initialize keyword, add empty braces and append a

pair of curly braces. Everything enclosed by the curly ones is whats being executed. For those proficient in

programming, the initialize method is the agent constructor.

In listing 22 you can see an example of the wolf agent with its initialize method. Besides defining variables

and specifying a tick method the wolf uses its initialize method to set a random starting position and to

assign a value to the Hunger variable. This is done in lines five through eight. When the simulation starts

the program gets executed in the following order:

1. Create the agent variables and fill them with values. This can either happen directly in code or through

an external file. See sections Variables (2.4.2) and external (5.4) for details

2. Call each agent’s initialize method and execute the enclosed commands once

3. For each time-step, execute the commands inside the tick method until the simulation finishes

0 agent wolf on AgentLayer{

1 var Energy : integer = 10

2 var Hunger : real

3

4 i n i t i a l i z e(){

5 pos at #(random(10),random(10))

6 Hunger = 15.3

7 }

8

9 tick{

10 move 1 up

11 Energy = Energy - 1

12 i f(Energy<=0){

13 k i l l me

14 }

15 }

16 }

Page 35 of 60

Page 40: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Listing 22: Wolf agent with an initialize method to set its start position to a random location

5.6 kill me

Depending on the kind of model you are writing, your agents might be expected to die. To account for this,

we added a special kill me command to the language that allows to kill an agent. If the agent should die,

use the kill me command as shown in listing 23. The wolves defines a variable Energy that represents his

energy level as an integer. This variable is only there for demonstration purpose. In the wolfs tick method

he decreases the energy level and afterwards checks if the energy is equal to zero or even smaller. This is

done in lines 4 and 5. After one simulation step, the wolf has an energy level of 5 and the check in line 4

passes as false. In the next simulation step the energy is reduced by another 5 which leaves the wolf with

an energy level of 0. The check in line 4 goes through and the command in line 5 is executed, which kills

the wolf. After this line of code has been executed, the wolf has died and will not be part of the simulation

anymore.

0 agent wolf on AgentLayer{

1 var Energy : integer = 10

2 tick{

3 Energy = Energy - 5

4 i f(Energy <= 0){

5 k i l l me

6 }

7 }

8 }

Listing 23: Wolf agent dying from not having enough energy

5.7 layer

Layers serve two purposes. They are containers for agents and can contain data as in the case of raster-layer

and vector-layer . They are used to manage the agents and allow for exploration functionality which will

be covered in the explore (5.3) section. For now, the layer keyword will be used as container for agents.

Later in this handbook, layers with time-series capabilities ( vector-layer (5.21) ) and GIS functionality (

raster-layer (5.13) ) will be introduced. In general, new layers are created by using the following syntax:

layer layer name

The layer keyword tells the model that a new layer with the name layer name should be added. The

layer should be named so that it can later be referred to as it is the case with creating new agent types.

5.7.1 Layer Attributes and Functions

Basic layers (the ones that contain agents) can fulfill different tasks in the model. They can store information

and even offer actions that can be used by the agents. Listing 24 shows an example model that demonstrates

how this works. In the scenario the firewood collector agent can go out and collect firewood that is then

stored in the village. Alternatively the agent can check if the village has enough firewood so that he can take

it from there instead. In the example, the layer is used as shared resource between the agents. To implement

this, the agent layer (AgentLayer) will offer two methods. The first method (StoreFirewood) is performed

by the agents when they return from collecting. The second method (WithdrawFirewood) can be used to

Page 36 of 60

Page 41: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

take firewood when there is plenty.

In line 17 the agent checks how much firewood is available in the village. The layer stores this information in

the AmountOfFirewood variable that can be read by the agents. If there is enough firewood, the agent will

take it from there as shown in line 18 by using the WithdrawFirewood method. In case there isn’t enough

available in the village (line 20), the agent will go and look for firewood in the surroundings. When he comes

back from collecting, he puts some of it in the villages storage so that others can take from there. To store

firewood he uses the StoreFirewood method.

0 model firewood

1

2

3 layer AgentLayer as agentlayer{

4 var AmountOfFirewood : integer = 0

5

6 def StoreFirewood(KiloFirewood : integer){

7 AmountOfFirewood = AmountOfFirewood + KiloFirewood

8 }

9

10 def WithdrawFirewood(KiloFirewood : integer){

11 AmountOfFirewood = AmountOfFirewood - KiloFirewood

12 }

13 }

14

15 agent FirewoodCollector on AgentLayer{

16 tick{

17 i f(agentlayer.AmountOfFirewood > 5){

18 agentlayer.WithdrawFirewood(5)

19 }

20 else{

21 //go get firewood

22 //...

23

24 agentlayer.StoreFirewood(3)

25 }

26 }

27 }

Listing 24: Firewood collectors using a layer as shared resource

5.8 move

Most agents will move during simulations, the basis for that is the positioning system. This system is based

on a grid which spans the whole simulated area and can have any size. The actual size is determined by the

user of the MARS system and will be specified once the model has been uploaded for simulation execution

in the MARS cloud.

Page 37 of 60

Page 42: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Figure 23: Coordinate system for the models

5.8.1 Coordinate System

Starting in the lower left corner, the coordinate system stretches the whole simulation area. The actual size,

meaning the number grid cells in x- and y-direction will be set later during simulation setup in the MARS

cloud. Coordinates in the system are composed of two values for x- and y-position thus the notation as

shown in figure 23. The position in the lowest left corner is (0/0). Moving one field to the right leads to

(1/0) whereas one field to the top would lead to position (0/1). In a simulation model, the coordinates are

noted in the following way:

#( x-coordinate , y-coordinate )

Please note that the coordinate system has its bounds. It is not possible to move to negative coordinate

like (-3/-4), (-10/6) or (5/-7). Moving outside the defined grid is not possible either. This means that

the agents can’t go to (101/101) if the grid has the dimensions of 100x100 fields. The agents will stop

at the borders and will not move farther. There is NO such thing as a wraparound that inserts the

agents at the opposite site of the grid.

5.8.2 Movement Command

The agents can move by using the move me to command. It is up to you as a modeler to move the agent

either from one grid cell to another or even over multiple cells at once. Movements can be performed in

any direction so it is possible to go up, down, left, right and diagonally as well. The syntax for the move

command looks like this:

move me distance to destination

Page 38 of 60

Page 43: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

First the move me command is written, followed by an optional distance parameter specifying how far

the agent (how many grid cells) is going to move. If this distance parameter is left out, a default value

of 1 is assumed so that the agent moves to the next grid cell corresponding to a step length of one. Again

this can either be up, down, left, right or diagonally. All of these movements have a length of 1, there is no

Manhattan metric involved. The next part of the move command is to write the to statement followed by

the destination the agent is supposed to move to. Destination can either be another agent or a coordinate.

Movement Examples

0 //start position: (1/1)

1 move me to #(0,0) //position: (0/0)

2 move me to #(1,0) //position: (1/0)

3

4 //start position: (10/10)

5 move me 5 to #(10,15) //position: (10/15)

6 move 10 to #(20,15) //position: (20/15)

7

8 //start position: (5/5)

9 move me 10 to #(8,5) //position: (15/5)

10 move me 10 to #(15,10) //position: (15/15)

11

12 //start position: (3/3)

13 move me 5 to #(-3,3) //position: (0/3)

14 move me 5 to #(0,-3) //position: (0/0)

Listing 25: Example movement actions

Line 0:

The agent starts at position (1/1). Executing the move command in line 1 moves him to position (0/0). No

distance parameter was specified so the step length is set to 1. If the agent moves towards position (0/0) he

does that one step at a time. Since the grid cell (0/0) is exactly one field away from the agents start position

of (1/1), the move command brings the agent there in one step. The agent has moved diagonally.

Now that the agent is at (0/0), the next move command (line 2) brings him to position (1/0). Again no

distance parameter was specified so 1 is assumed. The field (1/0) is one grid cell apart from (0/0) so the

agent can move there in one step moving to the right.

Line 4:

New start position is (10/10). The first move command (line 5) tells the agent to move 5 field towards

position (10/15). Distance to that position is 5 so the agent can move there in one step as specified.

Same goes for the move command in line 6. The agent starts at position (10/15) and is told to move to

position (20/15). Distance this time is 10 fields. Again the agent is told to move exactly that far which

leaves him at position (20/15).

Line 8:

The agent starts at position (5/5) and is sent 10 fields in the direction of (8/5). Since the direction coordinate

(8/5) is on the way but the 10 fields he is told to move is farer away than the 3 steps the destination is away,

the agents steps over the (8/5) field and keeps going in that direction until he reaches its new position (15/5)

which is 10 grid cells apart from the starting point. In line 10 the agent is told something similar. The

direction (15/10) is closer to the agent in terms of distance than the 10 fields he is told to move. Therefore

the agent heads in the direction of (15/10) and gets to its new position (15/15).

Line 12:

This example shows whats going to happen when the agent tries to exceed the coordinate system. Starting

Page 39 of 60

Page 44: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

point is (3/3) with the first command telling the agent to move 5 field in the direction of (−3/3). The agent

can move in that direction but only until he hits the minimum x-coordinate of 0. Therefore he stops at

position (0/3). In the the next line the agent is told to move in the direction of (0/− 3) which, as before, is

outside of the valid coordinate space. The agent starts to move in that direction until he reaches position

(0/0) at which he cannot move further. His movement leaves him at position (0/0).

5.9 nearest

Another way of exploring the environment is the nearest command. Similar to the explore keyword,

this can be used to find agents. The feature that distinguishes the two commands is the GIS capabilities of

nearest . Besides finding agents, it is possible to find features on raster-layers and vector-layers as well.

The difference between nearest and explore is that the nearest command returns the closest point, not

all points as explore does. Even though one tries to find the nearest agent or feature on a raster-layer /

vector-layer , one receives that entities position. So the nearest functionality returns a position, not an

agent or raster/ vector feature.

The nearest command can lead to model crashes if you don’t treat the returned values right. Since

the nearest keyword returns the position of agents/ GIS features, it can only do so if the desired entity

is available. Please read the Null Reference Exceptions paragraph below prior to using nearest in you

model. This might spare you a lot of trouble later on.

Finding agents works similar to the explore command. First you write the nearest command, then you

specify the agent type that you want to find. As a result you get the position of the closest agent of that

type which can then be used to calculate a distance for moving there.

nearest agent type

When you are trying to find certain GIS features with the nearest command you have to modify it a bit.

We start again with the nearest keyword but then we add on afterwards. The last part of the command is

specifying the raster layer name / vector layer name . This tells the system on which layer it should look

for the closest feature. As with the basic version of nearest , you receive the closest position of the desired

feature, not the feature itself.

nearest on raster layer name

nearest on vector layer name

Additionally, the nearest function can be extended with a search radius. In the default setting, the nearest

command searches the whole simulated area to find either an agent or a feature on a GIS layer. If you wan’t

to limit this radius, thereby giving the agent a field of view, you can use the notation below. The radius

originates in the agents current position.

nearest agent type in radius

nearest on raster layer name in radius

nearest on vector layer name in radius

Page 40 of 60

Page 45: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Null Reference Exceptions When you use the nearest command you have to treat the results with

caution since there might be no result. Remember, the returned value of nearest is a position of either

an agent or a GIS feature. Problems can occur if the desired feature or agent doesn’t exist. In the wolf,

sheep, grass model this could happen if the wolf tries to find the nearest sheep but there aren’t any left.

Nearest would return an empty position since there is no sheep nearby. If the wolf was to use this empty po-

sition as input for the move command, the model would crash. Instead, the agent should be build in a way

that checks if the position is valid prior to using it as parameter for other commands like the move operation.

Listing 26 shows an example from the wolf, sheep, grass model where the wolf examines the resulting

coordinate before using them. In line 2 he tries to find the nearest sheep by using the nearest command.

Before he tries to go there (line 4), he checks the resulting position from the nearest operation. This is

done in line 3 where he checks if the result is something different than nil. Nil is the replacement value if

the nearest operation couldn’t find anything. It basically means nothing (latin: nil = nothing). In case the

coordinate is indeed nil, he wouldn’t execute the move operation but execute the else path.

0 agent wolf on AgentLayer{

1 tick{

2 var nearestSheep = nearest sheep

3 i f(nearestSheep != nil){

4 move to nearestSheep

5 nearestSheep.BeEaten()

6 }

7 else{

8 //specify alternative action

9 }

10 }

11 }

Listing 26: Wolf agent examining the results of nearest prior to using it

continue here

5.10 observe

Part of the simulation results are custom agent attributes. By default only the agents position is written in

the result database. That way you can examine the movement in the browser and look at population counts.

If you wan’t to have additional agent attributes added to the results, you can use the observe keyword.

Written before a variable, it leads to that variable being saved in every simulation step.

In listing 27 you can see a sheep agent with a variable name Energy. Before writing the var keyword, the

observe keyword has been added. In every simulation step that Energy variables value will be written to the

result database so you as a modeler can look at the current value for every simulated time step afterwards.

0 agent sheep on AgentLayer{

1 observe var Energy : integer = 40

2 tick{

3 Energy = Energy - random(3)

4 }

5 }

Listing 27: Sheep agents who’s Energy variable is added to the results in every simulation step

Page 41 of 60

Page 46: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

5.11 pos at

Besides the move command there is another way of changing an agents position. Using the pos at keyword

you can set the agent position to a grid cell of your choice. The difference between the two commands is

that move actually moves the agent while pos at relocates the agent by basically beaming him there. If

you ask yourself when you should use which, consider the following: Whenever your agent is supposed to

move a certain amount of grid cells in a direction use the move command. When you know the agents

destination coordinates you can use pos at to get him there instantly. For the model it makes no difference

how the agent got to a position so feel free to use the command of your choice.

pos at destination coordinate

Using the command is very easy. Write pos at and add the destination coordinate in coordinate notation.

You can either do this with a coordinate or with a placeholder like the nearest command. In listing 28 you

can see the wolf agent using the pos at command to change its position. Line 2 shows him setting position

to coordinate (5/5). In line 3 he uses the pos at command to relocate to the nearest sheep’s position.

0 agent wolf on AgentLayer{

1 tick{

2 pos at #(5,5)

3 pos at nearest sheep

4 }

5 }

Listing 28: Wolf agent using the pos at to set its position

5.12 random

The random command creates random numbers in a specified range. These numbers will be in between zero

an a upper bound. The upper bound is specified through the parameter enclosed by parentheses.

random ( upper bound )

The generated numbers will be from zero up to the specified bound, but not the upper bound itself. Creating

a random number in between zero and five will be 0,1,2,3,4 but never five! Another example can be seen in

listing 29 where, in line 0, we create random numbers in between zero and three. Possible values are zero,

one and two, but not three.

0 random(3)

1

2 random(10)-5

3 random(15)+5

Listing 29: Examples on how to use the random function

If you want to create random numbers starting at another point than zero you will have to take a different

approach. Add or subtract the lower bound from the random value and specify the range you want by

adapting the upper bound. For example if you want to have random numbers between -5 and 5 you would

write it like shown in line 2 of listing 29. Possible values from that statement are {-5,-4,-3,-2,-1,0,1,2,3,4}.Same goes for the command in line 3 which produces random numbers in between five and twenty.

Page 42 of 60

Page 47: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

5.13 raster-layer

Refine wording since the raster layer isn’t the only way to use GIS data anymore

If you want to use GIS data during simulation, the raster-layer is the way to go. This special layer type

allows access to rasterized GIS files in the ASC format. During simulation the agents can read information

from these files and even change them (writing access). Like regular layers the raster-layer has to be defined

in the beginning of the model.

raster-layer layer name as layer alias

Listing 30 shows an example model that includes a raster-layer and uses the whole capabilities of it: At first

a model is defined (name: wolf sheep grass), then an agent layer (name: agentLayer) is put in and at last

a new agent type (name: sheepAgent) is created on the agent layer. The raster-layer with the name Gis-

GrassLayer is created in line two. You start by defining the layer, giving it a name and then specifying the

alias by which it is referred to in the model code. Naming is done in the way that the name (GisGrassLayer)

is written in camel case and the alias (gisgrasslayer) in lower case. Once this is done the layer is ready to

be used by the agents. This usage can be divided into three groups: reading information from the layer,

changing the layers information and finding coordinates with certain features.

Starting with the last category: Take a look at line 8 where the nearest command is used in combination

with the raster-layer. Similar to the usage of nearest with agents this operation doesn’t return a value from

the raster-layer but a coordinate with a certain feature. The feature that the raster-layer is looking for is

a value not equal to the nodata value specified in the ASC file that will be added later to the simulation.

Take a look at the GIS ASC Files (6.3.2) section where you can find more information about ASC files

as well as an example file. What the nearest function does is trying to find the closest grid cell with an

actual value. That grid cell is the result and will be returned. For more information about the usage of

nearest in combination with the raster-layer please see section nearest (5.9) where the details are described.

Next usage scenario for the raster-layer is reading information from it. The type of information you can

read depends on the information contained in the ASC file. In general it is possible to read the values either

as integers or floating point numbers. Therefore the DSL offers two corresponding functions by the name of

GetIntegerValue and GetNumberValue. How they are used can be seen in listing 30 in lines ten and eleven.

Both functions return the value in their respective format (integer or real). That is why the lines start

with variable declarations to save these resulting values. The syntax for using the two commands is straight

forward. First you specify the raster-layer you want to read from, then you choose the format in which

you want to read the information. For both GetIntegerValue as well as GetNumberValue you have to specify

the coordinate you wan’t to have the value for. If you want to read values from the grid cell your agent is

currently on you just pass xcor and ycor . In case you want to read from a different grid cell you can

specify the coordinates alike.

0 model wolf_sheep_grass

1

2 raster-layer GisGrassLayer as gisgrasslayer

3

4 layer agentLayer

5

6 agent sheepAgent on agentLayer{

7 tick{

8 var nearestGrass = nearest on GisGrassLayer

9

Page 43 of 60

Page 48: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

10 var a = gisgrasslayer.GetIntegerValue(xcor,ycor)

11 var b = gisgrasslayer.GetNumberValue(xcor,ycor)

12

13 gisgrasslayer.Increase(xcor,ycor,2)

14 gisgrasslayer.Reduce(xcor,ycor,5)

15 }

16 }

Listing 30: Model creation with a raster-layer

The third way of working with the raster-layer is changing its values. Increase and Reduce are functions

built into the DSL that allow to increase the value of a grid cell by adding something while the reduce

command allows to subtract something from the cells value. As with the commands to read from the layer

you have to specify a grid cell in coordinate notation for which you want to change the values. If it is the

same position the agent is on you can use xcor and ycor . The last parameter passed to the function is the

number/ amount you want to either add or subtract. Listing 30 shows examples for both commands in line

thirteen and fourteen. Please note that neither Increase nor Reduce return any values. Another example

of changing the values of a raster-layer can be found in section 6.5.5 where an observer agent is used to go

through all grid cells and update the values.

5.14 simtime

When you wan’t to know about the time during simulation you can use the simtime . It can either be used

to learn about the current tick you’re in as well as be used to find out the exact date and time. This means

you can let an agent do something after the 200th tick has happened for example. You can also use the

actual time to tailor behavior to a certain point in time like having wolfs howl when the moon is out.

5.14.1 Simtime Example 1

In this example the observer agent is using the simtime function to find out in which tick it is. If it reaches

the 20th tick a new wolf agent will be spawned at a random position. The comparison shown in line 2 of

listing 31 reads the simtime object and checks if the current tick equals 20. If that is the case the command

in line 3 is executed thereby spawning a new wolf agent.

0 agent Observer on AgentLayer{

1 tick{

2 i f(simtime === 20){

3 spawn wolf at #(random(100),random(100))

4 }

5 }

6 }

Listing 31: Observer agent using the simtime functionality

5.14.2 Simtime Example 2

The second example demonstrates another functionality of the simtime command. By using simtime in

combination with the Time package you can get exact information about the current year, month, day,

hour, minute or even second of the tick.

Page 44 of 60

Page 49: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

Before using the Time package you have to include Mars as shown in line 2 of listing 32. With this included

you have access to the needed functionality. Take a look at lines 8 through 12 in the example. For each of

these lines we create a variable to store the received information (a-e).

The time (year, month, day, hour, minute, second) that the shown commands will return depend on

the simulation start date as well as the delta t set in the MARS cloud UI.

0 model wolf_sheep_grass

1

2 use Mars

3

4 layer AgentLayer

5

6 agent Observer on AgentLayer{

7 tick{

8 var a = Time.Year(simtime)

9 var b = Time.Month(simtime)

10 var c = Time.Day(simtime)

11 var d = Time.Minute(simtime)

12 var e = Time.Second(simtime)

13 }

14 }

Listing 32: Observer agent finding out about the exact time during a simulation

If you set the start date to January 1st of 2019 at midnight, the example will yield the following results in

the first tick:

Line 8: Variable a will return the number 2019

Line 9: Variable b will return the number 1

Line 10: Variable c will return the number 1

Line 11: Variable d will return the number 0

Line 12: Variable e will return the number 0

5.15 spawn

Creating agents during simulation can be done using the spawn command. This feature comes in handy

if your agents reproduce for example. Spawning can happen at any point in the simulated area. When you

create a new agent with the spawn keyword, the new agents initialize method will be executed once when

he is created. This is the place where you should specify the agents initial attributes. For more information

on initialize see section 5.5.

spawn agent type

Syntax for the spawn command is straightforward. First you write the keyword itself and then you add the

desired agent type of which a new agent should be created. While the simple version of spawn command

spawns a new agent at the position of the calling agent, the more elaborate one can spawn new agents at

any point in the simulated space.

Page 45 of 60

Page 50: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

spawn agent type at coordinate

If you wan’t to spawn the agent at a position different from the current agent you simply add a coordinate

after the on keyword. The beginning of the spawn process is the same.

In listing 33 you can see the wolf agent using the spawn command twice. Line 2 shows him spawning a new

wolf at his current position. In line 3 he creates a new wolf at position (3/3).

0 agent wolf on AgentLayer{

1 tick{

2 spawn wolf

3 spawn wolf at #(3,3)

4 }

5 }

Listing 33: Wolf agent spawning new wolves during simulation

5.16 static

Agents can have static properties. This allows all agents of the same type to have a shared status than is

the same for every agent instance. Each agent can read and change that value, thereby changing it for all

agents. The static concept is the same as in the programming language C#. For more information you

can read up on it here.

5.17 tick

The tick method is the central method of every agent. Here you specify what each agent is doing during

each simulation step. These agent instruction go in between the curly braces. Inside the agents curly braces

you define the tick as shown in listing 34 where you can see the wolf agent with its tick method.

tick {}

0 agent wolf on AgentLayer{

1 var Energy : integer = 10

2

3 tick{

4 move 1 up

5 Energy = Energy - 1

6 i f(Energy<=0){

7 k i l l me

8 }

9 }

10 }

Listing 34: Tick example from the wolf sheep grass model

5.18 ts-layer

Time-series data can be used during simulation through the ts-layer . As with other layers you have to

create it prior to the agent definition. The ts-layer cannot manage agents so it isn’t possible to place agents

on it. Lets say you have a file that contains precipitation or temperature values for certain points in time

Page 46 of 60

Page 51: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

and you wan’t to use the data in your simulation. You would create a ts-layer in the model and then upload

the data to the MARS cloud. Read sections 4.3 through 4.4.2 to learn about the process of importing files

and assigning them to a model.

ts-layer layer name as layer alias

Creating time-series layers works the same as with the raster-layer . First you write the keyword ts-layer

then you give the layer a name ( layer name ). The creation step is completed by adding the as keyword

an assigning the layer an alias by which it is referred to in the model ( layer alias ). It is customary to write

the layer name in camel case and the layer alias in lower case.

Lets take a look at listing 35 which demonstrates the layers capabilities. In line 2 a new ts-layer by the

name of PrecipitationLayer is created. The grass agent accesses this layer in line 9 where it reads the current

value for the simulated time. The value that is going to be read originates in the file uploaded to the MARS

cloud once the simulation is running. You will have to setup the scenario so that the the simulated time

matches the time span covered in that time-series file. Learn more about time-series files in the Time-series

CSV Files (6.4.1) section. The values contained in that file for the current simulation tick can be requested

by the ts-layer either as integer or a floating point number. Line 18 demonstrates functions, head over to

section to learn more about them.

0 model wolf_sheep_grass

1

2 ts-layer PrecipiationLayer as precipitationlayer

3

4 layer AgentLayer

5

6 agent grass on AgentLayer{

7 var energy : integer = 10

8 tick{

9 var currentPrecipitation = precipitationlayer.GetNumberValue()

10

11 i f(currentPrecipitation > 5){

12 grow(2)

13 }

14 else{

15 grow(1)

16 }

17 }

18 def grow(amount : integer){

19 energy = energy + amount

20 }

21 }

Listing 35: Grass agents growth depending on the amount of current rainfall

5.19 val

There are two types of variables that differ only in the way they can be accessed. The var command

specifies variables that can be assigned and then modified while variables created with val can only be

Page 47 of 60

Page 52: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

assigned once and keep their value after that. This is corresponds to the readonly modifier in C# on which

you can read more here.

Use this type of variables when you wan’t to make sure that the value isn’t being change over the course of

the agents/ layers life.

5.20 var

There are two types of variables that differ only in the way they can be accessed. The var command

specifies variables that can be assigned and then modified while variables created with val can only be

assigned once and keep their value after that.

The var keyword is the default way of working with variables. Unless you have a good reason you should

always stick to them.

5.21 vector-layer

Utilizing vector-based GIS data during simulation can be achieved by using the vector-layer command. This

type of layer allows to import and query GeoJSON files. During simulation the agents can read information

from these files and even change them (writing access). Like regular layers the vector-layer has to be defined

in the beginning of the model.

vector-layer layer name as layer alias

Listing 36 shows an example model that includes a vector-layer and uses the whole capabilities of it: First,

a model is defined (name: wolf sheep grass), then a layer (name: agentLayer) is put in and at last a new

agent type (name: sheepAgent) is created on the agent layer. This follows the basic principles for agents and

layers. The vector-layer with the name GisGrassLayer is created in line two. You start by defining the

layer, giving it a name and then specifying the alias by which it is referred to in the model code. Naming

is done in the way that the name (GisGrassLayer) is written in camel case and the alias (gisgrasslayer) in

lower case. Once this is done the layer is ready to be used by the agents. This usage can be divided in two

groups groups: reading information from the layer for the current tick and finding coordinates with certain

features.

Starting with the last category: Take a look at line 8 where the nearest command is used in combination

with the vector-layer . Similar to the usage of nearest with agents this operation doesn’t return a value

from the vector-layer but a coordinate with a certain feature. Take a look at the GIS GeoJSON Files

(6.4) section where you can find more information about GeoJSON files as well as an example. What the

nearest function does, is trying to find the closest position with an actual value. That coordinate is the

result and will be returned, saved to the nearestGrass variable.

Line 9 shows a similar search for a feature. The difference is the origin of that search. While the search

of line 8 originates in the agents current position, the one in line 9 originates at the specified coordinate

with position (2/2) and reveals the closest feature from that point. For more information about the usage

of nearest in combination with the vector-layer please see section nearest (5.9) where the details are

described.

Next usage scenario for the vector-layer is reading information from it. The type of information you can

read depends on the information contained in the GeoJSON file. In general it is possible to read the values

either as integers or floating point numbers. Therefore the DSL offers two corresponding functions by the

name of GetIntegerValue and GetNumberValue. How they are used can be seen in listing 30 in lines ten and

eleven. Both functions return the value in their respective format (integer or real). Lines 11 and 12 both

start with a variable declaration where the results of these methods will be stored. The syntax for using

Page 48 of 60

Page 53: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

the two commands is straight forward. First you specify the vector-layer you want to read from, then you

choose the format in which you want to read the information.

0 model wolf_sheep_grass

1

2 vector-layer GisGrassLayer as gisgrasslayer

3

4 layer agentLayer

5

6 agent sheepAgent on agentLayer{

7 tick{

8 var nearestGrass = nearest on GisGrassLayer

9 var nearestPoint = nearest on GisGrassLayer of #(2, 2)

10

11 var a = gisgrasslayer.GetIntegerValue()

12 var b = gisgrasslayer.GetNumberValue()

13 }

14 }

Listing 36: Model creation with a vector-layer

5.22 x-cor and ycor

The agents position on the grid are denoted by the two variables xcor and ycor . Each agent automatically

has these variables. They are read-only so you cannot change their values directly. If you wan’t to relocate

an agent you can either use the move or the pos at command.

Page 49 of 60

Page 54: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

6 Cookbook

6.1 Example Models

6.1.1 Wolf, Sheep, Grass

0 model WolfSheepPredation

1

2 use Mars

3 layer Grassland

4 raster-layer BiomassRaster as biomass {

5 def EatBiomass(cell : Tuple<integer, integer>, amount : real)

6 {

7 var mass = biomass.Reduce(cell.Item1, cell.Item2, amount)

8 i f(mass >= 0) return mass else return 0

9 }

10 }

11

12 /**agent Observer on Grassland {

13 tick {

14 var growthRate = random(10)

15 while(growthRate > 0) {

16 biomass.Increase(random(100), random(100), random(5) - 5)

17 growthRate--

18 }

19 }

20 }*/

21

22 agent Sheep on Grassland {

23

24 observe var Energy : real = 50

25 observe var EnergyMax : integer = 80

26 observe var Hunger : integer

27 observe var TargetDistance : real

28 observe var Rule : string = ""

29 //var Target : Grass

30

31 i n i t i a l i z e Sheep {

32 pos at #(random(100), random(100))

33 println "Current position (" + xcor + ", " + ycor + ")"

34 }

35

36 tick{

37 //reduce energy

38 Energy = Energy - (1 + random(3))

39 i f(Energy < 0) k i l l me

40 var diff = (EnergyMax - Energy)

41 var rel = (diff / ((EnergyMax) as real))

42 var hunger = (rel * 100)

43 Hunger = hunger as integer

Page 50 of 60

Page 55: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

44 i f(hunger > 20) Energy = Energy +

45 Math::Abs(biomass.EatBiomass(#(xcor, ycor), random(4)))

46 RandomMove()

47 }

48

49 def RandomMove() => move me to #(xcor + random(2)-1, ycor + random(2)-1)

50

51 passive Die() => k i l l me

52 passive GetPosition() => return #(xcor,ycor)

53 passive GetFoodValue() => return Energy

54 }

55 agent Wolve on Grassland {

56

57 observe var Energy : real = 80

58 observe var EnergyMax : integer = 100

59 observe var Hunger : integer

60 observe var TargetDistance : real

61 observe var Rule : string = ""

62 var Target : Sheep

63

64 i n i t i a l i z e {

65 pos at #(random(100), random(100))

66 println "Current position (" + xcor + ", " + ycor + ")"

67 }

68

69 tick {

70 //reduce energy

71 Energy = Energy - (1 + random(3))

72 i f(Energy < 0) {

73 k i l l me

74 }

75

76 var diff = (EnergyMax - Energy)

77 var rel = (diff / ((EnergyMax) as real))

78 var hunger = (rel * 100)

79 Hunger = hunger as integer

80

81 i f(hunger > 20) {

82 i f(Target == nil or not Target.Alive) {

83 Target = nearest Sheep

84 }

85 i f(Target !== nil) {

86 var sheepDistance = distance(Target)

87 i f(sheepDistance <= 1.4143) {

88 Rule = "R1 - Kill the sheep.";

89 IncreaseEnergy(Target)

90 } else {

91 var position = Target.GetPosition

92 Rule = "R2 - Moving towards sheep (" +

Page 51 of 60

Page 56: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

93 position.Item1 + ", " + position.Item2 + ").";

94 move 1 to Target

95 }

96 }

97 } else {

98 TargetDistance = 0

99 Rule = "R3 - No target: Random movement.";

100 move me to #(random(60), random(60))

101 }

102 }

103

104 active IncreaseEnergy(sheep : Sheep) {

105 var energy = sheep.GetFoodValue

106 Energy = Energy + energy

107 i f(Energy > EnergyMax) Energy = EnergyMax

108 sheep.Die

109 }

110 }

Listing 37: Wolf sheep grass example model

6.1.2 Chatting Agents

This model features two agent types (TeaLover and CoffeeLover) that use a layer to communicate with each

other. Both wait for an invitation for either tea or coffee. If they receive such an invitation they would

accept it by responding with yes. All communication is handled by the MailboxLayer which implements two

functions PutMessage and ReadMailbox to access the messages. Thereby agents can send and read messages.

0 model LayerMailbox

1

2 layer MailboxLayer as mailbox {

3

4 var Mailbox : Tuple<string, Sender> = nil

5

6 def PutMessage(message : string, sender : Sender)

7 => Mailbox = #(message, sender)

8

9 def ReadMailbox() => return Mailbox

10 }

11

12 agent TeaLover on MailboxLayer {

13 tick {

14 var post = mailbox.ReadMailbox;

15 i f("Tea time?" === post.Item1) {

16 post.Item2.Answer("Yes")

17 }

18 }

19 }

20

21 agent CoffeeLover on MailboxLayer {

Page 52 of 60

Page 57: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

22 tick {

23 var post = mailbox.ReadMailbox;

24 i f("Coffee time?" === post.Item1) {

25 post.Item2.Answer("Yes")

26 }

27 }

28 }

Listing 38: Two agent types using a layer to communicate

6.2 Useful Code Snippets

6.2.1 Agent Evolution

0 agent caterpillar on AgentLayer{

1 var agentState : integer = 0

2

3 tick{

4 i f(simtime > 200){

5 agentState = 1

6 }

7 //caterpillar state

8 i f(agentState === 0){

9

10 }

11 //butterfly state

12 else i f (agentState === 1){

13

14 }

15 }

16 }

Listing 39: Simulation of a caterpillar that turns into a butterfly after 200 ticks

6.2.2 Agent Live Stages

0 agent elephant on AgentLayer{

1 var stage : integer = 0

2 var simulatedDays = 0

3

4 tick{

5 simulatedDays = simulatedDays + 1

6

7 //change agent stage base on simulation time

8 i f(simulatedDays === 10){

9 stage = 1

10 }

11 i f(simulatedDays === 20){

12 stage = 2

Page 53 of 60

Page 58: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

13 }

14

15

16 //Calf

17 i f(stage === 0){

18

19 }

20 //Adolescent

21 else i f(stage === 1){

22

23 }

24 //Adult

25 else{

26

27 }

28 }

29 }

Listing 40: Elephant with conditional behavior based on the stage of live he is in

6.2.3 Random Walk

0 model random_walker

1

2 layer AgentLayer

3

4 agent RandomWalkAgent on AgentLayer {

5 tick {

6 switch (random(8)) {

7 case 0 : { move left }

8 case 1 : { move right }

9 case 2 : { move down }

10 case 3 : { move up }

11 case 4 : { move up-left }

12 case 5 : { move up-right }

13 case 6 : { move down-right }

14 case 7 : { move down-left }

15 }

16 }

17 }

Listing 41: Randomly walking agent. Moves 1 grid cell in every simulation step

6.2.4 Biomass Removal

This snippets shows an example where the surroundings are modeled as biomass. The biomass information

itself is contained in a raster-layer . Each grid cell contains a certain amount of biomass that the agents,

elephants in this case, can eat. The elephant moves around in every tick but only eats between 6am and

8pm. Using the simtime command together with the Mars package we can get the current hour of the day

(line 10). Simulation step duration (delta t) has to be set to one hour when executing this model.

Page 54 of 60

Page 59: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

0 model elephant_biomass_removal

1

2 use Mars

3

4 raster-layer BiomassLayer as biomasslayer

5 layer AgentLayer

6

7 agent Elephant on AgentLayer{

8 var energy : integer = 10

9 tick{

10 var currentHourOfDay = Time.Hour(simtime)

11 i f(currentHourOfDay > 6 and currentHourOfDay < 20){

12 biomasslayer.Reduce(xcor,ycor,5)

13 }

14 move me 3 to #(random(100),random(100))

15 }

16 }

Listing 42: Elephant agent removing biomass from its surroundings

6.2.5 Agent Interaction: Buying Goods

0 agent FruitDealer on AgentLayer{

1 var AppleSupply = 20

2 passive BuyApple(money : integer) : bool{

3 i f(money >= 2){

4 i f(AppleSupply > 0){

5 AppleSupply = AppleSupply - 1

6 return true

7 }

8 }

9 return fa l se

10 }

11 }

12 agent buyer on AgentLayer{

13 var money : integer = 10

14 tick{

15 var dealer = nearest FruitDealer

16 i f(dealer.BuyApple(money)){

17 money = money - 2

18 println "I bought an apple"

19 }

20 else{

21 println "Couldn’t get an apple"

22 }

23 }

24 }

Listing 43: Two agents trading apples

Page 55 of 60

Page 60: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

6.3 Data Usage Examples

6.3.1 Agent Init Files

Agent init files can be used to initialize agents individually so that each agent has its own set of variables that

differs from these of other agents of the same agent type. This is advanced functionality that can be used in

combination with the MARS cloud system. Prerequisite to using this is to annotate the agents parameter

that should be set with this method by adding the external keyword to the variable definition. Listing

45 shows an agent init file example that can be used with the model shown in listing 44. This wolf agent

has three external variables name energy, weight and name (listing 44). All are of different types (integer,

floating point and string).

0 agent wolf on AgentLayer{

1 external var Energy : integer

2 external var Weight : real

3 external var Name : string

4 }

Listing 44: Wolf agent with three external attributes

These attributes are filled later on during simulation creation with the following agent init file. Since the file

has four lines, you can created up to four agents from it. The first line of an agent init file should contain

the names of the variables that are going to be set through it. The correct formatting is important, if not

done properly it won’t work. Delimiter for everything are semicolons, no spaces are to be used.

0 energy;weight;name

1 10;14.3;"Bob"

2 12;20.6;"John"

3 24;2.0;"Chad"

4 5;15.4;"James"

Listing 45: Agent init file for the wolf

6.3.2 GIS ASC Files

Here we can see an example file that was used in the wolf, sheep, grass model to represent the grass. Each

patch in that 10 by 10 grid has an integer number depicting the amount of grass on that patch. sheep would

move around the simulated area and eat from the grass by decreasing the values.

0 ncols 10

1 nrows 10

2 xllcorner 0

3 yllcorner 0

4 cellsize 0.1

5 nodata_value -99

6 4 7 4 4 4 2 4 4 4 4

7 1 4 4 4 4 6 4 4 4 1

8 4 4 3 4 4 4 4 7 4 4

9 2 4 4 8 4 5 4 6 4 2

10 4 9 4 4 4 4 4 4 4 4

Page 56 of 60

Page 61: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

11 4 4 4 7 4 1 4 4 3 4

12 3 0 4 4 4 4 1 4 4 4

13 4 4 8 4 9 4 9 9 4 8

14 5 4 4 4 4 4 4 4 4 4

15 4 4 4 4 8 4 4 4 2 4

Listing 46: GIS grass ASC file with 10x10 grid size

6.4 GIS GeoJSON Files

Add section about GeoJSON Files

6.4.1 Time-series CSV Files

Time-series data can be used by the MARS system if it is formatted as CSV file. Each line must contain a

timestamp as shown in figure 47 followed by the actual value. This value can either be of type float or an

integer. Delimiter for the file are semicolons and no spaces are allowed. The first line of the file must be

similar to the depicted version in figure 47, otherwise the MARS system won’t recognize it as a time-series

file. Parameter number three of the first line (temperature) should be a description of the data. In figure 47

the files contains temperature values so its called temperature.

0 date;hour;temperature

1 2019-01-01;12:00;5.0

2 2019-01-01;13:00;6.1

3 2019-01-01;14:00;7.3

4 2019-01-01;15:00;7.0

5 2019-01-01;16:00;6.8

6 2019-01-01;17:00;6

7 2019-01-01;18:00;5.9

Listing 47: Example time-series file with temperature values

6.5 Programming Features

6.5.1 Functions

Agents and layers can use functions to simplify or structure their code. Functions can be defined inside

classes, agents and layers. Note that you cannot define functions inside the agents tick and initialize

methods.

def method name ( parameters ) : return type {}

New functions are defined by writing the def command followed by the desired name of the function.

Enclosed in braces follow parameters which are optional. After the parameters you can specify the return

type of the function. This is optional as well. You can choose between bool , integer , real , string and

void to either return a boolean value, an integer, real, string or nothing in the case of void . At last you

have to put curly braces. The function code will be contained in these. Listing 48 shows an agent with two

example functions. The first one defined in line 7 takes two parameter a and b and multiplies them. In line

8 the result is computed and returned to the caller. When this function is called (line 3) it will take the two

input parameters (2 and 3 in this case) and multiply them. Line 4 prints the result which will be 6 in the

example. Functions can also be used to alter variables. The TestAgent defines a variable named health in

Page 57 of 60

Page 62: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

line 1 which will be changed by the increaseHealth function. This function expects a floating point number

as input (amount) and won’t return any values as denoted by the void in the definition. When this function

is called in line 5 the agents health is going to increase by five.

0 agent TestAgent on AgentLayer{

1 var health : real = 10

2 tick{

3 var result = multiply(2,3)

4 print(result)

5 increaseHealth(5)

6 }

7 def multiply(a : integer, b : integer) : integer{

8 return a * b

9 }

10 def increaseHealth(amount : real) : void{

11 health = health + amount

12 }

13 }

Listing 48: Function examples

6.5.2 Arrays

Arrays work the same as in most programming languages as they start at zero. New arrays can be created

as shown in figure ???. Accessing an arrays’ value works by specifying the index the value should be read

off. Line ??? in figure ??? demonstrates this.

Write more about arrays and add a screenshot with code to demonstrate

6.5.3 Enums

add section about enums

6.5.4 Maps/ Dictionaries

add section about dictionaries/ maps

6.5.5 Loops

As in most programming languages, there are multiple loop constructs available in the DSL. Depending on

you use-case you can pick the one that suits you best. Below you’ll find example code for each of the various

loop types.

for loops are to be used when a process is to be repeated a known amount of times. You begin by

specifying a variable, i in this case, whom’s value will be checked for a condition afterwards. In this example

we define the variable i to start out at zero and then check if its value is lower than ten. If this evaluates

to true the statement enclosed by the curly braces is executed. After this has happened the last step in the

braces (incrementing i by one) is executed. This loop is repeated until i is bigger than ten which gives you

exactly ten iterations.

Page 58 of 60

Page 63: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

0 agent DemoAgent on DemoLayer{

1 tick{

2 for (var i = 0; i<10; i++){

3 print "hello"

4 }

5 }

6 }

Listing 49: For loop

foreach loops should be used if you have a list, array or set of variables you want to go through one by

one and do something. In the example below this is the array with the name c which contains two integers.

When the code is executed the loop goes over this array and prints each integer one by one. The variable

b is a placeholder that is used as the reference to the current value of the array we are currently looping

through.

0 agent DemoAgent on DemoLayer{

1 tick{

2 var c = ##[1,2]

3 each (var b in c ){

4 print b

5 }

6 }

7 }

Listing 50: Foreach loop

while loops are to be used if a piece of code is supposed to be repeated until a certain condition is met.

In the example below the condition is that the variable a is bigger or equal to ten. As long as a is smaller

than ten the statement in the curly braces is executed over and over again. Since the statement in the braces

increments a in every iteration the loop will end after executing ten times.

0 agent DemoAgent on DemoLayer{

1 tick{

2 var a = 0

3 while(a < 10){

4 print "hello"

5 a = a + 1

6 }

7 }

Listing 51: While loop

Example: Observer agent use loop to iterate over all raster cells. This code snippet shows a mini

model with a raster layer and an observer agent. The agent (Observer) uses two nested for loops to go

through all raster cells and increase their values.

Page 59 of 60

Page 64: Multi-Agent Modelling with MARS A Handbook

Multi-Agent Modelling with MARS: A Handbook

0 raster-layer GrassLayer as grasslayer

1

2 layer AgentLayer

3

4 agent Observer on AgentLayer{

5 tick{

6 for (var x = 0; x <= 10; x++){

7 for (var y = 0; y <= 10; y++){

8 grasslayer.Increase(x,y,5)

9 }

10 }

11 }

12 }

Listing 52: Observer agent going through all raster cells increasing their values

Release

Version: 1.5.5

Author: Julius Weyl

Published 08.07.2019

References

[1] Robert Axelrod. Advancing the art of simulation in the social sciences. In Simulating Social Phenomena,

pages 21–40. Springer Berlin Heidelberg, 1997.

[2] Nigel Gilbert and Klaus G. Troitzsch. Simulation for the Social Scientist. Open University Press, 2005.

[3] Daniel Glake, Julius Weyl, Christian Huning, Carolin Dohmen, and Thomas Clemen. Modeling through

Model Transformation with MARS 2.0. In 2017 Spring Simulation Multiconference, page 12, 2017.

[4] Dirk Helbing and Stefano Balietti. Agent-Based Modeling. In Social Self-Organization, pages 25–70.

Springer Berlin Heidelberg, 2012.

[5] Christian Huning, Mitja Adebahr, Thomas Thiel-Clemen, Jan Dalski, Ulfia Lenfers, Lukas Grundmann,

Janus Dybulla, and Gregory Kiker. Modeling & Simulation as a Service with the Massive Multi-Agent

System MARS. In Spring Simulation Multiconference, 2016.

[6] Julius Weyl, Daniel Glake, and Thomas Clemen. Agent-based Traffic Simulation at City Scale with

MARS. In 2018 Spring Simulation Multiconference, 2018.

Page 60 of 60