Programming NetLogo Simulations
NetLogo Procedures
Thus far, we have covered how to access, modify, and direct all entities in NetLogo.
Now it is time to learn the heart of NetLogo: the Code tab.
The way to make patches and turtles do more complex things is by creating procedures. A procedure combines a series of NetLogo commands into a single new command that you define.
Specific objective
Create a simple ecosystem model of vegetation growth, herbivore grazing, and herbivore life cycle.
Let’s Create a New Model!
To start a new model, select New
from the File
menu. Begin by creating a setup button with the following steps:
- Click the “Add” icon in the toolbar at the top of the Interface tab.
- On the menu next to “Add”, select “Button” (if it isn’t already selected).
- Click wherever you want the button to appear in the empty white area of the “Interface” tab.
- A dialog box for editing the button opens. Type
setup
in the box labeled “Commands”. - Press the “OK” button when you’re done; the dialog box closes.
Red sticky notes if this didn’t work for you.
Now you have a setup button.
Pressing the button runs a procedure called “setup”. A procedure is a sequence of NetLogo commands that we assign a new name. We’ll define that procedure soon.
The button refers to a procedure that doesn’t exist, so the button turns red.
If you want to see the actual error message, click the button.
Create the Setup Procedure
Swtich to the code tab and type:
to setup
clear-all
create-turtles 100 [ setxy random-xcor random-ycor ]
reset-ticks
end
Note: Every procedure begins with to
and ends with end
.
Understanding the Setup Procedure
What do these lines of code do?
to setup
begins defining a procedure named “setup”.clear-all
resets the world to an initial, empty state. All the patches turn black and any turtles you might have created disappear. Basically, it wipes the slate clean for a new model run.create-turtles 100
creates 100 turtles. They start out standing at the origin, that is, the center of patch 0,0.- After
create-turtles
we can put commands for the new turtles to run, enclosed by square brackets.
setxy random-xcor random-ycor
is a command using “reporters”. A reporter, as opposed to a command, reports a result. First each turtle runs the reporter random-xcor which will report a random number from the allowable range of turtle coordinates along the X axis. Then each turtle runs the reporter random-ycor, same for the Y axis. Finally each turtle runs thesetxy
command with those two numbers as inputs. That makes the turtle move to the point with those coordinates.reset-ticks
starts the tick counter, now that setup is otherwise complete.end completes
the definition of the “setup” procedure.
Switch to the Interface tab and press the setup button you made before. Repeat to see the effects of the random initialization.
Control the View
Now that we’re using the tick counter (automatically created with reset-ticks
), we should tell NetLogo that it only needs to update the view once per tick, instead of continuously updating it.
- Find the view updates menu. It’s above the view and by default says “continuous”.
- Choose “on ticks” instead.
Make the Go Button
Now make a button called “go”. Follow the same steps you used to make the setup button, except:
- For Commands enter
go
instead ofsetup
. - Check the “Forever” checkbox in the edit dialog.
- Check the “Disable until ticks start” checkbox too.
The “Forever” checkbox makes the button stay down once pressed, so its commands run over and over again, not just once.
The “Disable until ticks start” prevents you from pressing go before setup.
Add the Go Procedure
to go
move-turtles
tick
end
tick
is a primitive (i.e., built-in to NetLogo) that advances the tick counter by one tick.
move-turtles
is not, and we need to add another procedure. Note that it is common that one procedure might have (many) others nested within (i.e., dependencies).
Add the Move Procedure
Add the move-turtles
procedure after the go
procedure:
to move-turtles
ask turtles [
right random 360
forward 1
]
end
Note there are no spaces around the hyphen in move-turtles
. Earlier, we used red - 2
, with spaces, in order to subtract two numbers, but here we want move-turtles
, without spaces. The “-“ combines “move” and “turtles” into a single name.
Once finished adding the code, go back to the Interface, click setup
to initialize and go
to make your agents move.
Green sticky notes when you’ve gotten this to work.
Coding Best Practices
Why couldn’t we have just written all of these commands in go
instead of in a separate procedure?
We could have, but during the course of building your model, it’s likely that you’ll add many other parts. We’d like to keep go
as simple as possible, so that it is easy to understand.
Eventually, it will include many other things you want to have happen as the model runs, such as calculating something or plotting the results.
Each of these things to do will have its own procedure and each procedure will have its own unique name.
Creating an Environment
Now we’ve got 100 turtles aimlessly moving around, completely unaware of anything else around them. Let’s create a structured environemnt through which they will move.
Go back to the setup
procedure. We can rewrite it as follows:
to setup
clear-all
setup-patches
setup-turtles
reset-ticks
end
The new definition of setup
refers to two new procedures we need to define.
To define setup-patches
, add this:
to setup-patches
ask patches [ set pcolor green ]
end
The setup-patches
procedure sets the color of every patch to green to start with.
The only part remaining in our new setup
that is still undefined is setup-turtles. Add this procedure too:
to setup-turtles
create-turtles 100
ask turtles [ setxy random-xcor random-ycor ]
end
Go back to the interface, click “setup” and “go”.
Green sticky notes when you’ve gotten this to work.
Adding Turtle Attributes and Behavior
Thus far, our turtles are just running around. Let’s add some interaction between the turtles and the patches.
We’ll make the turtles eat “grass” (the green patches), reproduce, and die. The grass will change color and gradually grow back after it is eaten.
We’ll need a way of controlling when a turtle reproduces and dies. We’ll determine that by keeping track of how much “energy” each turtle has. To do that we need to add a new turtle variable.
You’ve already seen built-in turtle variables like color
. To make a new turtle variable, we add a turtles-own
declaration at the top of the Code tab, before all the procedures.
Call it energy:
turtles-own [energy]
Rewrite the Go procedure
Let’s use this newly defined variable (energy) to allow the turtles to eat. Go down to the go
procedure and rewrite as:
to go
move-turtles
eat-grass
tick
end
The if
statement
A turtle has direct access to the variables of the patch it is standing on. We want each turtle to determine whether the value of the patch color it is on (pcolor) is “green”, and if so, to gain energy by eating grass.
Add a new eat-grass
procedure below the move-turtle
procedure:
to eat-grass
ask turtles [
...
]
end
An “if statement” allows the program to exectue one procedure if and only if the patch color is green. Only then will the turtle run commands given inside brackets and following the test:
to eat-grass
ask turtles [
if pcolor = green [
set pcolor black
set energy energy + 10
]
]
end
The commands make the turtle change the patch color to black and increase its own energy by 10. The patch turns black to signify that the grass at that spot has been eaten.
Movement Costs Energy
Next, let’s make the movement of turtles use up some of the turtle’s energy.
Rewrite move-turtles
as follows:
to move-turtles
ask turtles [
right random 360
forward 1
set energy energy - 1
]
end
Switch back to the Interface, click “setup” and “go”, and watch your turtles graze!
Green sticky notes when you get this to work.
Creating Monitors
Use the monitor to get real-time reporting on the states of model entities.
Just like creating a button, create a monitor by clicking the “Add” icon on the toolbar, selecting “Monitor” next to it, and clicking on an open spot in the Interface.
A dialog box will appear.
- In the dialog type:
count turtles
. - Press the OK button to close the dialog.
turtles
is an “agentset”, the set of all turtles.
Create another Monitor
Create a monitor by clicking the “Add” icon on the toolbar, selecting “Monitor” next to it, and clicking on an open spot in the Interface.
A dialog box will again appear.
- In the Reporter section of the dialog box type:
count patches with [pcolor = green]
- In the Display name section of the dialog box type:
grass patches
- Press the OK button to close the dialog box.
Use the setup and go buttons and watch the numbers in the monitors change.
Green sticky notes when you get this to work.
Switches and Labels
What else is going on that we can track? Turtles are gaining and losing energy as they move around and graze.
Let’s create a switch to allow us to toggle energy reporting on and off.
- Click on the “Add” icon on the toolbar (in the Interface tab).
- Select “Switch” from the menu next to “Add”.
- Click on an open spot in the interface.
A dialog will appear.
- Into the Global variable field, type
show-energy?
- Don’t forget to include the question mark in the name.
Add Energy Switch procedure
Go back to the go
procedure in the Code tab.
Rewrite the eat-grass procedure
as follows:
to eat-grass
ask turtles [
if pcolor = green [
set pcolor black
set energy energy + 10
]
ifelse show-energy?
[ set label energy ]
[ set label "" ]
]
end
Go back to the Interface, toggle the energy switch to “on”, and click the “setup” and “go” buttons.
Green sticky notes when you get this to work.
How Does ifelse
Work?
The eat-grass
procedure introduces the ifelse
command.
Each turtle, when it runs these new commands, checks the value of show-energy?
(determined by the switch).
If the switch is on, comparison is true, and the turtle will run the commands inside the first set of brackets. In this case, it assigns the value for the energy to the label of the turtle.
If the comparison is false (the switch is off) then the turtle runs the commands inside the second set of brackets. In this case, it removes the text labels (by setting the label of the turtle to be nothing with an empty text string).
More Dynamics and Behavior
Now our turtles are eating. Let’s make them reproduce and die, and have the grass grow back.
We’ll add all three of these behaviors now, by making three separate procedures, one for each behavior.
Rewrite the go
procedure as follows to add more procedures:
to go
move-turtles
eat-grass
reproduce
check-death
regrow-grass
tick
end
Procedure for Reproduction
Add the procedures for reproduce
, check-death
, and regrow-grass
, starting with reproduce
as shown below:
to reproduce
ask turtles [
if energy > 50 [
set energy energy - 50
hatch 1 [ set energy 50 ]
]
]
end
Interpreting the reproduce
procedure
When each turtle runs reproduce
, it checks the value of the turtle’s energy variable.
If it is greater than 50, then the turtle runs the commands inside the first set of brackets.
In this case, it decreases the turtle’s energy by 50, then “hatches” a new turtle with an energy of 50.
The hatch command is a NetLogo primitive which looks like this: hatch number [ commands ]. This turtle creates number new turtles, each identical to its parent, and asks the new turtle(s) that have been hatched to run commands. You can use the commands to give the new turtles different colors, headings, or whatever. In our case we run one command. We set the energy for the newly hatched turtle to be 50.
Procedure for death
Add the following code for check-death
:
to check-death
ask turtles [
if energy <= 0 [ die ]
]
end
Interpreting the check-death
procedure
Each turtle, when it runs check-death it will check to see if its energy is less than or equal to 0.
If this is true, then the turtle is told to die (die is a NetLogo primitive).
Procedure for regrowing the grass
Add the procedures for regrow-grass
as shown below:
to regrow-grass
ask patches [
if random 100 < 3 [ set pcolor green ]
]
end
Interpreting the regrow-grass
procedure
When each patch runs regrow-grass
it will check to see if a random integer from 0 to 99 is less than 3.
If so, the patch color is set to green. This will happen 3% of the time (on average) for each patch, since there are three numbers (0, 1, and 2) out of 100 possible that are less than 3.
Run it!
Go back to the Interface, toggle the energy switch to “off,” and click the “setup” and “go” buttons.
Green sticky notes when you get this to work.
What do you notice about the dynamics? How is this communicated through the Monitors?
Plotting
Wouldn’t it be nice if we had a easier way to track the changes in the model behavior over time?
Fortunately, NetLogo allows us to plot data as we go along.
To make plotting work, we’ll need to create a plot in the Interface tab and put some commands inside it.
Create a plot
The commands we put in the plots will run automatically when our setup procedure calls reset-ticks and when our go procedure calls tick.
- Create a plot by clicking the “Add” icon on the toolbar, selecting “Plot” next to it, and clicking on an open spot in the Interface.
- Set its Name to “Totals”
- Set the X axis label to “time”
- Set the Y axis label to “totals”
- Change the name of the “default” pen to “turtles”.
- Enter plot count turtles under “Pen Update Commands”.
- Press the “Add Pen” button.
- Change the name of the new pen to “grass”.
- Enter
plot count patches with [pcolor = green]
under “Pen Update Commands”. - Press OK in the Plot dialog to finish editing.
Go back to the Interface and click the “setup” and “go” buttons.
Green sticky notes when you get this to work.
Plotting notes
-
There are not labels for the lines in the plot. Mouse over the Interface and you’ll notice that your cursor turns to cross-hairs. Click and hold while dragging over some part of the plot until it is highlighted. Now the plot is selected. Notice that the Edit and Delete buttons are no longer greyed-out. Click Edit to open the plot dialog, and then click the “Show Legend?” box.
-
When you create the plot you can also set the minimum and maximum values on the X and Y axes. You’ll want to leave the “Auto Scale” checkbox checked, so that if anything you plot exceeds the minimum and maximum values for the axes, the axes will automatically grow so you can see all the data.
-
The term “pen” is a little weird, right? But here’s the raionale … we used the plot command to add the next point to a plot. This command moves the current plot pen to the point that has an X coordinate equal to 1 greater than the previously plotted X coordinate and a Y coordinate equal to the value given in the plot command (in the first case, the number of turtles, and in the second case, the number of green patches). As the pens move they each draw a line.
Tick counter
To make comparisons between plots from one model run and another, it is often useful to do the comparison for the same length of model run. This can be done by stopping or starting an action at a specific time by stopping the model at the same point each model run.
Keeping track of how many times the go
procedure is run is a useful way to cue these actions. That’s what the tick counter does. You’re already using the tick counter in your model, with the reset-ticks
and tick
commands, which also trigger plotting.
You can also use the tick counter for other things, such as to set a limit on the total length of a run.
Set the limit of a model run
Change the go procedure:
to go
if ticks >= 300 [ stop ]
move-turtles
eat-grass
check-death
reproduce
regrow-grass
tick
end
Now setup and run the model.
Green sticky notes if your model runs and then stops on tick 300.
Sliders
In case you don’t want to start with the same parameter value each time, sliders are an easy and intuitive way to modify parameters.
Let’s vary the number of turtles we start with.
- Create a slider named “number-of-turtles”: click the Add icon on the toolbar, select Slider next to it, and click on an open spot in the interface.
- Then inside of setup-turtles, instead of create-turtles 100 you can type:
to setup-turtles
create-turtles number-of-turtles
end
Go back to the Interface, move the slider to change the number of agents, and click “setup” and “go”.
Red sticky notes if this did not work for you.
More Sliders
Adjust the energy the turtles gain and lose as they eat grass and reproduce.
Make a slider called “energy-from-grass”.
Then, inside of eat-grass
, make this change:
to eat-grass
ask turtles [
if pcolor = green [
set pcolor black
set energy energy + energy-from-grass
]
ifelse show-energy?
[ set label energy ]
[ set label "" ]
]
end
Make another slider called “birth-energy”.
Inside of reproduce
, make this change:
to reproduce
ask turtles [
if energy > birth-energy [
set energy energy - birth-energy
hatch 1 [ set energy birth-energy ]
]
]
end
Challenge
Are there other parameters that could be varied? Write one or more sliders for these parameters.
(Hint: grass regrowth rate, movement of turtles ….)
Final Note
Don’t forget to comment your code! It has been said that best practice is at least 50% of your key strokes should be comments. Comments let you mix an explanation the code right in with the code itself. You might use comments to help others understand your model, or you might use them as notes to yourself.
Comments begin with “;;” and continue to the end of the line. In the Code tab, comments are gray, so your eyes can pick them out easily.
Acknowledgements & Support
Portions of the instructional materials are adopted from Tutorial #3 in the NetLogo User Manual.
If you need to catch-up before a section of code will work, just squish it's 🍅 to copy code above it into your clipboard. Then paste into your interpreter's console, run, and you'll be ready to start in on that section. Code copied by both 🍅 and 📋 will also appear below, where you can edit first, and then copy, paste, and run again.
# Nothing here yet!