diff --git a/src/core/output.jl b/src/core/output.jl
index 555c4bed63baff1a37c0ccdd9abba4932878c838..d59eb3d91f885d545d21132b27955698bb0cfe1b 100644
--- a/src/core/output.jl
+++ b/src/core/output.jl
@@ -194,7 +194,7 @@ function newdataoutput!(model::SimulationModel, name::String,
             end
         end
     end
-    ndo = DataOutput(frequency, [[]], df, outputfunction, plotfunction)
+    ndo = DataOutput(frequency, [], df, outputfunction, plotfunction)
     model.dataoutputs[name] = ndo
 end
 
@@ -221,7 +221,7 @@ function outputdata(model::SimulationModel, force=false)
             (output.frequency == "yearly" && isnextyear(model.date)) ||
             (output.frequency == "end" && model.date == @param(core.enddate))
             !isnothing(output.outputfunction) && (output.databuffer = output.outputfunction(model))
-            isempty(output.databuffer) && continue
+            (isempty(output.databuffer) || output.databuffer == [[]]) && continue
             if @param(core.csvoutput)
                 open(joinpath(@param(core.outdir), o*".csv"), "a") do f
                     for row in output.databuffer
@@ -234,17 +234,17 @@ function outputdata(model::SimulationModel, force=false)
                     push!(output.datastore, row)
                 end
             end
-            output.databuffer = [[]]
+            output.databuffer = []
         end
     end
 end
 
 """
-    record(model, outputname, data)
+    record!(model, outputname, data)
 
 Append an observation vector to the given output.
 """
-function record(model::SimulationModel, outputname::String, data::Vector)
+function record!(model::SimulationModel, outputname::String, data::Vector)
     push!(model.dataoutputs[outputname].databuffer, data)
 end
     
diff --git a/src/nature/ecologicaldata.jl b/src/nature/ecologicaldata.jl
index c350b9926cbd14158b2f2e10e6c2acb98645c20f..8f0b7e8bc38d08228dc688609519cdb552e28055 100644
--- a/src/nature/ecologicaldata.jl
+++ b/src/nature/ecologicaldata.jl
@@ -14,6 +14,7 @@ function initecologicaldata(model::SimulationModel)
                    @param(nature.popoutfreq), savepopulationdata, populationtrends)
     newdataoutput!(model, "individuals", ["Date","ID","X","Y","Species","Sex","Age"],
                    @param(nature.indoutfreq), saveindividualdata, visualisemap)
+    newdataoutput!(model, "mortality", ["Date", "Species", "Cause"], @param(nature.popoutfreq))
     initskylarkdata(model)
 end
 
diff --git a/src/nature/individuals.jl b/src/nature/individuals.jl
index 934d219381825082a6ce56d8710e19d14c61d9d1..7cb9da522187bde26c3344556c325faa361e4e44 100644
--- a/src/nature/individuals.jl
+++ b/src/nature/individuals.jl
@@ -47,6 +47,7 @@ function kill!(animal::Animal, model::SimulationModel,
         # print the epitaph and remove the animal from the model
         postfix = isempty(cause) ? "." : " from $cause."
         @debug "$(animalid(animal)) has died$(postfix)"
+        @record("mortality", [model.date, speciesof(animal), cause])
         model.animals[animal.id] = nothing
         return true
     end
diff --git a/src/nature/macros.jl b/src/nature/macros.jl
index 14a81d3f2546b0c9f217f010b0a603e48374dc58..250d688940d815ef7b87284aecc59a8a300aba52 100644
--- a/src/nature/macros.jl
+++ b/src/nature/macros.jl
@@ -496,6 +496,7 @@ end
     @thisyear(annualdate)
 
 Construct a date object referring to the current model year from an AnnualDate.
+Only use in scopes where `model` is available.
 """
 macro thisyear(annualdate)
     :(thisyear($(esc(annualdate)), $(esc(:model))))
@@ -505,6 +506,7 @@ end
     @nextyear(annualdate)
 
 Construct a date object referring to the next year in the model from an AnnualDate.
+Only use in scopes where `model` is available.
 """
 macro nextyear(annualdate)
     :(nextyear($(esc(annualdate)), $(esc(:model))))
@@ -514,7 +516,26 @@ end
     @lastyear(annualdate)
 
 Construct a date object referring to the last year in the model from an AnnualDate.
+Only use in scopes where `model` is available.
 """
 macro lastyear(annualdate)
     :(lastyear($(esc(annualdate)), $(esc(:model))))
 end
+
+"""
+    @record(outputname, data)
+
+Record an observation / data point. Only use in scopes where `model` is available.
+"""
+macro record(args...)
+    :(record!($(esc(:model)), $(map(esc, args)...)))
+end
+
+"""
+    @destroynest(reason)
+
+Utility wrapper for `destroynest!()` in the Skylark model.
+"""
+macro destroynest(reason)
+    :(destroynest!($(esc(:self)), $(esc(:model)), $(esc(reason))))
+end
diff --git a/src/nature/species/skylark.jl b/src/nature/species/skylark.jl
index cced0226228e00d7f72de96d8d6c4fc4dff8fb91..547f1cd2b0f702932ea29dbdfadfd979007f3feb 100644
--- a/src/nature/species/skylark.jl
+++ b/src/nature/species/skylark.jl
@@ -229,8 +229,8 @@ Females that have found a partner build a nest and lay eggs in a suitable locati
         self.timer -= 1
     end
     # tillage and harvest destroys the nest
-    @respond(tillage, destroynest!(self, "tillage"))
-    @respond(harvesting, destroynest!(self, "harvesting"))
+    @respond(tillage, @destroynest("tillage"))
+    @respond(harvesting, @destroynest("harvesting"))
 end
 
 """
@@ -243,24 +243,27 @@ chicks are independent or in case of brood loss.
     self.timer += 1
     #TODO this should be habitat-dependent!
     if self.timer <= self.eggtime
-        @chance(self.eggpredationmortality) && destroynest!(self, "predation")
+        @chance(self.eggpredationmortality) && @destroynest("predation")
     elseif self.timer <= self.eggtime + self.nestlingtime
-        @chance(self.nestlingpredationmortality) && destroynest!(self, "predation")
+        @chance(self.nestlingpredationmortality) && @destroynest("predation")
     elseif self.timer <= self.eggtime + self.nestlingtime + self.fledglingtime
-        @chance(self.fledglingpredationmortality) && destroynest!(self, "predation")
+        @chance(self.fledglingpredationmortality) && @destroynest("predation")
     else
         # create new young, reset timer and clutch counter
         for o in 1:self.clutch #XXX is this the best way of doing first-year mortality?
-            @chance(self.firstyearmortality) ?
-                @debug("A skylark has died from first year mortality") : 
+            if @chance(self.firstyearmortality)
+                @debug("A skylark has died from first year mortality")
+                @record("mortality", [model.date, "Skylark", "firstyearmortality"])
+            else
                 @reproduce(1, self.mate)
+            end
         end
         self.clutch = 0
     end
     if self.clutch > 0
         # tillage and harvest destroys the nest
-        @respond(tillage, destroynest!(self, "tillage"))
-        @respond(harvesting, destroynest!(self, "harvesting"))        
+        @respond(tillage, @destroynest("tillage"))
+        @respond(harvesting, @destroynest("harvesting"))        
     else # restart breeding cycle if there is time
         self.timer = 0
         self.nest = ()
@@ -358,16 +361,20 @@ function allowsnesting(skylark::Skylark, model::SimulationModel, pos::Tuple{Int6
 end
 
 """
-    destroynest!(skylark, reason)
+    destroynest!(skylark, model, reason)
 
 Remove the skylark's nest and offspring due to disturbance or predation.
 """
-function destroynest!(self::Skylark, reason::String)
+function destroynest!(self::Skylark, model::SimulationModel, reason::String)
+    for c in self.clutch
+        @record("mortality", [model.date, "Skylark", reason])
+    end
     self.nest = ()
     self.clutch = 0
     @debug("$(animalid(self)) had her nest destroyed by $reason.")
 end
 
+
 ## INITIALISATION
 
 """