diff --git a/src/core/landscape.jl b/src/core/landscape.jl
index 7672839848aa54d9182d01534c71f4dbda18bee4..aff4e570b5550f40cb1c07de6d48fb3564b26940 100644
--- a/src/core/landscape.jl
+++ b/src/core/landscape.jl
@@ -15,9 +15,9 @@ A pixel is a simple data structure to combine land use and ownership information
 in a single object. The model landscape consists of a matrix of pixels.
 (Note: further landscape information may be added here in future.)
 """
-struct Pixel
+mutable struct Pixel
     landcover::LandCover
-    fieldid::Union{Missing, UInt32}
+    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
 end
@@ -41,7 +41,9 @@ function initlandscape()
             lc = landcover[x,y][1]
             (ismissing(lc)) && (lc = 0)
             lcv = LandCover(Int(lc/10))
-            landscape[x,y] = Pixel(lcv, farmfields[x,y][1], Vector{Symbol}())
+            ff = farmfields[x,y][1]
+            !(ismissing(ff)) && (ff = Int64(ff))
+            landscape[x,y] = Pixel(lcv, ff, Vector{Symbol}())
         end
     end
     return landscape
diff --git a/src/core/simulation.jl b/src/core/simulation.jl
index 7ef064e39bbd24f3ad0c4b5b47d036a51b033a53..3ee8fe7ca8bf2352082215f19d50717a6c6a264f 100644
--- a/src/core/simulation.jl
+++ b/src/core/simulation.jl
@@ -19,8 +19,9 @@ function initialise(config::String=PARAMFILE)
     space = GridSpace(size(landscape), periodic=false)
     properties = Dict{Symbol,Any}(:date=>param("core.startdate"),
                                   :landscape=>landscape)
-    model = AgentBasedModel(Union{Farmer,Animal,CropPlot}, space, properties=properties,
-                            rng=Random.Xoshiro(param("core.seed")))
+    @debug "Setting up model now"
+    model = AgentBasedModel(Union{Farmer,Animal,FarmPlot}, space, properties=properties,
+                            rng=Random.Xoshiro(param("core.seed")), warn=false)
     # initialise submodels
     initfarms!(model)
     initfields!(model)
@@ -36,7 +37,7 @@ Execute one update of the model.
 """
 function stepsimulation!(model::AgentBasedModel)
     @info "Simulating day $(model.date)."
-    for a in Schedulers.ByType((Farmer,Animal,CropPlot), true)(model)
+    for a in Schedulers.ByType((Farmer,Animal,FarmPlot), true)(model)
         #The animal may have been killed, so we need a try/catch
         try stepagent!(getindex(model, a), model) catch keyerror end
     end
diff --git a/src/crop/crops.jl b/src/crop/crops.jl
index 0db809b6159f46e7f0a40145a8be362344fef84e..ccae89b5abe3497475fbf1dbb4d7f1fa58ab496b 100644
--- a/src/crop/crops.jl
+++ b/src/crop/crops.jl
@@ -6,24 +6,83 @@
 #XXX not sure whether it makes sense to have this as an agent type,
 # or perhaps better a grid property?
 
-@agent CropPlot GridAgent{2} begin
+"""
+This is a docstring
+"""
+@agent FarmPlot NoSpaceAgent begin
+    pixels::Vector{Tuple{Int64, Int64}}
+    croptype::String
+    height::Float64
+    biomass::Float64
     #TODO
 end
 
 """
-    stepagent!(cropplot, model)
+    stepagent!(farmplot, model)
 
-Update a crop plot by one day.
+Update a farm plot by one day.
 """
-function stepagent!(cropplot::CropPlot, model::AgentBasedModel)
+function stepagent!(farmplot::FarmPlot, model::AgentBasedModel)
     #TODO
 end
 
 """
     initfields!(model)
 
-Initialise the model with its crop plots.
+Initialise the model with its farm plots.
 """
 function initfields!(model::AgentBasedModel)
-    #TODO
+    n = 0
+    convertid = Dict{Int64,Int64}()
+    width, height = size(model.landscape)
+    for x in 1:width
+        for y in 1:height
+            # for each pixel, we need to extract the field ID given by the map input file,
+            # and convert it into the internal object ID used by Agents.jl, creating a new
+            # agent object if necessary
+            rawid = model.landscape[x,y].fieldid
+            (ismissing(rawid)) && continue
+            if rawid in keys(convertid)
+                objectid = convertid[rawid]
+                model.landscape[x,y].fieldid = objectid
+                push!(model[objectid].pixels, (x,y))
+            else
+                fp = add_agent!(FarmPlot, model, [(x,y)], "fallow", 0.0, 0.0)
+                model.landscape[x,y].fieldid = fp.id
+                convertid[rawid] = fp.id
+                n += 1
+            end
+        end
+    end
+    @debug "Initialised $n farm plots."
+end
+
+#XXX only needed during development, can be deleted again
+function countfields(model::AgentBasedModel)
+    ids::Vector{Int64} = []
+    width, height = size(model.landscape)
+    for x in 1:width
+        for y in 1:height
+            i = model.landscape[x,y].fieldid
+            (ismissing(i)) && continue
+            push!(ids, i)
+        end
+    end
+    ids |> sort! |> unique! |> length
+end
+
+"""
+    averagefieldsize(model)
+
+Calculate the average field size in hectares for the model landscape.
+"""
+function averagefieldsize(model::AgentBasedModel)
+    conversionfactor = 100 #our pixels are currently 10x10m, so 100 pixels per hectare
+    sizes::Vector{Float64} = []
+    for a in allagents(model)
+        (typeof(a) != FarmPlot) && continue
+        push!(sizes, size(a.pixels)[1]/conversionfactor)
+    end
+    round(sum(sizes)/size(sizes)[1], digits=2)
+    #sizes
 end
diff --git a/src/nature/nature.jl b/src/nature/nature.jl
index abc2043ad0c0dcbc32cfad8f5e34632d55adcb88..39e388ecaabe5a8f33401c92c518c005eca10479 100644
--- a/src/nature/nature.jl
+++ b/src/nature/nature.jl
@@ -12,7 +12,6 @@
 This is the generic agent type for all animals. Species are differentiated
 by trait dictionaries passed by them during initialisation.
 """
-#XXX fix the @agent docstring issue (https://github.com/JuliaDynamics/Agents.jl/issues/715)
 @agent Animal GridAgent{2} begin
     #XXX is it (performance-)wise to use a dict for the traits?
     # Doesn't this rather obviate the point of having an agent struct?
@@ -111,7 +110,7 @@ To transition an individual to another phase, simply redefine its phase variable
 `@trait(phase) = "newphase"`.
 """
 macro phase(name, body)
-    #XXX Using an undeclared variable in the body doesn't throw an error?
+    #FIXME Somehow, errors in the phase body are not shown?
     :($(esc(name)) = function(animal::Animal, model::AgentBasedModel) $body end)
 end
 
@@ -173,6 +172,8 @@ macro reproduce(args...)
     :(reproduce!(animal, model, $(args...)))
 end
 
+#XXX add a macro @f to call a function with animal and model as first parameters?
+# e.g. @f(nearby_agents, distance)
 
 ### FUNCTIONS INTEGRATING THE NATURE MODEL WITH THE REST OF PERSEPHONE