diff --git a/src/engine/runtime.js b/src/engine/runtime.js
index fa9c366bd..e756ec778 100644
--- a/src/engine/runtime.js
+++ b/src/engine/runtime.js
@@ -605,6 +605,14 @@ class Runtime extends EventEmitter {
         return 'BLOCKSINFO_UPDATE';
     }
 
+    /**
+     * Event name when the runtime tick loop has been started.
+     * @const {string}
+     */
+    static get RUNTIME_STARTED () {
+        return 'RUNTIME_STARTED';
+    }
+
     /**
      * How rapidly we try to step threads by default, in ms.
      */
@@ -2172,6 +2180,7 @@ class Runtime extends EventEmitter {
         this._steppingInterval = setInterval(() => {
             this._step();
         }, interval);
+        this.emit(Runtime.RUNTIME_STARTED);
     }
 
     /**
diff --git a/src/virtual-machine.js b/src/virtual-machine.js
index b829664a2..436d37d12 100644
--- a/src/virtual-machine.js
+++ b/src/virtual-machine.js
@@ -126,6 +126,9 @@ class VirtualMachine extends EventEmitter {
         this.runtime.on(Runtime.MIC_LISTENING, listening => {
             this.emit(Runtime.MIC_LISTENING, listening);
         });
+        this.runtime.on(Runtime.RUNTIME_STARTED, () => {
+            this.emit(Runtime.RUNTIME_STARTED);
+        });
 
         this.extensionManager = new ExtensionManager(this.runtime);
 
diff --git a/test/unit/engine_runtime.js b/test/unit/engine_runtime.js
index 4fd56416b..2d5c28978 100644
--- a/test/unit/engine_runtime.js
+++ b/test/unit/engine_runtime.js
@@ -1,4 +1,4 @@
-const test = require('tap').test;
+const tap = require('tap');
 const path = require('path');
 const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
 const VirtualMachine = require('../../src/virtual-machine');
@@ -6,6 +6,10 @@ const Runtime = require('../../src/engine/runtime');
 const MonitorRecord = require('../../src/engine/monitor-record');
 const {Map} = require('immutable');
 
+tap.tearDown(() => process.nextTick(process.exit));
+
+const test = tap.test;
+
 test('spec', t => {
     const r = new Runtime();
 
@@ -180,3 +184,14 @@ test('Cloud variable limit allows only 8 cloud variables', t => {
     t.end();
 
 });
+
+test('Starting the runtime emits an event', t => {
+    let started = false;
+    const rt = new Runtime();
+    rt.addListener('RUNTIME_STARTED', () => {
+        started = true;
+    });
+    rt.start();
+    t.equal(started, true);
+    t.end();
+});
diff --git a/test/unit/virtual-machine.js b/test/unit/virtual-machine.js
index 371cd96cf..78036fdcf 100644
--- a/test/unit/virtual-machine.js
+++ b/test/unit/virtual-machine.js
@@ -1,4 +1,4 @@
-const test = require('tap').test;
+const tap = require('tap');
 const VirtualMachine = require('../../src/virtual-machine');
 const Sprite = require('../../src/sprites/sprite');
 const Variable = require('../../src/engine/variable');
@@ -8,6 +8,10 @@ const Renderer = require('../fixtures/fake-renderer');
 const Runtime = require('../../src/engine/runtime');
 const RenderedTarget = require('../../src/sprites/rendered-target');
 
+tap.tearDown(() => process.nextTick(process.exit));
+
+const test = tap.test;
+
 test('deleteSound returns function after deleting or null if nothing was deleted', t => {
     const vm = new VirtualMachine();
     const sprite = new Sprite();
@@ -967,3 +971,14 @@ test('Getting the renderer returns the renderer', t => {
     t.equal(vm.renderer, renderer);
     t.end();
 });
+
+test('Starting the VM emits an event', t => {
+    let started = false;
+    const vm = new VirtualMachine();
+    vm.addListener('RUNTIME_STARTED', () => {
+        started = true;
+    });
+    vm.start();
+    t.equal(started, true);
+    t.end();
+});