Step 8. Add obsidian
1. Help Westerosi defend the realm
If you run the model at the moment, the Night King will always win, simply because the whitewalkers kill everything they touch and they themselves never die.
​
It's time to introduce a new weapon to help balance the scale a bit: obsidian!
​
Obsidian, or dragonglass, is the only weapon known to men that can kill whitewalkers (apart from dragons, but they're not here yet). Here, you will have people mining obsidian from Dragonstone (only known source to date as Sam lost most of the points he found at the Fist of the First Men). There will be different ways in which the setup of the obsidian will take place: through location, network, or territory.
​
1. Location: Only Dragonstone will have a cache of obsidian. Anybody that walks by Dragonstone (i.e., the closest patch on the shore next to the Dragonstone island) will obtain obsidian.
​
2. Network: Dragonstone and the cities that can be reached from it via the
networks will get caches of obsidian. This takes into consideration the direction of the links. If links are directed, only the linked cities that can be reached from Dragonstone (or intermediary cities) will get obsidian caches. If links are undirected, all linked cities will get some.
​
3. Territory: All cities that are held by the house holding Dragonstone and the people who identify with that house will automatically get obsidian. This may change over time if conflict? is ON and Dragonstone gets taken over by a new house.
​
People will gain obsidian when they travel to a location that has a cache or when they encounter someone who has enough pieces to share.
​
To set all this up, add a human variable called obsidian, a city variable called obsidian-cache, and an Interface chooser that shows all setup possibilities.
humans-own [ obsidian ] ; determines how much obsidian the human has to kill whitewalkers
cities-own [
city-name ; the name of the city or castle
city-size ; size of the city (taken from the shapefile)
centrality ; will take the centrality measure of the city when we create networks with roads
obsidian-cache? ; if the city has obsidian
]
humans-own [ obsidian ]
cities-own [
city-name
city-size
centrality
obsidian-cache?
]
2. Update the network
When we created the network in step 4, we used the road to show us which castles should be linked with which. Dragonstone being on an island, it was not included. However, to get obsidian to the main land, we need to add it to the network.
​
Change the setup-directed-networks and setup-undirected-networks procedures to create a link between Dragonstone and King's Landing. In the directed networks, the link should be from Dragonstone to King's Landing (arbitrary choice based on the fact that goods usually travel to the bigger city).
to setup-undirected-network ; observer procedure
; Hardcoding those temp variables so that they can be called below (shorter code below)
let castle-black one-of cities with [ city-name = "Castle Black" ]
let winterfell one-of cities with [ city-name = "Winterfell" ]
let moat-cailin one-of cities with [ city-name = "Moat Cailin" ]
let crossroad-inn one-of cities with [ city-name = "Crossroads Inn" ]
let lannisport one-of cities with [ city-name = "Lannisport" ]
let eyrie one-of cities with [ city-name = "The Eyrie" ]
let kings-landing one-of cities with [ city-name = "King's Landing" ]
let maidenpool one-of cities with [ city-name = "Maidenpool" ]
let highgarden one-of cities with [ city-name = "Highgarden" ]
let storms-end one-of cities with [ city-name = "Storm's End" ]
let oldtown one-of cities with [ city-name = "Oldtown" ]
let dragonstone one-of cities with [ city-name = "Dragonstone" ]
; These roads are an oversimplification of the roads in Westeros and focus on cities connected by the big roads only
ask castle-black [ create-link-with winterfell ] ; Road between Castle Black and Winterfell
ask winterfell [ create-link-with moat-cailin ] ; Road between Winterfell and Moat Cailin
ask moat-cailin [ create-link-with crossroad-inn ] ; Road between Moat Cailin to the Inn at the crossroads
ask lannisport [ create-link-with highgarden ] ; Road between Lannisport and Highgarden
ask highgarden [ create-link-with oldtown ] ; Road between Highgarden and Old Town
ask crossroad-inn [
create-link-with lannisport ; Road between the inn and Lannisport
create-link-with eyrie ; Road between the inn and the Eyrie
create-link-with kings-landing ; Road between the inn and King's Landing
]
ask kings-landing [
create-link-with maidenpool ; Road between King's Landing and Maidenpool
create-link-with lannisport ; Road between King's Landing and Lannisport
create-link-with highgarden ; Road between King's Landing and Highgarden
create-link-with storms-end ; Road between King's Landing and Storm's End
create-link-with dragonstone ; Road between King's Landing and Dragonstone (maritime "road")
]
end
to setup-undirected-network
let castle-black one-of cities with [ city-name = "Castle Black" ]
let winterfell one-of cities with [ city-name = "Winterfell" ]
let moat-cailin one-of cities with [ city-name = "Moat Cailin" ]
let crossroad-inn one-of cities with [ city-name = "Crossroads Inn" ]
let lannisport one-of cities with [ city-name = "Lannisport" ]
let eyrie one-of cities with [ city-name = "The Eyrie" ]
let kings-landing one-of cities with [ city-name = "King's Landing" ]
let maidenpool one-of cities with [ city-name = "Maidenpool" ]
let highgarden one-of cities with [ city-name = "Highgarden" ]
let storms-end one-of cities with [ city-name = "Storm's End" ]
let oldtown one-of cities with [ city-name = "Oldtown" ]
let dragonstone one-of cities with [ city-name = "Dragonstone" ]
ask castle-black [ create-link-with winterfell ]
ask winterfell [ create-link-with moat-cailin ]
ask moat-cailin [ create-link-with crossroad-inn ]
ask lannisport [ create-link-with highgarden ]
ask highgarden [ create-link-with oldtown ]
ask crossroad-inn [
create-link-with lannisport
create-link-with eyrie
create-link-with kings-landing
]
ask kings-landing [
create-link-with maidenpool
create-link-with lannisport
create-link-with highgarden
create-link-with storms-end
create-link-with dragonstone
]
end
to setup-directed-network ; observer procedure
; Hardcoding those temp variables so that they can be called below (shorter code below)
let castle-black one-of cities with [ city-name = "Castle Black" ]
let winterfell one-of cities with [ city-name = "Winterfell" ]
let moat-cailin one-of cities with [ city-name = "Moat Cailin" ]
let crossroad-inn one-of cities with [ city-name = "Crossroads Inn" ]
let lannisport one-of cities with [ city-name = "Lannisport" ]
let eyrie one-of cities with [ city-name = "The Eyrie" ]
let kings-landing one-of cities with [ city-name = "King's Landing" ]
let maidenpool one-of cities with [ city-name = "Maidenpool" ]
let highgarden one-of cities with [ city-name = "Highgarden" ]
let storms-end one-of cities with [ city-name = "Storm's End" ]
let oldtown one-of cities with [ city-name = "Oldtown" ]
let dragonstone one-of cities with [ city-name = "Dragonstone" ]
; These roads are an oversimplification of the roads in Westeros and focus on cities connected by the big roads only.
; For directed networks, the direction of the links is arbitrary and does not follow any ASOIAF data
ask castle-black [ create-link-from winterfell ] ; Road to Castle Black from Winterfell (Brothers of the watch can't go back home)
ask winterfell [
create-link-from moat-cailin
create-link-to moat-cailin ; Bidirectional road between Winterfell and Moat Cailin
]
ask moat-cailin [ create-link-to crossroad-inn ] ; Road from Moat Cailin to the Inn at the crossroads
ask crossroad-inn [
create-link-to lannisport ; Road from the inn to Lannisport
create-link-from eyrie ; Road to the inn from the Eyrie
create-link-from kings-landing ; Road to the inn from King's Landing
]
ask kings-landing [
create-link-from maidenpool ; Road to King's Landing from Maidenpool
create-link-from lannisport ; Road to King's Landing from Lannisport
create-link-from highgarden ; Road to King's Landing from Highgarden
create-link-from storms-end ; Road to King's Landing from Storm's End (all roads lead to King's Landing)
create-link-from dragonstone ; Road from Dragonstone to King's Landing
]
ask lannisport [ create-link-to highgarden ] ; Road from Lannisport to Highgarden
ask highgarden [ create-link-from oldtown ] ; Road to Highgarden from Oldtown
end
to setup-directed-network
let castle-black one-of cities with [ city-name = "Castle Black" ]
let winterfell one-of cities with [ city-name = "Winterfell" ]
let moat-cailin one-of cities with [ city-name = "Moat Cailin" ]
let crossroad-inn one-of cities with [ city-name = "Crossroads Inn" ]
let lannisport one-of cities with [ city-name = "Lannisport" ]
let eyrie one-of cities with [ city-name = "The Eyrie" ]
let kings-landing one-of cities with [ city-name = "King's Landing" ]
let maidenpool one-of cities with [ city-name = "Maidenpool" ]
let highgarden one-of cities with [ city-name = "Highgarden" ]
let storms-end one-of cities with [ city-name = "Storm's End" ]
let oldtown one-of cities with [ city-name = "Oldtown" ]
let dragonstone one-of cities with [ city-name = "Dragonstone" ]
ask castle-black [ create-link-from winterfell ] e)
ask winterfell [
create-link-from moat-cailin
create-link-to moat-cailin
]
ask moat-cailin [ create-link-to crossroad-inn ]
ask crossroad-inn [
create-link-to lannisport
create-link-from eyrie
create-link-from kings-landing
]
ask kings-landing [
create-link-from maidenpool
create-link-from lannisport
create-link-from highgarden
create-link-from storms-end
create-link-from dragonstone
]
ask lannisport [ create-link-to highgarden ]
ask highgarden [ create-link-from oldtown ]
end
3. Set up the initial sources
Import the "person with obsidian" turtle shape from this model.
​
Create a new setup procedure that will add caches of obsidian to Dragonstone and to any other cities and people involved, depending on the obsidian-distribution method chosen in the Interface. Integrate it to the setup procedure.
​
Integrate this new procedure to the main setup procedure, but make sure that you call it after creating the networks, or else the network distribution will not work.
​
Then, add a few lines of code to change the go procedure to update who has control over Dragonstone if obsidian-distribution is set to "territory" as a new house might take take it over by winning the prisoner's dilemma game, and thus inherit its obsidian.
to setup-obsidian ; observer procedure
ask cities [
set obsidian-cache? false ; by default, cities do not have obsidian
]
let dragonstone one-of cities with [ city-name = "Dragonstone" ]
ask dragonstone [
set obsidian-cache? true ; but Dragonstone has a cache
]
if obsidian-distribution = "network" [ ; if the distribution is based on network
ask cities with [ any? my-links ][ ; focuses only on connected cities
ask dragonstone [
if nw:distance-to myself != false [ ; identifies the cities that can be reached by Dragonstone
ask myself [ ; those connected cities get caches of obsidian
set obsidian-cache? true
]
]
]
]
]
​
if obsidian-distribution = "territory" [ ; if the distribution is based on territory
ask cities with [ house-color = [ house-color ] of Dragonstone ][ ; all cities from the same house...
set obsidian-cache? true ; ... get a cache
]
]
end
to setup-obsidian
ask cities [
set obsidian-cache? false
]
let dragonstone one-of cities with [ city-name = "Dragonstone" ]
ask dragonstone [
set obsidian-cache? true
]
if obsidian-distribution = "network" [
ask cities with [ any? my-links ][
ask dragonstone [
if nw:distance-to myself != false [
ask myself [
set obsidian-cache? true
]
]
]
]
]
​
if obsidian-distribution = "territory" [
ask cities with [ house-color = [ house-color ] of Dragonstone ][
set obsidian-cache? true
]
]
end
to setup
[ ... ]
ifelse link-type = "undirected" [ ; check which link type is chosen in the Interface
setup-undirected-network ; create the undirected network
][
setup-directed-network ; create the directed network
]
setup-obsidian ; call the setup-obsidian procedure to distribute obsidian
to setup
[ ... ]
ifelse link-type = "undirected" [
setup-undirected-network
][
setup-directed-network
]
setup-obsidian
if conflict? [ ; if conflict? switch is ON (same as "if conflict? = true"), houses will fight using the prisoner's dilemma
update-players ; update the list of possible players
if length players > 1 [ ; the houses fight only if there are more than one house left
houses-fight-for-territory
]
]
; Updates the distribution of obsidian if Dragonstone changes owner
if obsidian-distribution = "territory" [
let dragonstone one-of cities with [ city-name = "Dragonstone" ]
let dragonstone-color [ color ] of dragonstone
ask cities with [ color = dragonstone-color ][
set obsidian-cache? true ; mimics if a different house takes over and distributes obsidian to all its people
]
]
if conflict? [
update-players
if length players > 1 [
houses-fight-for-territory
]
]
if obsidian-distribution = "territory" [
let dragonstone one-of cities with [ city-name = "Dragonstone" ]
let dragonstone-color [ color ] of dragonstone
ask cities with [ color = dragonstone-color ][
set obsidian-cache? true
]
]
4. Allow people to pick up obsidian
To insure that as most people as possible can get obsidian, you will allow people to pick up 10 obsidian tools (arbitrary number, why not?) if they walk by a city with obsidian. Given that Dragonstone is on an island, you will need to have a special statement where one person picks up obsidian when within 10 patches of that particular city.
​
Create a new procedure for this and integrate it to the go procedure.
​
In this procedure, you will see that every human who picks up obsidian prints a statement in the Command Center. Here, we use the primitive show, which prints the ID of the human doing the action first, followed by the text we added. This will slow down the model a bit, but it is useful if you want to inspect a human with obsidian (to see its cool design... or make sure they actually have 10 tools in their kit). If you do not want those print statements, simply comment this line out. Print statements are very useful for debugging, so do not be afraid to use them.
to pick-up-obsidian ; human procedure
let picking-obsidian false ; temp variable to keep track of who is picking up obsidian
; For Dragonstone
let dragonstone one-of cities with [ city-name = "Dragonstone" ] in-radius 10
if dragonstone != nobody [ ; if Dragonstone is within 10 patches
set picking-obsidian true ; the human remembers that it is picking up obsidian
]
; For other cities with caches
let city-with-obsidian cities-here with [ obsidian-cache? ]
if any? city-with-obsidian [ ; if the city visited has a cache
set picking-obsidian true
]
if picking-obsidian [ ; if the human is picking up
show "picking up" ; the human prints its ID and the text here
set shape "person with obsidian" ; changes its shape to show its weapon
set obsidian 10 ; adds 10 tool to its toolkit
]
end
to pick-up-obsidian
let picking-obsidian false
let dragonstone one-of cities with [ city-name = "Dragonstone" ] in-radius 10
if dragonstone != nobody [
set picking-obsidian true
]
let city-with-obsidian cities-here with [ obsidian-cache? ]
if any? city-with-obsidian [
set picking-obsidian true
]
if picking-obsidian [
show "picking up"
set shape "person with obsidian"
set obsidian 10
]
end
to go
[ ... ]
​
ask humans [ ; human actions, almost all the same as sheep and wolves
ifelse territorial-movement [
move-humans ; calls the "move-humans" procedure if there is territorial movement
][
move ; calls the "move" procedure
]
pick-up-obsidian ; every move, humans will try to pick up obsidian if they can
set energy energy - 1 ; humans also lose energy as they move
humans-eat ; Humans eat some of the sheep that are on their patch or the grass if available
domesticate-wolves ; Humans domesticate some of the wolves they encounter
humans-feed-animals ; humans feed their domesticated wolves
death ; humans die when they run out of energy
reproduce humans-reproduce ; wolves reproduce at a random rate governed by a slider
]
to go
[ ... ]
​
ask humans [
ifelse territorial-movement [
move-humans
][
move
]
pick-up-obsidian
set energy energy - 1
humans-eat
domesticate-wolves
humans-feed-animals
death
reproduce humans-reproduce
]
5. Exchange obsidian
Let's now allow people who have more than 1 obsidian tool to give one of their tools to people they encounter, if those people don't already have a tool.
​
If we wanted to be fancy, we could allow trade only between people of the same house, but we will let you think about how you could implement that part for now.
​
Create a new procedure that tells people to check if the person they meet already have tools, and if they don't, give them one, until they only have one left.
​
Then call that procedure in the go procedure.
to exchange-obsidian ; human procedure
if obsidian > 1 [ ; if the human doing the action has more than 1 tool in its kit
let friends humans-here with [ obsidian = 0 ] ; checks if there are people without obsidian on the same patch
if any? friends [
set obsidian obsidian - 1 ; take one tool from my inventory
ask friends [
set obsidian 1 ; give it to the people who do not have any
set shape "person with obsidian" ; who can change their appearance
]
]
]
end
to exchange-obsidian
if obsidian > 1 [
let friends humans-here with [ obsidian = 0 ]
if any? friends [
set obsidian obsidian - 1
ask friends [
set obsidian 1
set shape "person with obsidian"
]
]
]
end
to go
[ ... ]
​
ask humans [ ; human actions, almost all the same as sheep and wolves
ifelse territorial-movement [
move-humans ; calls the "move-humans" procedure if there is territorial movement
][
move ; calls the "move" procedure
]
pick-up-obsidian ; every move, humans will try to pick up obsidian if they can
exchange-obsidian ; every move, humans can exchange obsidian if they have some to give
set energy energy - 1 ; humans also lose energy as they move
humans-eat ; Humans eat some of the sheep that are on their patch or the grass if available
domesticate-wolves ; Humans domesticate some of the wolves they encounter
humans-feed-animals ; humans feed their domesticated wolves
death ; humans die when they run out of energy
reproduce humans-reproduce ; humans reproduce at a random rate governed by a slider
]
to go
[ ... ]
​
ask humans [
ifelse territorial-movement [
move-humans
][
move
]
pick-up-obsidian
exchange-obsidian
set energy energy - 1
humans-eat
domesticate-wolves
humans-feed-animals
death
reproduce humans-reproduce
]
6. Fight the whitewalkers
Now that you have a good trading program, it is time to use the obsidian to kill whitewalkers.
​
In the Whitewalker.nls file, add some code to the winter-advance procedure where people with obsidian can try to kill the whitewalkers they encounter. You will need to make sure that the living-things turtle-set now only includes sheep and wolves. Let's assume that killing them destroys the obsidian tool, however.
to winter-advance ; observer procedure
ask whitewalkers [
others-move ; calls the others-move procedure
let living-things ( turtle-set wolves sheep humans ) ; agentset of all living beings
if any? living-things in-radius 1 [ ; if there are any living beings on the same patch
ask living-things in-radius 1 [ die ] ; they are killed and
hatch-whitewalkers 1 ; a new whitewalker takes its place
]
; If the whitewalker falls upon someone with obsidian, it's game over
let my-opponents humans-here with [ obsidian > 0 ]
if any? my-opponents [ ; if there is someone with obsidian on the same patch
ask one-of my-opponents [
set obsidian ( obsidian - 1 ) ; the tool breaks
]
show "..." ; whitewalkers don't speak
die
]
; If the whitewalker runs into a human without obsidian tools, the human dies
if any? humans-here with [ obsidian = 0 ][
ask humans-here [ die ]
hatch-whitewalkers 1
]
]
​
end
to winter-advance
ask whitewalkers [
others-move ; calls the others-move procedure
let living-things ( turtle-set wolves sheep humans )
if any? living-things in-radius 1 [
ask living-things in-radius 1 [ die ]
hatch-whitewalkers 1
]
let my-opponents humans-here with [ obsidian > 0 ]
if any? my-opponents [
ask one-of my-opponents [
set obsidian ( obsidian - 1 )
]
show "..."
die
]
if any? humans-here with [ obsidian = 0 ][
ask humans-here [ die ]
hatch-whitewalkers 1
]
]
​
end
7. You did it again!
Congratulations on adding obsidian to the model. Now, you can run the model under different settings and see which one allows people to kill whitewalkers the fastest. For example, does conflict help or not? What type of obsidian distribution works best?
​
If you want to see the finished model for this step, download it here​​​.
​
The next step is also the final one. There, you will add a new breed of dragons to the model, to provide more help to deal with the advance of whitewalkers.
​
See you there!