Files
playdate-kit/Sources/PlaydateKit/PlaydateKit.docc/GettingStarted.md
T
javier 2e7ee12ec1
CI / Build & test (macOS) (push) Has been cancelled
CI / Embedded Swift cross-compile (push) Has been cancelled
Documentation / deploy (push) Has been cancelled
Adjusted the naming of the library in the Package file.
2026-07-25 12:02:55 +02:00

1.9 KiB

Getting Started

Bootstrap the bindings from your game's entry point and drive a frame loop.

Overview

A Playdate game has a single C entry point, eventHandler, which the firmware calls with a PlaydateAPI* and an event code. Export it with @_cdecl, call Playdate/initialize(with:) on the first event, and install an update callback:

import CPlaydate
import PlaydateKit

@_cdecl("eventHandler")
func eventHandler(
    pointer: UnsafeMutableRawPointer,
    event: PDSystemEvent,
    argument: UInt32
) -> Int32 {
    if case .initialize = SystemEvent(event: event, argument: argument) {
        Playdate.initialize(with: pointer)   // must happen before anything else
        Game.shared.start()
    }

    return 0
}

final class Game {
    nonisolated(unsafe) static let shared = Game()

    func start() {
        Display.setRefreshRate(50)

        System.setUpdateCallback {
            self.update()
            return true   // true = redraw the display this frame
        }
    }

    func update() {
        let (_, pushed, _) = System.buttonState
        if pushed.contains(.a) {
            System.log("A pressed")
        }

        Graphics.clear(color: .white)
        Graphics.drawText("Hello, Playdate", x: 8, y: 8)
        System.drawFPS()
    }
}

Conventions to know

  • Initialization. Calling any wrapper before Playdate/initialize(with:) is a programmer error and will crash.
  • Errors. Fallible operations use typed throws — PlaydateError generally, Network/NetError for network I/O.
  • Ownership. A wrapper that creates a C object frees it on deinit; keep the wrapper referenced for as long as you use it. Wrappers vending OS-owned objects don't free them — keep the owner alive instead, as documented on each API.
  • Threading. The Playdate runtime is single-threaded; don't call the API from other threads.