diff --git a/Source/Engine/Game.swift b/Source/Engine/Game.swift
index 3a12b7b..6e23584 100644
--- a/Source/Engine/Game.swift
+++ b/Source/Engine/Game.swift
@@ -17,6 +17,10 @@ public enum GameState {
     case playing
 }
 
+public struct SavedGame: Codable {
+    let world: World?
+}
+
 public struct Game {
     public weak var delegate: GameDelegate?
     public let levels: [Tilemap]
@@ -39,6 +43,24 @@ public extension Game {
         return HUD(player: world.player, font: font)
     }
 
+    func save() -> SavedGame {
+        switch state {
+        case .playing:
+            return SavedGame(world: world)
+        default:
+            return SavedGame(world: nil)
+        }
+    }
+
+    mutating func load(_ savedGame: SavedGame) {
+        guard let world = savedGame.world else {
+            self.state = .title
+            return
+        }
+        self.state = .playing
+        self.world = world
+    }
+
     mutating func update(timeStep: Double, input: Input) {
         guard let delegate = delegate else {
             return
diff --git a/Source/Rampage/ViewController.swift b/Source/Rampage/ViewController.swift
index be69759..04e02fc 100644
--- a/Source/Rampage/ViewController.swift
+++ b/Source/Rampage/ViewController.swift
@@ -13,7 +13,11 @@ import Renderer
 private let joystickRadius: Double = 40
 private let maximumTimeStep: Double = 1 / 20
 private let worldTimeStep: Double = 1 / 120
-private let savePath = "~/Documents/quicksave.json"
+
+private let savedGameURL: URL = {
+  let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
+  return documentsURL.appendingPathComponent("quicksave.plist")
+}()
 
 public func loadLevels() -> [Tilemap] {
     let jsonURL = Bundle.main.url(forResource: "Levels", withExtension: "json")!
@@ -160,15 +164,15 @@ class ViewController: UIViewController {
     }
 
     func saveState() throws {
-        let data = try JSONEncoder().encode(world)
-        let url = URL(fileURLWithPath: (savePath as NSString).expandingTildeInPath)
-        try data.write(to: url, options: .atomic)
+        let savedGame = game.save()
+        let data = try PropertyListEncoder().encode(savedGame)
+        try data.write(to: savedGameURL, options: .atomic)
     }
 
     func restoreState() throws {
-        let url = URL(fileURLWithPath: (savePath as NSString).expandingTildeInPath)
-        let data = try Data(contentsOf: url)
-        world = try JSONDecoder().decode(World.self, from: data)
+        let data = try Data(contentsOf: savedGameURL)
+        let savedGame = try PropertyListDecoder().decode(SavedGame.self, from: data)
+        game.load(savedGame)
     }
 }