diff --git a/src/crop/almass.jl b/src/crop/almass.jl
index 4c7dff6d4ce2b19b292679f49c3b6e4812e24ef2..dbc316b564b1d5725f45ceca38b1909ed6cb0966 100644
--- a/src/crop/almass.jl
+++ b/src/crop/almass.jl
@@ -14,9 +14,9 @@ using Persefone:
     m,
     SimulationModel,
     fertiliser,
-    initfields_fill_with!,
     maxtemp,
     mintemp
+
 import Persefone:
     stepagent!,
     croptype,
@@ -24,6 +24,7 @@ import Persefone:
     cropheight,
     cropcover,
     cropyield
+
 using Dates: Date, month, monthday
 using CSV: CSV
 
@@ -166,22 +167,6 @@ function readcropparameters(generalcropfile::String, growthfile::String)
     croptypes
 end
 
-"""
-    initfields!(model)
-
-Initialise the model with its farm plots.
-"""
-function initfields!(model::SimulationModel)
-    initfields_fill_with!(model) do model, x, y
-        month(model.date) < 3 ? phase = ALMaSS.janfirst : phase = ALMaSS.marchfirst
-        FarmPlot(length(model.farmplots) + 1, [(x,y)],
-                 CropState(model.crops["natural grass"],
-                           phase,
-                           0.0, 0.0m, 0.0, 0.0, Vector{EventType}())
-                 )
-    end
-end
-
 """
     stepagent!(farmplot, model)
 
diff --git a/src/crop/cropmodels.jl b/src/crop/cropmodels.jl
index 6b47594555aa9cedcea5e964b2d61600e53ad977..0a16bc5e6fa292e51b7717f8ac6ef7e59b52906e 100644
--- a/src/crop/cropmodels.jl
+++ b/src/crop/cropmodels.jl
@@ -1,6 +1,6 @@
 ### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
 ###
-### Crop model helper functions.
+### Functions for switchable crop models.
 ###
 
 function initcropmodel(cropmodel::AbstractString, cropfile::AbstractString, growthfile::AbstractString)
@@ -19,12 +19,58 @@ function initcropmodel(cropmodel::AbstractString, cropfile::AbstractString, grow
     return crops, Tcroptype, Tcropstate
 end
 
+"""
+    initfields!(model)
+
+Initialise the model with its farm plots.
+"""
 function initfields!(model::SimulationModel, cropmodel::AbstractString)
+    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.farmplots[objectid].pixels, (x,y))
+            else
+                cropstate = make_cropstate(model, cropmodel)
+                fp = FarmPlot(
+                    length(model.farmplots) + 1,
+                    [(x, y)],
+                    cropstate
+                )
+                push!(model.farmplots, fp)
+                model.landscape[x,y].fieldid = fp.id
+                convertid[rawid] = fp.id
+                n += 1
+            end
+        end
+    end
+    @info "Initialised $n farm plots."
+end
+
+function make_cropstate(model::SimulationModel, cropmodel::AbstractString)
     if cropmodel == "almass"
-        ALMaSS.initfields!(model)
+        phase = (month(model.date) < 3 ? ALMaSS.janfirst : ALMaSS.marchfirst)
+        cs = ALMaSS.CropState(
+                model.crops["natural grass"],
+                phase,
+                0.0, 0.0m, 0.0, 0.0, Vector{EventType}()
+        )
     elseif cropmodel == "simple"
-        SimpleCrop.initfields!(model)
+        cs = SimpleCrop.CropState(
+            model.crops["natural grass"],
+            0.0m
+        )
     else
-        error("initfields! for crop model '$cropmodel'")
+        error("Unhandled crop model '$cropmodel' in make_cropstate")
     end
+    return cs
 end
diff --git a/src/crop/farmplot.jl b/src/crop/farmplot.jl
index 0758219930808ccf43be5b89a669f8040c16d445..49a100d01ff393fb1e142c8b9c2d61284d4e5d11 100644
--- a/src/crop/farmplot.jl
+++ b/src/crop/farmplot.jl
@@ -15,40 +15,6 @@ cropheight(f::FarmPlot{T}) where {T} = cropheight(f.crop_state)
 cropcover(f::FarmPlot{T}) where {T} = cropcover(f.crop_state)
 cropyield(f::FarmPlot{T}) where {T} = cropyield(f.crop_state)
 
-"""
-    initfields_fill_with!(make_farmplot_fn, model)
-
-Initialise the model with its farm plots, using the
-`make_farmplot_fn(model, x, y)` function to create new farmplots.
-"""
-function initfields_fill_with!(make_farmplot_fn::Function, model::SimulationModel)
-    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.farmplots[objectid].pixels, (x,y))
-            else
-                fp = make_farmplot_fn(model, x, y)
-                push!(model.farmplots, fp)
-                model.landscape[x,y].fieldid = fp.id
-                convertid[rawid] = fp.id
-                n += 1
-            end
-        end
-    end
-    @info "Initialised $n farm plots."
-end
-
-
 ## UTILITY FUNCTIONS
 
 """
diff --git a/src/crop/simplecrop.jl b/src/crop/simplecrop.jl
index c653390c49d5ee5c80b2c6f5ca58a0007df2d32f..dead41ffbfd5e13d109ee368668e6c94ebe64505 100644
--- a/src/crop/simplecrop.jl
+++ b/src/crop/simplecrop.jl
@@ -4,8 +4,8 @@ using Persefone:
     FarmPlot,
     Length,
     m,
-    SimulationModel,
-    initfields_fill_with!
+    SimulationModel
+
 import Persefone:
     stepagent!,
     croptype,
@@ -41,15 +41,4 @@ function stepagent!(farmplot::FarmPlot{CropState}, model::SimulationModel)
     # TODO: do something simple
 end
 
-"""
-    initfields!(model)
-
-Initialise the model with its farm plots.
-"""
-function initfields!(model::SimulationModel)
-    initfields_fill_with!(model) do model, x, y
-        FarmPlot(length(model.farmplots) + 1, [(x,y)], CropState(model.crops["natural grass"], 0.0m))
-    end
-end
-
 end # module SimpleCrop
diff --git a/test/landscape_tests.jl b/test/landscape_tests.jl
index fc6ae84b6b0f5ca8adaa411b0cbfd9031dbd8f19..d2d3f02c05acfc029ac621b6a1d765c312fe46b8 100644
--- a/test/landscape_tests.jl
+++ b/test/landscape_tests.jl
@@ -6,7 +6,8 @@
 @testset "Landscape initialisation" begin
     model = inittestmodel(false)
     # these tests are specific to the Jena maps
-    @test_logs (:info, "Initialised 2092 farm plots.") match_mode=:any Ps.ALMaSS.initfields!(model)
+    cropmodel = "almass"
+    @test_logs (:info, "Initialised 2092 farm plots.") match_mode=:any Ps.initfields!(model, cropmodel)
     @test size(model.landscape) == (1754, 1602)
     @test Ps.landcover((100,100), model) == Ps.forest
     @test Ps.landcover((300,1), model) == Ps.soil