ALWAYS use when the user has any question about game controller input on Apple platforms - whether writing new code, porting from Windows, or modernizing an existing implementation. Trigger when working with the…
---
name: using-game-controller
description: ALWAYS use when the user has any question about game controller input on Apple platforms — whether writing new code, porting from Windows, or modernizing an existing implementation. Trigger when working with the GCController API or GameController framework (controller lifecycle, connect/disconnect, current controller, player index, profile-based input, modern input API, polling, callbacks, haptics, rumble, adaptive triggers, motion/IMU, or on-screen controls), or when porting Windows controller code such as XInput, DirectInput, GameInput, RawInput, joystickapi.h, IOKit HID, IOHIDManager, or HidP_* APIs. Do NOT trigger for keyboard or mouse input.
---
## Overview
A comprehensive guide to Apple's GameController framework - covering Swift/ObjC APIs, platform considerations, and porting from Windows.
Use the GameController framework when writing code for Apple platforms that interacts with game controllers. The `GCController` API presents a common abstraction over gamepad and joystick input devices. The GameController framework supports popular game controllers including the Sony DualSHOCK 4, Sony DualSense, Nintendo Switch Pro, and Microsoft Xbox controllers. Advanced features available on these controllers - IMU, Rumble, and Adaptive Triggers (force feedback) - are supported.
When porting Windows code that calls RawInput (e.g, `RegisterRawInputDevices`) or HID (`HidP_*`) APIs to interfce with Sony, Nintendo, and other non-Xbox controllers, AVOID writing equivalent code that uses IOKit and `IOHIDManager` APIs. PREFER to re-write the code to use the abstractions provided by the `GCController` API instead.
---
## Framework Concepts
* **Device-centric model** - Each `GCController` represents a connected gamepad or joystick device. You obtain the currently connected devices from `GCController.controllers`, listen for new connections (`GCControllerDidConnectNotification`) and disconnections (`GCControllerDidDisconnectNotification`), and monitor for input from the one(s) you are interested in.
* **Component architecture** - Game controller device features are exposed from sub-objects retrieved from the `GCController` object.
- Physical input from control surfaces (buttons, thumbsticks) is accessed through the `GCControllerLiveInput` object returned from the `GCController.input` property (modern API), or through the `GCPhysicalInputProfile` (or subclass thereof) object returned from `GCController.physicalInputProfile` (older profile based API).
- Motion input from an integrated IMU is accessed through the `GCMotion` object returned from the `GCController.motion` property. If this property returns `nil`, the controller does not feature an integrated IMU and does not produce motion input.
- Haptic and rumble commands are sent to a `CHHapticEngine` created from the `GCDeviceHaptics` object returned from `GCController.haptics` property. If this property returns `nil`, the controller does not feature integrated haptic or rumble actuators.
* **Physical Input Hierachy** - Input from buttons, thumbsticks, dpad, etc are nested in a two-level hierarchy. The first level is the element that produces the input (the specific button, thumbstick, or dpad). The second level is the input source. A button typically reports a boolean press state, but may also report a scalar displacement value (e.g, for a trigger). A thumbstick reports X and Y scalar components, and may also report a boolean press state if the thumbstick is clickable. Each is represented as a distinct input nested under the element.
* **Named Input Elements** - Buttons, thumbsticks, dpad, and other physical input elements are looked up by semantic (string) name from `GCControllerLiveInput` or `GCPhysicalInputProfile`. A `GCController` may represent a device with elements beyond those found on an Xbox controller.