diff --git a/src/GUI.jl b/src/GUI.jl
index 60356902b0f016c4b95403b5a73f25406b0c657d..25aea7c645546f10219b644834dde59c5523295f 100644
--- a/src/GUI.jl
+++ b/src/GUI.jl
@@ -6,16 +6,17 @@
 
 function loadsimulation(filename)
     global model
-    launching[] = true
+    @emit showSplash()
     fn = convert(filename, String)
     startswith(fn, "file://") && (fn = fn[8:end])
-    model = loadmodelobject(fn)
     running[] = false
+    model = loadmodelobject(fn)
     landcovermap = rotr90(load(@param(world.landcovermap)))
     date[] = model.date
     progress[] = (date[]-@param(core.startdate)) /
         (@param(core.enddate)-@param(core.startdate))
-    launching[] = false
+    @emit closeSplash()
+    @emit updateMakie()
     println("Loaded simulation.")
 end
 
@@ -36,21 +37,6 @@ function Base.convert(s::QString, ::Type{<:AbstractString})
 end
 
 #TODO saveoutput()
-
-function togglerunning()
-    global runsimulation, timer
-    if running[]
-        running[] = false
-        QML.stop(timer)
-        runbuttontext[] = ">>"
-        runbuttontip[] = "Run"
-    else
-        running[] = true
-        runbuttontext[] = "||"
-        runbuttontip[] = "Pause"
-        QML.start(timer)
-    end
-end
  
 function render_map(screen)
     global model, mapimage, landcovermap
@@ -108,22 +94,31 @@ end
 on(launching) do l
     if l
         @emit showSplash()
+        println("Showing splash screen.") #XXX DEBUG
     else
         @emit closeSplash()
         @emit updateMakie()
     end
 end
 
+on(running) do r
+    if r
+        runbuttontext[] = "||"
+        runbuttontip[] = "Pause"
+    else
+        runbuttontext[] = ">>"
+        runbuttontip[] = "Run"
+    end
+end
+
 datestring = () -> Dates.format(date[], "dd U yyyy")
 
-function activateqmlfunctions()     
-    @qmlfunction newsimulation
+function activateqmlfunctions()
     @qmlfunction configwindow
     @qmlfunction loadsimulation
     @qmlfunction savesimulation
     @qmlfunction nextstep
     @qmlfunction previousstep
-    @qmlfunction togglerunning
     @qmlfunction datestring
     @qmlfunction writeconfig
 end
@@ -149,12 +144,7 @@ function launch()
             vars = JuliaPropertyMap(guiproperties...),
             render_map_callback = @safe_cfunction(render_map, Cvoid, (Any,)),
             render_plot_callback = @safe_cfunction(render_plot, Cvoid, (Any,)))
-    launching[] = true
-    if isnothing(model)
-        #QML.start(timer)
-        #newsimulation()
-        #QML.stop(timer)
-    end
+    isnothing(model) && (launching[] = true) # initiates model initialisation
     println("Launched Persefone Desktop.")
-    exec() #TODO how do I make this async? -> change to Threads.@spawn?
+    exec()
 end
diff --git a/src/logic.jl b/src/logic.jl
index 3ae716528f7e7e9019ecb1953cb79ddf73ba11bf..ddf660780fda8779c6e64745de909bcb9f4341e2 100644
--- a/src/logic.jl
+++ b/src/logic.jl
@@ -3,17 +3,18 @@
 ### This file manages the model initialisation and run functions.
 ###
 
-
-function newsimulation()
+@resumable function createlaunchfunction()
     global model, landcovermap
-    launching[] = true # trigger the launch screen
+    Ps = Persefone
     running[] = false
     progress[] = 0.0
+    @yield 1
     model = initialise(configfile[])
+    @yield 1
     landcovermap = rotr90(load(@param(world.landcovermap)))
     date[] = model.date
     launching[] = false
-    println("Model initialised.")
+    println("Model initialised (resumable).")
 end
 
 function nextstep()
@@ -39,6 +40,23 @@ function nextstep()
     println("Updated model: $(date[]-Day(1))")
 end
 
+#XXX This could also be done with Channels rather than ResumableFunctions,
+# which would save us one dependency (Channels are inbuilt). However, the
+# ResumableFunctions version seemed to work more smoothly.
+@resumable function createrunfunction()
+    i = round(delay[]*20)
+    while running[]
+        i -= 1
+        if i <= 0
+            nextstep()
+            i = round(delay[]*20)
+        end
+        # to reduce interface lag, always only sleep for 50ms
+        sleep(0.05)
+        @yield 1
+    end
+end
+
 function previousstep()
     # Since we store all model output in a dataframe, we can simply
     # "scroll back" in time and visualise the state of the model at
@@ -52,31 +70,30 @@ function previousstep()
     println("Backtracked model: $(date[]-Day(1))")
 end
 
-#XXX This could also be done with Channels rather than ResumableFunctions,
-# which would save us one dependency (Channels are inbuilt). However, the
-# ResumableFunctions version seemed to work more smoothly.
-@resumable function createrunfunction()
-    i = round(delay[]*10)
-    while running[]
-        i -= 1
-        if i <= 0
-            nextstep()
-            i = round(delay[]*10)
-        end
-        # to reduce interface lag, always only sleep for 0.1s
-        sleep(0.1)
-        @yield 1
+on(launching; priority=10) do l
+    if l
+        QML.start(timer)
+        global newsimulation = createlaunchfunction()
+        println("Setting up model.") 
+    else
+        QML.stop(timer)
+        println("Model setup complete.")
     end
 end
 
-
-on(running) do r
-    ticks = 0 #prevent overflows
-    runsimulation = createrunfunction()
-    r ? println("Simulation started.") : println("Simulation stopped.") #XXX DEBUG
+on(running; priority=10) do r
+    if r
+        QML.start(timer)
+        global runsimulation = createrunfunction()
+        println("Simulation started.")
+    else
+        !launching[] && QML.stop(timer)
+        println("Simulation stopped.")
+    end
 end
 
 on(ticks) do t
-    #launching[] && #FIXME
+    launching[] && newsimulation()
     running[] && runsimulation()
+    t >= typemax(Int32) && (ticks[] = 0) #prevent overflow
 end
diff --git a/src/main.qml b/src/main.qml
index f06c1898ead9c393b55b4f0307d005df3566d8eb..28be96994a3e630496cc1a9196e6a958eb7d10ce 100644
--- a/src/main.qml
+++ b/src/main.qml
@@ -22,7 +22,7 @@ ApplicationWindow {
 			title: "&Simulation"
 			Action {
 				text: "&New Simulation"
-				onTriggered: { Julia.newsimulation() } //TODO select config file
+				onTriggered: { vars.launching = true } //TODO select config file
 			}
 			Action {
 				text: "&Configure Simulation"
@@ -110,7 +110,7 @@ ApplicationWindow {
 				text: vars.runbuttontext
 				ToolTip.text: vars.runbuttontip
 				ToolTip.visible: hovered
-				onClicked: { Julia.togglerunning() }
+				onClicked: { vars.running = !vars.running }
 			}
 			ProgressBar {
 				id: progressBar
diff --git a/src/variables.jl b/src/variables.jl
index b2a6b85de9cb40e50a9964d743c2853ee3c50d55..01a87ef76ce703ca16ebb5a6767b366de4c1c855 100644
--- a/src/variables.jl
+++ b/src/variables.jl
@@ -8,7 +8,8 @@
 
 global model = nothing
 global landcovermap = nothing
-global runsimulation = nothing
+global runsimulation = () -> nothing
+#global newsimulation = () -> nothing
 global timer = nothing
 
 const configfile = Observable("guiparams.toml")
@@ -47,7 +48,8 @@ const cropmodel = Observable("ALMaSS") #XXX alternatives not yet implemented
 ## the property list passed to QML
 
 global guiproperties =
-    ["running" => running,
+    ["launching" => launching,
+     "running" => running,
      "ticks" => ticks,
      "date" => date,
      "delay" => delay,