the sartrean knight

published

overview

the sartrean knight is a short interactive story blending medieval fantasy with existential philosophy. inspired by the works of Jean-Paul Sartre, the experience invites you to navigate a reflective journey about meaning, freedom, and the consequences of choice.

you play as a weary knight facing a mysterious gatekeeper. through dialogue and memories, you will determine your own path and conclusion, featuring multiple unique endings and full support for both English and Portuguese.

i developed the sartrean knight in one week during the initial phase of my experience at the Apple Developer Academy. the project was an opportunity to explore interactive storytelling and the design of meaningful choices.

i learned a lot about using JSON to build a game's narrative structure, as well as honing my skills in SwiftUI and Combine. it was also a rudimentary way to implement localization for an app, paving the way for me to later learn about using string catalogs.

design choices

palette

mist #F1F1F1
ink #000000
paper #FFFFFF

typography

MedievalSharp / antiquity and authenticity
The quick fox jumps over the lazy dog
Jacquard 24 / gothic decorative touch
The quick fox jumps over the lazy dog

rationale

the design of the sartrean knight was inspired by the aesthetics of medieval manuscripts, reflecting the philosophical and historical theme of the narrative.

the choice of MedievalSharp and Jacquard 24 fonts aims to evoke a sense of antiquity and authenticity, while the soft color palette and old paper textures complement the game's contemplative atmosphere.

in terms of story development, the choice to include images at each stage of the narrative was made to enrich the player's experience, providing a visual context that helps immerse them in the medieval setting.

the images were created to reflect the themes and emotions present in each part of the story, reinforcing the connection between the player and the plot.

the image frames were designed to resemble a decorated illustration that could be seen in an old book.

the images themselves do not follow a specific artistic style, although they have certain gothic tendencies, but seek to capture the essence of the setting and characters in an evocative way.

tech stack

SwiftUI
UI framework
Combine
reactive state
JSON / Codable
narrative engine
Icon Composer
asset creation

code snippets

Story data loading optimization

swift
private func loadStory() {
    guard let url = Bundle.main.url(forResource: "story", withExtension: "json"),
          let data = try? Data(contentsOf: url) else { return }
    do {
        let decoded = try JSONDecoder().decode(StoryData.self, from: data)
        for page in decoded.screens {
            pages[page.id] = page
        }
        orderedPages = decoded.screens
        currentPageID = decoded.screens.first?.id
    } catch {
        print("Failed to decode story.json: \(error)")
    }
}

Custom typography parser

swift
func parseFigureSegments(_ input: String) -> [FigureSegment] {
    var segments: [FigureSegment] = []
    let parts = input.components(separatedBy: "[figure]")
    
    for part in parts {
        if part.contains("[/figure]") {
            let subParts = part.components(separatedBy: "[/figure]")
            if subParts.count >= 1 {
                segments.append(FigureSegment(text: subParts[0], isFigure: true))
                if subParts.count > 1 && !subParts[1].isEmpty {
                    segments.append(FigureSegment(text: subParts[1], isFigure: false))
                }
            }
        } else if !part.isEmpty {
            segments.append(FigureSegment(text: part, isFigure: false))
        }
    }
    return segments
}

Reactive localization system

swift
class AppLanguage: ObservableObject {
    enum Language: String {
        case english = "en"
        case portuguese = "pt"
    }
    
    @Published var current: Language = .english
    
    func toggle() {
        current = (current == .english) ? .portuguese : .english
    }
}

credits

people

design · development
pedro wiezel

fonts

MedievalSharp
Wojciech Kalinowski
Jacquard 24
Sarah Cadigan-Fried

assets

textures
@joou and @samueladekunle (Figma Community)
backgrounds