diff --git a/src/core/landscape.jl b/src/core/landscape.jl
index aff4e570b5550f40cb1c07de6d48fb3564b26940..959aef5f0c4d4277a56652d10a24189b73d6773d 100644
--- a/src/core/landscape.jl
+++ b/src/core/landscape.jl
@@ -8,6 +8,8 @@
 ## Do not change the order of this enum, or initlandscape() will break!
 @enum LandCover nodata forest grass water builtup soil agriculture
 
+@enum LandscapeEvent test tillage fertiliser pesticide harvest
+
 """
     Pixel
 
@@ -18,8 +20,7 @@ in a single object. The model landscape consists of a matrix of pixels.
 mutable struct Pixel
     landcover::LandCover
     fieldid::Union{Missing,Int64}
-    events::Vector{Symbol} #TODO implement the rest of the events system
-    #FIXME actually this is stupid - I don't want a field ID, I want a field object
+    events::Vector{Tuple{LandscapeEvent,Int64}}
 end
 
 """
@@ -49,6 +50,27 @@ function initlandscape()
     return landscape
 end
 
+"""
+    updatelandscape!(model)
+
+Update the model landscape. (Currently only removes old events.)
+"""
+function updatelandscape!(model::AgentBasedModel)
+    #FIXME This is really slow?!
+    # Instead of cycling through every pixel every time, I should keep a list of active
+    # events, and cycle through those
+    width, height = size(model.landscape)
+    for x in 1:width
+        for y in 1:height
+            newevents::Vector{Tuple{LandscapeEvent,Int64}} = []
+            for e in model.landscape[x,y].events
+                # only keep events that still have a duration > 1 day
+                (e[2] > 1) && push!(newevents, (e[1], e[2]-1))
+            end
+            model.landscape[x,y].events = newevents
+        end
+    end
+end
 
 """
     landcover(model, position)
@@ -60,10 +82,21 @@ function landcover(model::AgentBasedModel, pos::Tuple{Int64,Int64})
 end
 
 """
-    fieldid(model, position)
+    farmplot(model, position)
 
-Return the UID of the field at this position (utility wrapper).
+Return the farm plot at this position (utility wrapper).
 """
-function fieldid(model::AgentBasedModel, pos::Tuple{Int64,Int64})
-    model.landscape[pos...].fieldid
+function farmplot(model::AgentBasedModel, pos::Tuple{Int64,Int64})
+    model[model.landscape[pos...].fieldid]
 end
+
+"""
+    createevent(model, pos, name, duration=1)
+
+Add a landscape event to the pixel at the specified site.
+"""
+function createevent(model::AgentBasedModel, pos::Tuple{Int64,Int64},
+                     name::LandscapeEvent, duration::Int64=1)
+    push!(model.landscape[pos...].events, (name, duration))
+end
+
diff --git a/src/core/simulation.jl b/src/core/simulation.jl
index 3ee8fe7ca8bf2352082215f19d50717a6c6a264f..525e76e2b0ce06a475d6186f62a9bb55375de12e 100644
--- a/src/core/simulation.jl
+++ b/src/core/simulation.jl
@@ -37,10 +37,11 @@ Execute one update of the model.
 """
 function stepsimulation!(model::AgentBasedModel)
     @info "Simulating day $(model.date)."
-    for a in Schedulers.ByType((Farmer,Animal,FarmPlot), true)(model)
+    for a in Schedulers.ByType((Farmer,FarmPlot,Animal), true)(model)
         #The animal may have been killed, so we need a try/catch
-        try stepagent!(getindex(model, a), model) catch keyerror end
+        try stepagent!(model[a], model) catch keyerror end
     end
+    #updatelandscape!(model)
     outputdata(model)
     model.date += Day(1)
 end
diff --git a/src/crop/crops.jl b/src/crop/crops.jl
index ccae89b5abe3497475fbf1dbb4d7f1fa58ab496b..709a203d4d9aec05329742a498d3acea3184a8fe 100644
--- a/src/crop/crops.jl
+++ b/src/crop/crops.jl
@@ -86,3 +86,16 @@ function averagefieldsize(model::AgentBasedModel)
     round(sum(sizes)/size(sizes)[1], digits=2)
     #sizes
 end
+
+
+"""
+    applyevent(model, farmplotid, name, duration=1)
+
+Apply an event to all pixels in a farm plot.
+"""
+function applyevent(model::AgentBasedModel, farmplotid::Int64,
+                    name::LandscapeEvent, duration::Int64=1)
+    for p in model[farmplotid].pixels
+        createevent(model, p, name, duration)
+    end
+end
diff --git a/src/nature/nature.jl b/src/nature/nature.jl
index 39e388ecaabe5a8f33401c92c518c005eca10479..9fe3f273b312c6622651b811045a9c9cff547825 100644
--- a/src/nature/nature.jl
+++ b/src/nature/nature.jl
@@ -122,7 +122,8 @@ This can only be used nested within `@phase`.
 """
 macro respond(eventname, body)
     quote
-        if $(esc(eventname)) in @here(events)
+        #TODO test this
+        if any(e -> e[1] == $(esc(eventname)), @here(events))
             $body
         end
     end