diff --git a/QtSLiM/recipes.qrc b/QtSLiM/recipes.qrc
index bcaa1cb3..23d65051 100644
--- a/QtSLiM/recipes.qrc
+++ b/QtSLiM/recipes.qrc
@@ -202,5 +202,6 @@
recipes/Recipe 19.6 - A coevolutionary host-parasitoid trait-matching model.txt
recipes/Recipe 19.7 - A coevolutionary host-parasite matching-allele model.txt
recipes/Recipe 19.8 - Within-host reproduction in a host-pathogen model.txt
+ recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt
diff --git a/QtSLiM/recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt b/QtSLiM/recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt
new file mode 100644
index 00000000..3327d8fa
--- /dev/null
+++ b/QtSLiM/recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt
@@ -0,0 +1,62 @@
+initialize() {
+ initializeSLiMModelType("nonWF");
+ initializeSLiMOptions(dimensionality="xy");
+ defineConstant("K", 100000); // carrying-capacity density
+ defineConstant("S", 0.005); // sigma_S, the spatial interaction width
+ defineConstant("M", 0.025); // sigma_M, the spatial mating width
+
+ initializeMutationType("m1", 0.5, "f", 0.0);
+ m1.convertToSubstitution = T;
+
+ initializeGenomicElementType("g1", m1, 1.0);
+ initializeGenomicElement(g1, 0, 1e8 - 1);
+ initializeMutationRate(1e-7);
+ initializeRecombinationRate(1e-8);
+
+ // competition kernel
+ initializeInteractionType(1, "xy", reciprocal=T, maxDistance=S * 2);
+ i1.setInteractionFunction("n", 1.0, S);
+
+ // mating kernel
+ initializeInteractionType(2, "xy", reciprocal=T, maxDistance=M * 2);
+ i1.setInteractionFunction("n", 1.0, M);
+}
+2: first() {
+ i2.evaluate(p1);
+}
+reproduction() {
+ inds = p1.individuals;
+ mates = i2.drawByStrength(inds, 1, returnDict=T);
+ order = mates.compactIndices();
+ inds = inds[order];
+ num = rpois(size(inds), 5);
+ nonzero_indices = which(num > 0);
+
+ for (i in nonzero_indices)
+ {
+ ind = inds[i];
+ offspring = p1.addCrossed(ind, mates.getValue(i), count=num[i], defer=T);
+ offspring.setSpatialPosition(ind.spatialPosition);
+ }
+
+ self.active = 0;
+}
+1 early() {
+ sim.addSubpop("p1", K);
+ p1.individuals.setSpatialPosition(p1.pointUniform(K));
+}
+early() {
+ // deviate offspring from their maternal positions
+ newborns = p1.subsetIndividuals(maxAge=0);
+ old_pos = newborns.spatialPosition;
+ new_pos = p1.pointReflected(old_pos + rnorm(size(old_pos), 0, 0.02));
+ newborns.setSpatialPosition(new_pos);
+}
+early() {
+ // spatial competition
+ i1.evaluate(p1);
+ inds = p1.individuals;
+ competition = i1.localPopulationDensity(inds);
+ inds.fitnessScaling = K / competition;
+}
+100 late() { }
diff --git a/SLiMgui/Recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt b/SLiMgui/Recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt
new file mode 100644
index 00000000..3327d8fa
--- /dev/null
+++ b/SLiMgui/Recipes/Recipe 22.7 - Parallelizing nonWF reproduction and spatial interactions.txt
@@ -0,0 +1,62 @@
+initialize() {
+ initializeSLiMModelType("nonWF");
+ initializeSLiMOptions(dimensionality="xy");
+ defineConstant("K", 100000); // carrying-capacity density
+ defineConstant("S", 0.005); // sigma_S, the spatial interaction width
+ defineConstant("M", 0.025); // sigma_M, the spatial mating width
+
+ initializeMutationType("m1", 0.5, "f", 0.0);
+ m1.convertToSubstitution = T;
+
+ initializeGenomicElementType("g1", m1, 1.0);
+ initializeGenomicElement(g1, 0, 1e8 - 1);
+ initializeMutationRate(1e-7);
+ initializeRecombinationRate(1e-8);
+
+ // competition kernel
+ initializeInteractionType(1, "xy", reciprocal=T, maxDistance=S * 2);
+ i1.setInteractionFunction("n", 1.0, S);
+
+ // mating kernel
+ initializeInteractionType(2, "xy", reciprocal=T, maxDistance=M * 2);
+ i1.setInteractionFunction("n", 1.0, M);
+}
+2: first() {
+ i2.evaluate(p1);
+}
+reproduction() {
+ inds = p1.individuals;
+ mates = i2.drawByStrength(inds, 1, returnDict=T);
+ order = mates.compactIndices();
+ inds = inds[order];
+ num = rpois(size(inds), 5);
+ nonzero_indices = which(num > 0);
+
+ for (i in nonzero_indices)
+ {
+ ind = inds[i];
+ offspring = p1.addCrossed(ind, mates.getValue(i), count=num[i], defer=T);
+ offspring.setSpatialPosition(ind.spatialPosition);
+ }
+
+ self.active = 0;
+}
+1 early() {
+ sim.addSubpop("p1", K);
+ p1.individuals.setSpatialPosition(p1.pointUniform(K));
+}
+early() {
+ // deviate offspring from their maternal positions
+ newborns = p1.subsetIndividuals(maxAge=0);
+ old_pos = newborns.spatialPosition;
+ new_pos = p1.pointReflected(old_pos + rnorm(size(old_pos), 0, 0.02));
+ newborns.setSpatialPosition(new_pos);
+}
+early() {
+ // spatial competition
+ i1.evaluate(p1);
+ inds = p1.individuals;
+ competition = i1.localPopulationDensity(inds);
+ inds.fitnessScaling = K / competition;
+}
+100 late() { }