{"id":17304215,"url":"https://github.com/ericlewis/swift-playdate","last_synced_at":"2025-04-14T13:13:45.231Z","repository":{"id":61760838,"uuid":"473016746","full_name":"ericlewis/swift-playdate","owner":"ericlewis","description":"Swift package for building Playdate games \u0026 apps.","archived":false,"fork":false,"pushed_at":"2022-10-11T10:21:50.000Z","size":220,"stargazers_count":43,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-28T02:23:26.153Z","etag":null,"topics":["playdate","swift"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ericlewis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-03-23T02:59:15.000Z","updated_at":"2024-08-20T07:00:09.000Z","dependencies_parsed_at":"2022-10-20T20:00:14.655Z","dependency_job_id":null,"html_url":"https://github.com/ericlewis/swift-playdate","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericlewis%2Fswift-playdate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericlewis%2Fswift-playdate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericlewis%2Fswift-playdate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericlewis%2Fswift-playdate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ericlewis","download_url":"https://codeload.github.com/ericlewis/swift-playdate/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248886328,"owners_count":21177644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["playdate","swift"],"created_at":"2024-10-15T11:52:28.591Z","updated_at":"2025-04-14T13:13:45.166Z","avatar_url":"https://github.com/ericlewis.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Swift :heart: Playdate\n\nSwift package \u0026 plugin for building games that run on [Playdate's](https://play.date) [simulator](https://sdk.play.date/1.9.3/#using-playdate-simulator).\n\n### Some things to know:\n- Requires XCode 13.3+ \n- Only tested on M1 Mac.\n- Useful for exploring what swift development might be like, you cannot build for device (yet).\n- This is highly experimental and likely to change - the swift wrapper is barely started.\n- You will likely need to kill the simulator between runs, it doesn't seem to pick up on changes very well.\n- The plugin isn't very stable / smart, but it can be made to be.\n\n## Usage\n\n`swift-playdate` can be used via [swift-package-manager](https://github.com/apple/swift-package-manager). It only requires a small bit of project structure.\n\n- Must be a package based project with product type of dynamic.\n- Must have a `Sources/Resources` folder with *at least* a valid `pdxinfo` file inside.\n\t- note: other assets (images, sound, lua files) are to be added here too.\n- Builds are handled via SPM:\n\t- `swift package --disable-sandbox pdc`: creates a pdx file located at `.build/plugins/pdc/outputs/artifacts/{PACKAGE_DISPLAY_NAME}.pdx`\n\t- `swift package --disable-sandbox pdc --run`: creates a pdx file \u0026 opens it in the simulator\n  - `--disable-sandbox` is required because we are using plugins outside their typical reach.\n- Ideally swizzle the `EventCallback` in order to install an update handler.\n\n## Example\n```swift\nimport Playdate\n\n// MARK: Game Loop\n\nfunc updateCallback() -\u003e Bool {\n  Graphics.clear(with: .white)\n  processInputs()\n  DisplayList.updateAndDrawSprites()\n\n  return true\n}\n\nfunc processInputs() {\n  let state = System.currentButtonState\n  player.move(\n    by: .init(\n      x: state.contains(.left) ? -10 : state.contains(.right) ? 10 : 0,\n      y: state.contains(.up) ? -10 : state.contains(.down) ? 10 : 0\n    )\n  )\n}\n\n// MARK: Setup\n\nlet image = Bitmap(\"images/player\")\nlet player = Sprite()\n\nfunc initialize() {\n  setupPlayer()\n  setupMenu()\n}\n\nfunc setupPlayer() {\n  player.setImage(image)\n  player.move(to: .init(x: image.size.width, y: image.size.height))\n  player.addToDisplayList()\n}\n\nfunc setupMenu() {\n  Menu.addCheckmarkItem(\"inverted\", isOn: false) { isEnabled in\n    Display.isInverted = isEnabled\n  }\n}\n\n// MARK: Event Handler\n\n@_dynamicReplacement(for: EventCallback(event:))\nfunc eventCallback(event: SystemEvent) {\n  if event == .initialize {\n    initialize()\n    System.setUpdateCallback(updateCallback)\n  }\n}\n\n```\n\n## Supported APIs\nBelow is a list of all the C apis \u0026 wether or not there is some sort of equivalent in `Playdate`.\n\n### Display\n|Status|Name|\n|:-:|---|\n|✅|getWidth|\n|✅|getHeight|\n|✅|setRefreshRate|\n|✅|setInverted|\n|✅|setScale|\n|✅|setMosaic|\n|✅|setFlipped|\n|✅|setOffset|\n\n### File\n|Status|Name|\n|:-:|---|\n|🚧|geterr|\n|🚧|stat|\n|🚧|mkdir|\n|🚧|unlink|\n|🚧|rename|\n|🚧|open|\n|🚧|read|\n|🚧|write|\n|🚧|flush|\n|🚧|tell|\n|🚧|seek|\n\n### Graphics\n|Status|Name|\n|:-:|---|\n|✅|Clear|\n|✅|setBackgroundColor|\n|✅|setStencil|\n|✅|setDrawMode|\n|✅|setDrawOffset|\n|✅|setClipRect|\n|✅|setScreenClipRect|\n|✅|clearClipRect|\n|✅|setLineCapStyle|\n|✅|setFont|\n|✅|setTextTracking|\n|✅|setTextLeading|\n|✅|pushContext|\n|✅|popContext|\n\n#### Drawing\n|Status|Name|\n|:-:|---|\n|✅|drawBitmap|\n|✅|tileBitmap|\n|✅|drawLine|\n|🚧|fillTriangle|\n|✅|drawRect|\n|✅|fillRect|\n|🚧|drawEllipse|\n|🚧|fillEllipse|\n|🚧|fillPolygon|\n|✅|drawScaledBitmap|\n|✅|drawText|\n\n#### Bitmap\n|Status|Name|\n|:-:|---|\n|✅|newBitmap|\n|✅|freeBitmap|\n|✅|loadBitmap|\n|✅|copyBitmap|\n|🚧|loadIntoBitmap|\n|✅|getBitmapData|\n|✅|clearBitmap|\n|🚧|rotatedBitmap|\n\n#### BitmapTable\n|Status|Name|\n|:-:|---|\n|🚧|newBitmapTable|\n|🚧|freeBitmapTable|\n|🚧|loadBitmapTable|\n|🚧|loadIntoBitmapTable|\n|🚧|getBitmapTable|\n\n#### Font\n|Status|Name|\n|:-:|---|\n|🚧|loadFont|\n|🚧|getFontPage|\n|🚧|getPageGlyph|\n|🚧|getGlyphKerning|\n|🚧|getTextWidth|\n\n#### Raw Framebuffer\n|Status|Name|\n|:-:|---|\n|🚧|getFrame|\n|🚧|getDisplayFrame|\n|🚧|getDebugFrame|\n|🚧|copyFrameBufferBitmap|\n|🚧|markUpdatedRows|\n|✅|display|\n\n### JSON\nNote: it may not be worth implementing these since we have JSONDecoder.\n\n### Lua\n|Status|Name|\n|:-:|---|\n|🚧|addFunction|\n|🚧|registerClass|\n|🚧|pushFunction|\n|🚧|indexMetatable|\n|🚧|start|\n|🚧|stop|\n|🚧|getArgCount|\n|🚧|getArgCount|\n|🚧|argIsNil|\n|🚧|getArgBool|\n|🚧|getArgInt|\n|🚧|getArgFloat|\n|🚧|getArgString|\n|🚧|getArgBytes|\n|🚧|getArgObject|\n|🚧|getBitmap|\n|🚧|getSprite|\n|🚧|pushNil|\n|🚧|pushBool|\n|🚧|pushInt|\n|🚧|pushFloat|\n|🚧|pushString|\n|🚧|pushBytes|\n|🚧|pushBitmap|\n|🚧|pushSprite|\n|🚧|pushObject|\n|🚧|retainObject|\n|🚧|releaseObject|\n|🚧|setObjectValue|\n|🚧|getObjectValue|\n|🚧|callFunction|\n\n### Scoreboards\nNote: these are not documented anywhere.\n|Status|Name|\n|:-:|---|\n|🚧|addScore|\n|🚧|getPersonalBest|\n|🚧|freeScore|\n|🚧|getScoreboards|\n|🚧|freeBoardsList|\n|🚧|getScores|\n|🚧|freeScoresList|\n\n### Sound\nTODO\n\n### Sprite\n|Status|Name|\n|:-:|---|\n|✅|newSprite|\n|✅|moveTo|\n|✅|moveBy|\n|✅|getPosition|\n|✅|addSprite|\n|✅|setImage|\n|✅|freeSprite|\n|🚧|copy|\n|🚧|setBounds|\n|🚧|getBounds|\n|🚧|getImage|\n|🚧|setSize|\n|🚧|setZIndex|\n|🚧|getZIndex|\n|🚧|setTag|\n|🚧|getTag|\n|🚧|setDrawMode|\n|🚧|setImageFlip|\n|🚧|getImageFlip|\n|🚧|setStencil|\n|🚧|setStencilPattern|\n|🚧|clearStencil|\n|🚧|setClipRect|\n|🚧|clearClipRect|\n|🚧|setClipRectsInRange|\n|🚧|clearClipRectsInRange|\n|🚧|setUpdatesEnabled|\n|🚧|updatesEnabled|\n|🚧|setVisible|\n|🚧|isVisible|\n|🚧|setOpaque|\n|🚧|setAlwaysRedraw|\n|🚧|markDirty|\n|🚧|addDirtyRect|\n|🚧|setIgnoresDrawOffset|\n|🚧|setUpdateFunction|\n|🚧|setDrawFunction|\n|🚧|setUserData|\n|🚧|getUserData|\n|🚧|removeSprite|\n|🚧|removeSprites|\n|🚧|removeAllSprites|\n|🚧|getSpriteCount|\n|🚧|drawSprites|\n|✅|updateAndDrawSprites|\n|🚧|resetCollisionWorld|\n|🚧|setCollisionsEnabled|\n|🚧|collisionsEnabled|\n|🚧|setCollideRect|\n|🚧|getCollideRect|\n|🚧|clearCollideRect|\n|🚧|setCollisionResponseFunction|\n|🚧|checkCollisions|\n|🚧|moveWithCollisions|\n|🚧|querySpritesAtPoint|\n|🚧|querySpritesInRect|\n|🚧|querySpritesAlongLine|\n|🚧|querySpriteInfoAlongLine|\n|🚧|overlappingSprites|\n|🚧|allOverlappingSprites|\n\n### System\n|Status|Name|\n|:-:|---|\n|✅|realloc|\n|✅|error|\n|✅|logToConsole|\n|✅|error|\n\n#### Menu\n|Status|Name|\n|:-:|---|\n|✅|addMenuItem|\n|✅|addCheckmarkMenuItem|\n|✅|addOptionsMenuItem|\n|✅|removeMenuItem|\n|✅|removeAllMenuItems|\n|❌|getMenuItemTitle|\n|❌|getMenuItemValue|\n|❌|setMenuItemValue|\n|❌|getMenuItemUserData|\n|❌|setMenuItemUserData|\n|✅|setMenuImage|\n\n#### Miscellaneous\n|Status|Name|\n|:-:|---|\n|✅|getCurrentTimeMilliseconds|\n|✅|getSecondsSinceEpoch|\n|✅|resetElapsedTime|\n|✅|getElapsedTime|\n|✅|getFlipped|\n|✅|getReduceFlashing|\n|❌|formatString|\n|✅|setUpdateCallback|\n|✅|drawFPS|\n|✅|getBatteryPercentage|\n|✅|getBatteryVoltage|\n|✅|getLanguage|\n|✅|setPeripheralsEnabled|\n|✅|getAccelerometer|\n|✅|getButtonState|\n|✅|getCrankAngle|\n|✅|getCrankChange|\n|✅|getCrankDocked|\n|✅|setAutoLockDisabled|\n|✅|setCrankSoundDisabled|\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fericlewis%2Fswift-playdate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fericlewis%2Fswift-playdate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fericlewis%2Fswift-playdate/lists"}