/tabletopkit
Builds multiplayer spatial board games using TabletopKit on visionOS. Use when creating tabletop game experiences with boards, pieces, cards, or dice; managing seats, turns, equipment state, TabletopAction flows, or TabletopInteraction delegates; synchronizing gameplay through
$ npx -y skills add dpearson2699/swift-ios-skills --skill tabletopkit --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/tabletopkit
Context preview
The summary Claude sees to decide when to auto-load this skill.
Builds multiplayer spatial board games using TabletopKit on visionOS. Use when creating tabletop game experiences with boards, pieces, cards, or dice; managing seats, turns, equipment state, TabletopAction flows, or TabletopInteraction delegates; synchronizing gameplay through
SKILL.md
tabletopkit.SKILL.mdname: tabletopkit
description: "Builds multiplayer spatial board games using TabletopKit on visionOS. Use when creating tabletop game experiences with boards, pieces, cards, or dice; managing seats, turns, equipment state, TabletopAction flows, or TabletopInteraction delegates; synchronizing gameplay through FaceTime Group Activities; rendering with RealityKit; or implementing snapping, tosses, and physics on a virtual table surface."
TabletopKit
Build visionOS board games whose synchronized state changes flow through `TabletopAction` and render with RealityKit. The availability matrix below owns version details.
Contents
- [Setup](#setup)
- [Game Configuration](#game-configuration)
- [Table and Board](#table-and-board)
- [Equipment (Pieces, Cards, Dice)](#equipment-pieces-cards-dice)
- [Player Seats](#player-seats)
- [Game Actions and Turns](#game-actions-and-turns)
- [Interactions](#interactions)
- [RealityKit Rendering](#realitykit-rendering)
- [Group Activities Integration](#group-activities-integration)
- [Common Mistakes](#common-mistakes)
- [Review Checklist](#review-checklist)
- [References](#references)
Setup
| Tier | APIs | |---|---| | visionOS 2.0+ | Core gameplay, equipment, seats, actions, rendering, Group Activities | | visionOS 2.2+ | `TabletopInteraction.Configuration` | | visionOS 26.0+ | Custom actions/state, registration, advanced toss outcomes, discarded-action observation |
Simulator supports single-player layout testing, not multiplayer.
Project Configuration
1. `import TabletopKit` in source files that define game logic. 2. `import RealityKit` for entity-based rendering. 3. For multiplayer, add the **Group Activities** capability in Signing & Capabilities. 4. Provide table, piece, card, and dice USDZ assets in a RealityKit content bundle.
Key Types Overview
| Type | Role | |---|---| | `TabletopGame` | Central game manager; owns setup, actions, observers, rendering | | `TableSetup` | Configuration object passed to `TabletopGame` init | | `Tabletop` / `EntityTabletop` | Protocol for the table surface | | `Equipment` / `EntityEquipment` | Protocol for interactive game pieces | | `TableSeat` / `EntityTableSeat` | Protocol for player seat positions | | `TabletopAction` | Commands that modify game state | | `TabletopInteraction` | Gesture-driven player interactions with equipment | | `TabletopGame.Observer` | Callback protocol for reacting to confirmed actions | | `TabletopGame.RenderDelegate` | Callback protocol for visual updates | | `EntityRenderDelegate` | RealityKit-specific render delegate |
Game Configuration
Build and validate a game in this order:
1. Define the tabletop, equipment, and seats. 2. Configure `TableSetup` and register every custom action type. 3. Create the game, attach its observer and renderer, claim a seat, and establish automatic or manual update handling. 4. Inspect the current snapshot for required equipment IDs, parents, seats, and counters before starting multiplayer. Fix the setup and rebuild if an invariant fails.
import TabletopKit
import RealityKit
let table = GameTable()
var setup = TableSetup(tabletop: table)
setup.add(seat: PlayerSeat(index: 0, pose: seatPose0))
setup.add(seat: PlayerSeat(index: 1, pose: seatPose1))
setup.add(equipment: GamePawn(id: .init(1)))
setup.add(equipment: GameDie(id: .init(2)))
let game = TabletopGame(tableSetup: setup)
game.claimAnySeat()
Call `update(deltaTime:)` each frame if automatic updates are not enabled via the `.tabletopGame(_:parent:automaticUpdate:)` modifier. Read state safely with `withCurrentSnapshot(_:)`.
Table and Board
Tabletop Protocol
Conform to `EntityTabletop` to define the playing surface. Provide a `shape` (round or rectangular) and a RealityKit `Entity` for visual representation.
struct GameTable: EntityTabletop {
var shape: TabletopShape
var entity: Entity
var id: EquipmentIdentifier
init() {
entity = try! Entity.load(named: "table/game_table", in: contentBundle)
shape = .round(entity: entity)
id = .init(0)
}
}Table Shapes
Use factory methods on `TabletopShape`:
// Round table from dimensions
let round = TabletopShape.round(
center: .init(x: 0, y: 0, z: 0),
radius: 0.5,
thickness: 0.05,
in: .meters
)
// Rectangular table from entity
let rect = TabletopShape.rectangular(entity: tableEntity)Equipment (Pieces, Cards, Dice)
Equipment Protocol
All interactive game objects conform to `Equipment` (or `EntityEquipment` for RealityKit-rendered pieces). Each piece has an `id` (`EquipmentIdentifier`) and an `initialState` property.
Choose the state type based on the equipment:
| State Type | Use Case | |---|---| | `BaseEquipmentState` | Generic pieces, pawns, tokens | | `CardState` | Playing cards (tracks `faceUp` / face-down) | | `DieState` | Dice with an integer `value` | | `RawValueState` | Custom data encoded as `UInt64` | | `CustomEquipmentState` | Custom state with a `BaseEquipmentState` plus game data; see the availability matrix |
Defining Equipment
// Pawn -- uses BaseEquipmentState
struct GamePawn: EntityEquipment {
var id: EquipmentIdentifier
var initialState: BaseEquipmentState
var entity: Entity
init(id: EquipmentIdentifier) {
self.id = id
self.entity = try! Entity.load(named: "pieces/pawn", in: contentBundle)
self.initialState = BaseEquipmentState(
parentID: .init(0), seatControl: .any,
pose: .identity, entity: entity
)
}
}
// Card -- uses CardState (tracks faceUp)
struct PlayingCard: EntityEquipment {
var id: EquipmentIdentifier
var initialState: CardState
var entity: Entity
init(id: EquipmentIdentifier) {
self.id = id
self.entity = try! Entity.load(named: "cards/card", in: contentBundle)
self.initialState = .faceDown(
parentID: .init(0), seatControl: .Read more
name: tabletopkit description: "Builds multiplayer spatial board games using TabletopKit on visionOS. Use when creating tabletop game experiences with boards, pieces, cards, or dice; managing seats, turns, equipment state, TabletopAction flows, or TabletopInteraction delegates; synchronizing gameplay through FaceTime Group Activities; rendering with RealityKit; or implementing snapping, tosses, and physics on a virtual table surface."
TabletopKit
Build visionOS board games whose synchronized state changes flow through `TabletopAction` and render with RealityKit. The availability matrix below owns version details.
Contents
- [Setup](#setup)
- [Game Configuration](#game-configuration)
- [Table and Board](#table-and-board)
- [Equipment (Pieces, Cards, Dice)](#equipment-pieces-cards-dice)
- [Player Seats](#player-seats)
- [Game Actions and Turns](#game-actions-and-turns)
- [Interactions](#interactions)
- [RealityKit Rendering](#realitykit-rendering)
- [Group Activities Integration](#group-activities-integration)
- [Common Mistakes](#common-mistakes)
- [Review Checklist](#review-checklist)
- [References](#references)
Setup
| Tier | APIs | |---|---| | visionOS 2.0+ | Core gameplay, equipment, seats, actions, rendering, Group Activities | | visionOS 2.2+ | `TabletopInteraction.Configuration` | | visionOS 26.0+ | Custom actions/state, registration, advanced toss outcomes, discarded-action observation |
Simulator supports single-player layout testing, not multiplayer.
Project Configuration
1. `import TabletopKit` in source files that define game logic. 2. `import RealityKit` for entity-based rendering. 3. For multiplayer, add the **Group Activities** capability in Signing & Capabilities. 4. Provide table, piece, card, and dice USDZ assets in a RealityKit content bundle.
Key Types Overview
| Type | Role | |---|---| | `TabletopGame` | Central game manager; owns setup, actions, observers, rendering | | `TableSetup` | Configuration object passed to `TabletopGame` init | | `Tabletop` / `EntityTabletop` | Protocol for the table surface | | `Equipment` / `EntityEquipment` | Protocol for interactive game pieces | | `TableSeat` / `EntityTableSeat` | Protocol for player seat positions | | `TabletopAction` | Commands that modify game state | | `TabletopInteraction` | Gesture-driven player interactions with equipment | | `TabletopGame.Observer` | Callback protocol for reacting to confirmed actions | | `TabletopGame.RenderDelegate` | Callback protocol for visual updates | | `EntityRenderDelegate` | RealityKit-specific render delegate |
Game Configuration
Build and validate a game in this order:
1. Define the tabletop, equipment, and seats. 2. Configure `TableSetup` and register every custom action type. 3. Create the game, attach its observer and renderer, claim a seat, and establish automatic or manual update handling. 4. Inspect the current snapshot for required equipment IDs, parents, seats, and counters before starting multiplayer. Fix the setup and rebuild if an invariant fails.
import TabletopKit import RealityKit let table = GameTable() var setup = TableSetup(tabletop: table) setup.add(seat: PlayerSeat(index: 0, pose: seatPose0)) setup.add(seat: PlayerSeat(index: 1, pose: seatPose1)) setup.add(equipment: GamePawn(id: .init(1))) setup.add(equipment: GameDie(id: .init(2))) let game = TabletopGame(tableSetup: setup) game.claimAnySeat()
Call `update(deltaTime:)` each frame if automatic updates are not enabled via the `.tabletopGame(_:parent:automaticUpdate:)` modifier. Read state safely with `withCurrentSnapshot(_:)`.
Table and Board
Tabletop Protocol
Conform to `EntityTabletop` to define the playing surface. Provide a `shape` (round or rectangular) and a RealityKit `Entity` for visual representation.
struct GameTable: EntityTabletop {
var shape: TabletopShape
var entity: Entity
var id: EquipmentIdentifier
init() {
entity = try! Entity.load(named: "table/game_table", in: contentBundle)
shape = .round(entity: entity)
id = .init(0)
}
}Table Shapes
Use factory methods on `TabletopShape`:
// Round table from dimensions
let round = TabletopShape.round(
center: .init(x: 0, y: 0, z: 0),
radius: 0.5,
thickness: 0.05,
in: .meters
)
// Rectangular table from entity
let rect = TabletopShape.rectangular(entity: tableEntity)Equipment (Pieces, Cards, Dice)
Equipment Protocol
All interactive game objects conform to `Equipment` (or `EntityEquipment` for RealityKit-rendered pieces). Each piece has an `id` (`EquipmentIdentifier`) and an `initialState` property.
Choose the state type based on the equipment:
| State Type | Use Case | |---|---| | `BaseEquipmentState` | Generic pieces, pawns, tokens | | `CardState` | Playing cards (tracks `faceUp` / face-down) | | `DieState` | Dice with an integer `value` | | `RawValueState` | Custom data encoded as `UInt64` | | `CustomEquipmentState` | Custom state with a `BaseEquipmentState` plus game data; see the availability matrix |
Defining Equipment
// Pawn -- uses BaseEquipmentState
struct GamePawn: EntityEquipment {
var id: EquipmentIdentifier
var initialState: BaseEquipmentState
var entity: Entity
init(id: EquipmentIdentifier) {
self.id = id
self.entity = try! Entity.load(named: "pieces/pawn", in: contentBundle)
self.initialState = BaseEquipmentState(
parentID: .init(0), seatControl: .any,
pose: .identity, entity: entity
)
}
}
// Card -- uses CardState (tracks faceUp)
struct PlayingCard: EntityEquipment {
var id: EquipmentIdentifier
var initialState: CardState
var entity: Entity
init(id: EquipmentIdentifier) {
self.id = id
self.entity = try! Entity.load(named: "cards/card", in: contentBundle)
self.initialState = .faceDown(
parentID: .init(0), seatControl: .86 agent skills optimized for iOS 26+ development with Swift 6.3 and modern Apple frameworks.
Repo: dpearson2699/swift-ios-skills
Other skills on swift-ios-skills.
- /accessorysetupkit
Discover and configure Bluetooth and Wi-Fi accessories using AccessorySetupKit. Use when presenting a privacy-preserving accessory picker, defining discovery descriptors for BLE or Wi-Fi devices, handling accessory session events, migrating from CoreBluetooth permission-based
Open skill - /activitykit
Implement, review, or improve Live Activities and Dynamic Island experiences in iOS apps using ActivityKit. Use when building real-time updating widgets for the Lock Screen and Dynamic Island — delivery tracking, sports scores, ride-sharing status, workout timers, media
Open skill - /adattributionkit
Measure ad effectiveness with privacy-preserving attribution using AdAttributionKit. Use when registering ad impressions, handling attribution postbacks, updating conversion values, implementing re-engagement attribution, configuring publisher or advertiser apps, or replacing
Open skill - /alarmkit
Implement AlarmKit alarms and countdown timers for iOS and iPadOS with Lock Screen, Dynamic Island, StandBy, and paired Apple Watch system UI. Covers AlarmManager scheduling, AlarmAttributes and AlarmPresentation, system Stop and AlarmButton secondary actions, authorization,
Open skill - /app-clips
Build iOS App Clips with invocation URLs, App Clip Codes, NFC, QR codes, Safari banners, Maps, Messages, target setup, App Store Connect experiences, size/capability constraints, NSUserActivity routing, SKOverlay promotion, App Group/keychain handoff, ephemeral notifications,
Open skill - /app-intents
Implement App Intents for Siri, Shortcuts, Spotlight, widgets, Control Center, and Apple Intelligence on iOS. Covers AppIntent actions, AppEntity and EntityQuery models, AppShortcutsProvider phrases, IndexedEntity Spotlight indexing, WidgetConfigurationIntent, SnippetIntent, and
Open skill

