diff --git a/src/core/input.jl b/src/core/input.jl
index 46460cb92af1701ff1109771a439809722bb44a5..e233382ea20a48e69be50e639c5cb5f617733270 100644
--- a/src/core/input.jl
+++ b/src/core/input.jl
@@ -125,39 +125,6 @@ function flattenTOML(tomldict)
     flatdict
 end
 
-"""
-    @rand(args...)
-
-Return a random number or element from the sample, using the model RNG.
-This is a utility wrapper that can only be used a context where the
-`model` object is available.
-"""
-macro rand(args...)
-    :($(esc(:rand))($(esc(:model)).rng, $(map(esc, args)...)))
-end
-
-"""
-    @shuffle!(collection)
-
-Shuffle the given collection in place, using the model RNG.
-This is a utility wrapper that can only be used a context where the
-`model` object is available.
-"""
-macro shuffle!(collection)
-    :($(esc(:shuffle!))($(esc(:model)).rng, $(esc(collection))))
-end
-
-"""
-    @chance(odds)
-
-Return true if a random number is less than the odds (0.0 <= `odds` <= 1.0),
-using the model RNG. This is a utility wrapper that can only be used a context
-where the `model` object is available.
-"""
-macro chance(odds)
-    :($(esc(:rand))($(esc(:model)).rng) < $(esc(odds)))
-end
-
 """
     parsecommandline()
 
diff --git a/src/core/utils.jl b/src/core/utils.jl
index 26882de921687502bb70bd6cbd359fa23bb18822..857d3e9f9edc89f0d029254f557d53bc721e9494 100644
--- a/src/core/utils.jl
+++ b/src/core/utils.jl
@@ -4,6 +4,8 @@
 ### units and dates.
 ###
 
+### UNITS AND DIMENSIONS
+
 ## Import and define units and dimensions
 import Unitful: cm, m, km, ha, mg, g, kg, Length, Area, Mass
 const m² = m^2
@@ -14,7 +16,7 @@ Base.:(/)(x::S,y::T) where {S<:Length, T<:Length} = (upreferred(x)/m) / (uprefer
 Base.:(/)(x::S,y::T) where {S<:Area, T<:Area} = (upreferred(x)/m²) / (upreferred(y)/m²)
 Base.:(/)(x::S,y::T) where {S<:Mass, T<:Mass} = (upreferred(x)/g) / (upreferred(y)/g)
 
-## Utility type and function for working wth recurring dates
+## RECURRING DATES
 
 """
     AnnualDate
@@ -87,3 +89,62 @@ Convert an AnnualDate to a Date, using the current/next/previous year of the sim
 thisyear(ad::AnnualDate, model::SimulationModel) = Date(year(model.date), ad)
 nextyear(ad::AnnualDate, model::SimulationModel) = Date(year(model.date)+1, ad)
 lastyear(ad::AnnualDate, model::SimulationModel) = Date(year(model.date)-1, ad)
+
+### RANDOM NUMBERS
+
+"""
+    randn(vector)
+
+Return a random element from the given vector, following a (mostly) normal distribution based on
+index values (i.e. elements in the middle of the vector will be returned most frequently).
+"""
+function randn(v::Vector, rng=default_rng())
+    r = randn(rng) + 3 # normal distribution centered around 3, gives values from 0 to 6
+    step = 6 / length(v)
+    i = Int(round(r / step))
+    v[i]
+end
+
+"""
+    @randn(args...)
+
+Return a normally-distributed random number or element from the sample, using the model RNG.
+This is a utility wrapper that can only be used a context where the
+`model` object is available.
+"""
+macro randn(args...)
+    :($(esc(:randn))($(esc(:model)).rng, $(map(esc, args)...)))
+end
+
+"""
+    @rand(args...)
+
+Return a random number or element from the sample, using the model RNG.
+This is a utility wrapper that can only be used a context where the
+`model` object is available.
+"""
+macro rand(args...)
+    :($(esc(:rand))($(esc(:model)).rng, $(map(esc, args)...)))
+end
+
+"""
+    @shuffle!(collection)
+
+Shuffle the given collection in place, using the model RNG.
+This is a utility wrapper that can only be used a context where the
+`model` object is available.
+"""
+macro shuffle!(collection)
+    :($(esc(:shuffle!))($(esc(:model)).rng, $(esc(collection))))
+end
+
+"""
+    @chance(odds)
+
+Return true if a random number is less than the odds (0.0 <= `odds` <= 1.0),
+using the model RNG. This is a utility wrapper that can only be used a context
+where the `model` object is available.
+"""
+macro chance(odds)
+    :($(esc(:rand))($(esc(:model)).rng) < $(esc(odds)))
+end