Skip to content

Commit

Permalink
🚸 Finishing touches
Browse files Browse the repository at this point in the history
In this commit, I've made some finishing touches to help advance
the development after the prototype launch.

First, I've created a system to load in a specific set of scenes
in a given order with a JSON configuration that gets loaded at
launch time. This will control which levels play in a specific
order.

Next, I've tested the prototype on iOS and fixed any remaining
snags that may make the game unplayable on iPad and iPhone.

Finally, I've fixed the story conversion script in the build config
so that it executes to the new structure.

Signed-off-by: Marquis Kurt <software@marquiskurt.net>
  • Loading branch information
alicerunsonfedora committed Oct 7, 2022
1 parent b40d8af commit af31160
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 197 deletions.
354 changes: 177 additions & 177 deletions Shounin/Assets/Story/Base.lproj/ch01-mise-en-abyme.jenson

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions Shounin/Bootstrap/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,30 @@ import GameKit
// MARK: - General App Delegation

class AppDelegate: NSObject {
typealias GameFlow = [FlowConfiguration]
static var observedState = GameEnvironmentState()
static var currentGameFlow: GameFlow?

func setUpGameCenterAccessPoint() {
GKAccessPoint.shared.location = .bottomTrailing
GKAccessPoint.shared.showHighlights = true
}

func fetchGameFlow() {
if let config = FlowConfiguration.load(from: "GameFlow") {
AppDelegate.currentGameFlow = config
}
}
}

// MARK: - Mac App Delegate Adaptor

#if os(macOS)
extension AppDelegate: NSApplicationDelegate {
func applicationWillFinishLaunching(_ notification: Notification) {
fetchGameFlow()
}

// Authenticate with Game Center.
func applicationDidFinishLaunching(_: Notification) {
if let useGC = Bundle.main.gameCenterEnabled, useGC {
Expand Down Expand Up @@ -84,6 +96,7 @@ extension AppDelegate: UIApplicationDelegate {
_: UIApplication,
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
fetchGameFlow()
if let useGC = Bundle.main.gameCenterEnabled, useGC {
DispatchQueue.main.async {
GKLocalPlayer.local.authenticateHandler = { loginSheet, error in
Expand Down
2 changes: 1 addition & 1 deletion Shounin/Bootstrap/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ enum NavigationState: Equatable {
}

struct ContentView: View {
@State private var navigationState: NavigationState = .mainMenu
@State private var navigationState: NavigationState = .game
@State private var displaySettings = false
var body: some View {
Group {
Expand Down
32 changes: 32 additions & 0 deletions Shounin/Bootstrap/Flow Configuration/FlowConfiguration.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// FlowConfiguration.swift
// Indexing Your Heart
//
// Created by Marquis Kurt on 10/7/22.
//
// This file is part of Indexing Your Heart.
//
// Indexing Your Heart is non-violent software: you can use, redistribute, and/or modify it under the terms of the
// CNPLv7+ as found in the LICENSE file in the source code root directory or at
// <https://git.pixie.town/thufie/npl-builder>.
//
// Indexing Your Heart comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. See the CNPL for
// details.

import Foundation

struct FlowConfiguration: Codable {
let stage: String
let chapter: String
}

extension FlowConfiguration {
static func load(from resourceName: String) -> [FlowConfiguration]? {
guard let path = Bundle.main.path(forResource: resourceName, ofType: "json") else { return nil }
let url = URL(filePath: path)
guard let data = try? Data(contentsOf: url) else { return nil }
let jsonDecoder = JSONDecoder()
jsonDecoder.allowsJSON5 = true
return try? jsonDecoder.decode([FlowConfiguration].self, from: data)
}
}
6 changes: 6 additions & 0 deletions Shounin/Bootstrap/GameFlow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"stage": "Stage1",
"chapter": "ch01-mise-en-abyme"
}
]
2 changes: 1 addition & 1 deletion Shounin/Extensions/SKTexture+URLInit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import UIKit

extension SKTexture {
convenience init?(contentsOf url: URL) {
guard let image = UIImage(contentsOf: url) else { return nil }
guard let image = UIImage(contentsOfFile: url.absoluteString) else { return nil }
self.init(image: image)
}
}
Expand Down
16 changes: 16 additions & 0 deletions Shounin/Shounin.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
958E090828F06786009E6AD9 /* Art_32x32.tsx in Resources */ = {isa = PBXBuildFile; fileRef = 958E090728F06786009E6AD9 /* Art_32x32.tsx */; };
958E090A28F067B0009E6AD9 /* 7_Art_32x32.png in Resources */ = {isa = PBXBuildFile; fileRef = 958E090928F067B0009E6AD9 /* 7_Art_32x32.png */; };
958E090C28F08695009E6AD9 /* SKTexture+URLInit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958E090B28F08695009E6AD9 /* SKTexture+URLInit.swift */; };
958E090E28F0B1D3009E6AD9 /* GameFlow.json in Resources */ = {isa = PBXBuildFile; fileRef = 958E090D28F0B1D3009E6AD9 /* GameFlow.json */; };
958E091128F0B20C009E6AD9 /* FlowConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958E091028F0B20C009E6AD9 /* FlowConfiguration.swift */; };
95A9605628EB603700F05059 /* CGImage+Resizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A9605528EB603700F05059 /* CGImage+Resizable.swift */; };
95A9605828EB61F600F05059 /* Bundle+InfoPlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A9605728EB61F600F05059 /* Bundle+InfoPlist.swift */; };
95AD565E28EE20B500051144 /* SKTiled in Frameworks */ = {isa = PBXBuildFile; productRef = 95AD565D28EE20B500051144 /* SKTiled */; };
Expand Down Expand Up @@ -129,6 +131,8 @@
958E090728F06786009E6AD9 /* Art_32x32.tsx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Art_32x32.tsx; sourceTree = "<group>"; };
958E090928F067B0009E6AD9 /* 7_Art_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 7_Art_32x32.png; sourceTree = "<group>"; };
958E090B28F08695009E6AD9 /* SKTexture+URLInit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SKTexture+URLInit.swift"; sourceTree = "<group>"; };
958E090D28F0B1D3009E6AD9 /* GameFlow.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = GameFlow.json; sourceTree = "<group>"; };
958E091028F0B20C009E6AD9 /* FlowConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowConfiguration.swift; sourceTree = "<group>"; };
95A9605528EB603700F05059 /* CGImage+Resizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGImage+Resizable.swift"; sourceTree = "<group>"; };
95A9605728EB61F600F05059 /* Bundle+InfoPlist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+InfoPlist.swift"; sourceTree = "<group>"; };
95AD566028EE241400051144 /* GameEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameEnvironment.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -348,12 +352,22 @@
path = Puzzles;
sourceTree = "<group>";
};
958E090F28F0B1FC009E6AD9 /* Flow Configuration */ = {
isa = PBXGroup;
children = (
958E091028F0B20C009E6AD9 /* FlowConfiguration.swift */,
);
path = "Flow Configuration";
sourceTree = "<group>";
};
9598462D28EC7BD6009585DA /* Bootstrap */ = {
isa = PBXGroup;
children = (
958E090F28F0B1FC009E6AD9 /* Flow Configuration */,
950F6CFB28C13D6F007ACB53 /* Entrypoint.swift */,
9524434928C781FB005F91E1 /* ContentView.swift */,
956B604528C7A4730031794C /* AppDelegate.swift */,
958E090D28F0B1D3009E6AD9 /* GameFlow.json */,
);
path = Bootstrap;
sourceTree = "<group>";
Expand Down Expand Up @@ -573,6 +587,7 @@
950F6CFE28C156A6007ACB53 /* Localizable.strings in Resources */,
95DB209028CFA9840079D624 /* ch02.md in Resources */,
9533177028D3788C00E6E516 /* ch06-les-conseils-pour-les-jeunes.jenson in Resources */,
958E090E28F0B1D3009E6AD9 /* GameFlow.json in Resources */,
95DB209328CFA9840079D624 /* ch05.md in Resources */,
9533176128D3787C00E6E516 /* ch01-mise-en-abyme.jenson in Resources */,
95011E7128C77B1D00E511F3 /* Salmon Sans 9 Bold.ttf in Resources */,
Expand Down Expand Up @@ -676,6 +691,7 @@
files = (
9510BD3128EB196E00AD0E28 /* PrototypeValidator.mlmodel in Sources */,
95E4F62428ECA05C009627F6 /* CaslonSceneView.swift in Sources */,
958E091128F0B20C009E6AD9 /* FlowConfiguration.swift in Sources */,
95FFC8FB28EF3A2D009D1A15 /* GamePlayer.swift in Sources */,
95E4F62128EC9CD9009627F6 /* CaslonScene.swift in Sources */,
9533175928D36A2900E6E516 /* SettingsView.swift in Sources */,
Expand Down
34 changes: 24 additions & 10 deletions Shounin/Views/GameSceneView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,37 @@ struct GameSceneView: View {
@AppStorage("dbg:show-nodes") var dbgShowNodes = false
@AppStorage("dbg:show-fps") var dbgShowFPS = false
@State private var debugOptions: SpriteView.DebugOptions = []

private var gameScene: SKScene = {
let scene = GameEnvironment(stageNamed: "Stage1")
scene.setEndingScene(to: "ch02-le-marteau-timide")
return scene
}()
@State private var gameFlow: AppDelegate.GameFlow = []

var body: some View {
ZStack {
Color.black
SpriteView(scene: gameScene, transition: .fade(withDuration: 2), debugOptions: debugOptions)
SpriteView(
scene: getGameSceneInCurrentContext(),
transition: .fade(withDuration: 2),
debugOptions: debugOptions
)
.aspectRatio(16 / 9, contentMode: .fit)
}
.onAppear {
if dbgShowNodes { debugOptions.insert(.showsNodeCount) }
if dbgShowFPS { debugOptions.insert(.showsFPS) }
// debugOptions.insert(.showsPhysics)
configureDebugSettings()
loadFlowIntoScene()
}
}

private func getGameSceneInCurrentContext() -> some SKScene {
let scene = GameEnvironment(stageNamed: gameFlow.first?.stage ?? "Stage1")
scene.setEndingScene(to: gameFlow.first?.chapter ?? "epilogue")
return scene
}

private func configureDebugSettings() {
if dbgShowNodes { debugOptions.insert(.showsNodeCount) }
if dbgShowFPS { debugOptions.insert(.showsFPS) }
}

private func loadFlowIntoScene() {
guard let flow = AppDelegate.currentGameFlow else { return }
gameFlow = flow
}
}
16 changes: 8 additions & 8 deletions Shounin/jenson-convert.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,48 +14,48 @@

echo "Converting Chapter 1..."
marteau jenson Story\ Source/ch01.md \
Shared/Assets/Story/Base.lproj/ch01-mise-en-abyme.jenson \
Assets/Story/Base.lproj/ch01-mise-en-abyme.jenson \
--chapter-name "Mise en Abyme"
echo "Done."

echo "Converting Chapter 2..."
marteau jenson Story\ Source/ch02.md \
Shared/Assets/Story/Base.lproj/ch02-le-marteau-timide.jenson \
Assets/Story/Base.lproj/ch02-le-marteau-timide.jenson \
--chapter-name "Le Marteau Timide"
echo "Done."

echo "Converting Chapter 3..."
marteau jenson Story\ Source/ch03.md \
Shared/Assets/Story/Base.lproj/ch03-ecouter-la-vague.jenson \
Assets/Story/Base.lproj/ch03-ecouter-la-vague.jenson \
--chapter-name "Écouter La Vague"
echo "Done."

echo "Converting Chapter 4..."
marteau jenson Story\ Source/ch04.md \
Shared/Assets/Story/Base.lproj/ch04-la-reveuse-sentimental.jenson \
Assets/Story/Base.lproj/ch04-la-reveuse-sentimental.jenson \
--chapter-name "La Rêveuse Sentimental"
echo "Done."

echo "Converting Chapter 5..."
marteau jenson Story\ Source/ch05.md \
Shared/Assets/Story/Base.lproj/ch05-la-lumiere-sombre.jenson \
Assets/Story/Base.lproj/ch05-la-lumiere-sombre.jenson \
--chapter-name "La Lumière Sombre"
echo "Done."

echo "Converting Chapter 6..."
marteau jenson Story\ Source/ch06.md \
Shared/Assets/Story/Base.lproj/ch06-les-conseils-pour-les-jeunes.jenson \
Assets/Story/Base.lproj/ch06-les-conseils-pour-les-jeunes.jenson \
--chapter-name "Les Conseils pour les Jeunes dans le Cœur"
echo "Done."

echo "Converting Chapter 7..."
marteau jenson Story\ Source/ch07.md \
Shared/Assets/Story/Base.lproj/ch07-changer-de-vie.jenson \
Assets/Story/Base.lproj/ch07-changer-de-vie.jenson \
--chapter-name "Changer de Vie"
echo "Done."

echo "Converting Epilogue..."
marteau jenson Story\ Source/epilogue.md \
Shared/Assets/Story/Base.lproj/epilogue.jenson \
Assets/Story/Base.lproj/epilogue.jenson \
--chapter-name "Epilogue"
echo "Done."

0 comments on commit af31160

Please sign in to comment.