Platform: Console
Controller-first design, certification compliance, and locked frame rates define console development.
NEVER Do
- NEVER show a mouse cursor — Certification (TRC/TCR) failure. Hide with
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN).
- NEVER skip pausing on focus loss — Monitor
NOTIFICATION_APPLICATION_FOCUS_OUT and force a pause.
- NEVER let a controller disconnect go unhandled — Force pause and show reconnect UI.
- NEVER use an unlocked frame rate — Lock 30 or 60 FPS via
Engine.max_fps and enable VSync.
- NEVER forget D-Pad navigation — Analog-only menus fail accessibility/TRC. Support D-Pad for all menus.
- NEVER hardcode button labels — Use GUID-based prompt mapping (
controller_prompt_mapper.gd), not "Press A".
- NEVER exceed hardware memory limits — Profile RAM; Switch budgets are rigid.
- NEVER assume Joypad 0 is always Player 1 — Query
Input.get_connected_joypads().
- NEVER distribute console export templates or SDKs publicly — NDA-bound.
- NEVER handle continuous analog sticks with boolean checks — Use
get_vector() / get_action_strength().
- NEVER vibrate continuously without a disable option — Finite
Input.start_joy_vibration() + accessibility toggle.
- NEVER expect OS window APIs on consoles —
DisplayServer.window_set_mode() is ignored/fails.
- NEVER map UI to raw button indices — Use Project Input Map (
ui_accept, ui_cancel, custom actions).
- NEVER rely on
NOTIFICATION_WM_CLOSE_REQUEST for termination — Consoles suspend; handle focus/suspend paths.
- NEVER query inputs without flushing when frame-perfect —
Input.flush_buffered_events() before critical checks.
- NEVER use
== / != on analog trigger axes — Use is_equal_approx().
- NEVER leave orphaned nodes across scene transitions — Strict RAM;
queue_free() and break cycles.
- NEVER write to
res:// at runtime — Use user:// only.
- NEVER save synchronously on the main thread — Offload; atomic
.tmp then rename.
Available Scripts
MANDATORY: Read the appropriate script before implementing the corresponding pattern.
certification_manager.gd
Expert TRC/TCR compliance (focus loss, controller disconnects).
performance_scaler_fsr.gd
Dynamic Resolution Scaling and FSR 2.2 management for console performance.
server_side_projectile.gd
Direct RenderingServer/PhysicsServer bypass for high-frequency objects.
async_save_manager.gd
Atomic, corruption-resistant threaded save system.
controller_prompt_mapper.gd
GUID-based button prompt detection (PlayStation/Xbox/Switch).
memory_budget_guard.gd
Strict RAM monitoring for platform-specific hardware budgets.
platform_dialog_invoker.gd
Native OS dialog and virtual keyboard abstraction.
background_data_prefetcher.gd
Asset pre-fetching using WorkerThreadPool to avoid level-load stutters.
achievement_offline_queue.gd
Achievement/Trophy caching with offline persistence.
console_boot_config.gd
Hardware-aware hardware initialization and rendering overrides.
Certification Golden Path (MANDATORY scripts)
Run this checklist in order for a console-ready vertical slice. Do NOT Load optional scripts unless the row below says optional.
| Step |
MANDATORY script |
Do NOT Load (unless needed) |
| 1. Boot |
console_boot_config.gd |
server_side_projectile.gd — RID bypass, not cert |
| 2. Focus / disconnect |
certification_manager.gd |
— |
| 3. Save atomicity |
async_save_manager.gd |
— |
| 4. FPS / scaler / RAM |
performance_scaler_fsr.gd + memory_budget_guard.gd |
Switch: set ram_limit_mb ≈ 3072 (retail) / warn at 3584; PS/Xbox: 4096–5120 per SKU — see script @export |
| 5. Prompts |
controller_prompt_mapper.gd |
— |
Optional only: achievement_offline_queue.gd, platform_dialog_invoker.gd, background_data_prefetcher.gd. Do NOT Load these during steps 1–5 unless achievements, system dialogs, or prefetch are in scope.
Input Handling (Input Map — not raw indices)
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("ui_accept"):
on_confirm()
elif event.is_action_pressed("ui_cancel"):
on_cancel()
# Prompts: MANDATORY controller_prompt_mapper.gd for face-button glyphs
Expert Techniques
TRC failure → fix (symptom → script → doc)
1. Platform-Overlay-Manager (Native UI Dialogs)
Prefer platform_dialog_invoker.gd / platform_overlay_manager.gd / DisplayServer.dialog_show() for TRC system messages over custom modal stacks.
2. Shader-Binary-Caching (RenderingDevice)
Enable shader/pipeline cache on fixed console GPUs; see console_shader_manager.gd and Official Docs pipeline compilation guidance in Reference.
3. Controller-Battery-Telemetry Hook
Use Input.joy_connection_changed + Input.get_joy_info() via controller_telemetry.gd; battery level often needs a platform GDExtension under NDA.
Deep dives (on demand)
- Joypad snippets, native overlay dialogs, shader cache UUID, controller telemetry → console-cert-patterns.md
Reference
Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.
Official Documentation
- Controllers, gamepads, and joysticks — Joypad indexing, deadzones, get_vector/get_connected_joypads, and why device 0 is never assumed Player 1 on consoles.
- Controller number and vibration — Finite start_joy_vibration durations, connection signals, and haptic accessibility toggles required by TRC/TCR.
- Using InputEvent — Event flow for InputEventJoypadButton/Motion, Input Map actions, and buffered flush before frame-critical checks.
- Custom mouse cursor — Input.set_mouse_mode / hidden cursor so a visible pointer does not fail console certification.
- Handling quit requests — Focus-out / suspend paths versus NOTIFICATION_WM_CLOSE_REQUEST, which consoles often never emit.
- Keyboard, mouse, and controller UI navigation — Focus neighbors and D-Pad/gamepad UI traversal required when analog-only menus fail accessibility/TRC.
- Resolution scaling — Viewport FSR2 / scaling_3d_scale profiles used to hold locked 30/60 FPS on weak SKUs.
- Saving games — user:// persistence, save indicators, and why res:// writes are invalid on exported console builds.
- Background loading — Threaded ResourceLoader prefetch so slow console storage does not hitch level transitions.
- Using multiple threads — WorkerThreadPool offload for atomic saves and prefetch without main-thread TCR frame spikes.
- Feature tags — OS.has_feature / export tags that gate console boot overrides (VSync, max FPS, low-end GI).
- Reducing stutter from shader/pipeline compilations — Shader/pipeline caching on fixed console GPUs to avoid first-use hitch rejections.
Related Skills
Prerequisites
- godot-project-foundations — Project layout, Input Map, and export/user paths before certification hooks and console boot overrides.
- godot-input-handling — Joypad actions, deadzones, and device remapping that controller-first UI and prompt mappers build on.
- godot-gdscript-mastery — Typed notifications, signals, and thread-safe call patterns used by compliance and async save managers.
Complements
Downstream / consumers
- godot-platform-desktop — Dual-ship PC builds that must share Input Map/actions while keeping console mouse-hidden and FPS-locked paths.
- godot-platform-mobile — Shared focus-loss / suspend pause patterns when the same title also targets handhelds.
- godot-multiplayer-networking — Online matchmaking/friends hooks that sit beside achievement queues and platform overlays.
- godot-genre-party — Multi-pad local play that consumes dynamic joypad slot discovery and prompt mapping.
Master
- godot-master — Library router and mirrored module entry for cross-skill discovery.
1---2name: godot-platform-console3description: Expert blueprint for console platforms (PlayStation, Xbox, Nintendo Switch) covering controller-first UI, certification requirements (TRCs/TCRs), platform services (achievements, cloud saves), and performance compliance. Use when targeting console releases or implementing gamepad-only interfaces. Keywords console, PlayStation, Xbox, Switch, TRC, TCR, certification, controller, gamepad, achievements.4---5
6# Platform: Console
7
8Controller-first design, certification compliance, and locked frame rates define console development.
9
10## NEVER Do
11
12- **NEVER show a mouse cursor** — Certification (TRC/TCR) failure. Hide with `Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)`.
13- **NEVER skip pausing on focus loss** — Monitor `NOTIFICATION_APPLICATION_FOCUS_OUT` and force a pause.
14- **NEVER let a controller disconnect go unhandled** — Force pause and show reconnect UI.
15- **NEVER use an unlocked frame rate** — Lock 30 or 60 FPS via `Engine.max_fps` and enable VSync.
16- **NEVER forget D-Pad navigation** — Analog-only menus fail accessibility/TRC. Support D-Pad for all menus.
17- **NEVER hardcode button labels** — Use GUID-based prompt mapping (`controller_prompt_mapper.gd`), not "Press A".
18- **NEVER exceed hardware memory limits** — Profile RAM; Switch budgets are rigid.
19- **NEVER assume Joypad 0 is always Player 1** — Query `Input.get_connected_joypads()`.
20- **NEVER distribute console export templates or SDKs publicly** — NDA-bound.
21- **NEVER handle continuous analog sticks with boolean checks** — Use `get_vector()` / `get_action_strength()`.
22- **NEVER vibrate continuously without a disable option** — Finite `Input.start_joy_vibration()` + accessibility toggle.
23- **NEVER expect OS window APIs on consoles** — `DisplayServer.window_set_mode()` is ignored/fails.
24- **NEVER map UI to raw button indices** — Use Project Input Map (`ui_accept`, `ui_cancel`, custom actions).
25- **NEVER rely on `NOTIFICATION_WM_CLOSE_REQUEST` for termination** — Consoles suspend; handle focus/suspend paths.
26- **NEVER query inputs without flushing when frame-perfect** — `Input.flush_buffered_events()` before critical checks.
27- **NEVER use `==` / `!=` on analog trigger axes** — Use `is_equal_approx()`.
28- **NEVER leave orphaned nodes across scene transitions** — Strict RAM; `queue_free()` and break cycles.
29- **NEVER write to `res://` at runtime** — Use `user://` only.
30- **NEVER save synchronously on the main thread** — Offload; atomic `.tmp` then rename.
31
32---
33
34## Available Scripts
35
36> **MANDATORY**: Read the appropriate script before implementing the corresponding pattern.
37
38### [certification_manager.gd](scripts/certification_manager.gd)
39Expert TRC/TCR compliance (focus loss, controller disconnects).
40
41### [performance_scaler_fsr.gd](scripts/performance_scaler_fsr.gd)
42Dynamic Resolution Scaling and FSR 2.2 management for console performance.
43
44### [server_side_projectile.gd](scripts/server_side_projectile.gd)
45Direct RenderingServer/PhysicsServer bypass for high-frequency objects.
46
47### [async_save_manager.gd](scripts/async_save_manager.gd)
48Atomic, corruption-resistant threaded save system.
49
50### [controller_prompt_mapper.gd](scripts/controller_prompt_mapper.gd)
51GUID-based button prompt detection (PlayStation/Xbox/Switch).
52
53### [memory_budget_guard.gd](scripts/memory_budget_guard.gd)
54Strict RAM monitoring for platform-specific hardware budgets.
55
56### [platform_dialog_invoker.gd](scripts/platform_dialog_invoker.gd)
57Native OS dialog and virtual keyboard abstraction.
58
59### [background_data_prefetcher.gd](scripts/background_data_prefetcher.gd)
60Asset pre-fetching using WorkerThreadPool to avoid level-load stutters.
61
62### [achievement_offline_queue.gd](scripts/achievement_offline_queue.gd)
63Achievement/Trophy caching with offline persistence.
64
65### [console_boot_config.gd](scripts/console_boot_config.gd)
66Hardware-aware hardware initialization and rendering overrides.
67
68---
69
70## Certification Golden Path (MANDATORY scripts)
71
72Run this checklist in order for a console-ready vertical slice. **Do NOT Load** optional scripts unless the row below says optional.
73
74| Step | MANDATORY script | Do NOT Load (unless needed) |
75| :--- | :--- | :--- |
76| 1. Boot | [console_boot_config.gd](scripts/console_boot_config.gd) | [server_side_projectile.gd](scripts/server_side_projectile.gd) — RID bypass, not cert |
77| 2. Focus / disconnect | [certification_manager.gd](scripts/certification_manager.gd) | — |
78| 3. Save atomicity | [async_save_manager.gd](scripts/async_save_manager.gd) | — |
79| 4. FPS / scaler / RAM | [performance_scaler_fsr.gd](scripts/performance_scaler_fsr.gd) + [memory_budget_guard.gd](scripts/memory_budget_guard.gd) | Switch: set `ram_limit_mb` ≈ **3072** (retail) / warn at **3584**; PS/Xbox: **4096–5120** per SKU — see script `@export` |
80| 5. Prompts | [controller_prompt_mapper.gd](scripts/controller_prompt_mapper.gd) | — |
81
82**Optional only:** [achievement_offline_queue.gd](scripts/achievement_offline_queue.gd), [platform_dialog_invoker.gd](scripts/platform_dialog_invoker.gd), [background_data_prefetcher.gd](scripts/background_data_prefetcher.gd). **Do NOT Load** these during steps 1–5 unless achievements, system dialogs, or prefetch are in scope.
83
84## Input Handling (Input Map — not raw indices)
85
86```gdscript
87func _unhandled_input(event: InputEvent) -> void:
88 if event.is_action_pressed("ui_accept"):
89 on_confirm()
90 elif event.is_action_pressed("ui_cancel"):
91 on_cancel()
92 # Prompts: MANDATORY controller_prompt_mapper.gd for face-button glyphs
93```
94
95## Expert Techniques
96
97### TRC failure → fix (symptom → script → doc)
98
99| Symptom | Fix script | Doc |
100| :--- | :--- | :--- |
101| Mouse pointer visible in game UI | Hide via Input Map flow + `Input.MOUSE_MODE_HIDDEN` in boot | [Custom mouse cursor](https://docs.godotengine.org/en/stable/tutorials/inputs/custom_mouse_cursor.html) |
102| Game runs when dashboard/home pressed | [certification_manager.gd](scripts/certification_manager.gd) focus-out pause | [Handling quit requests](https://docs.godotengine.org/en/stable/tutorials/inputs/handling_quit_requests.html) |
103| "Press A" hardcoded on Switch | [controller_prompt_mapper.gd](scripts/controller_prompt_mapper.gd) GUID glyphs | [Controllers, gamepads, and joysticks](https://docs.godotengine.org/en/stable/tutorials/inputs/controllers_gamepads_joysticks.html) |
104| Save corruption on power loss | [async_save_manager.gd](scripts/async_save_manager.gd) `.tmp` rename | [Saving games](https://docs.godotengine.org/en/stable/tutorials/io/saving_games.html) |
105| Frame time spikes / TRC perf fail | [performance_scaler_fsr.gd](scripts/performance_scaler_fsr.gd) + RAM guard | [Resolution scaling](https://docs.godotengine.org/en/stable/tutorials/3d/resolution_scaling.html) |
106
107### 1. Platform-Overlay-Manager (Native UI Dialogs)
108Prefer [platform_dialog_invoker.gd](scripts/platform_dialog_invoker.gd) / [platform_overlay_manager.gd](scripts/platform_overlay_manager.gd) / `DisplayServer.dialog_show()` for TRC system messages over custom modal stacks.
109
110### 2. Shader-Binary-Caching (RenderingDevice)
111Enable shader/pipeline cache on fixed console GPUs; see [console_shader_manager.gd](scripts/console_shader_manager.gd) and Official Docs pipeline compilation guidance in Reference.
112
113### 3. Controller-Battery-Telemetry Hook
114Use `Input.joy_connection_changed` + `Input.get_joy_info()` via [controller_telemetry.gd](scripts/controller_telemetry.gd); battery level often needs a platform GDExtension under NDA.
115
116## Deep dives (on demand)
117
118- Joypad snippets, native overlay dialogs, shader cache UUID, controller telemetry → [console-cert-patterns.md](references/console-cert-patterns.md)
119
120## Reference
121
122> Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.
123
124### Official Documentation
125- [Controllers, gamepads, and joysticks](https://docs.godotengine.org/en/stable/tutorials/inputs/controllers_gamepads_joysticks.html) — Joypad indexing, deadzones, get_vector/get_connected_joypads, and why device 0 is never assumed Player 1 on consoles.
126- [Controller number and vibration](https://docs.godotengine.org/en/stable/tutorials/inputs/controller_features.html) — Finite start_joy_vibration durations, connection signals, and haptic accessibility toggles required by TRC/TCR.
127- [Using InputEvent](https://docs.godotengine.org/en/stable/tutorials/inputs/inputevent.html) — Event flow for InputEventJoypadButton/Motion, Input Map actions, and buffered flush before frame-critical checks.
128- [Custom mouse cursor](https://docs.godotengine.org/en/stable/tutorials/inputs/custom_mouse_cursor.html) — Input.set_mouse_mode / hidden cursor so a visible pointer does not fail console certification.
129- [Handling quit requests](https://docs.godotengine.org/en/stable/tutorials/inputs/handling_quit_requests.html) — Focus-out / suspend paths versus NOTIFICATION_WM_CLOSE_REQUEST, which consoles often never emit.
130- [Keyboard, mouse, and controller UI navigation](https://docs.godotengine.org/en/stable/tutorials/ui/gui_navigation.html) — Focus neighbors and D-Pad/gamepad UI traversal required when analog-only menus fail accessibility/TRC.
131- [Resolution scaling](https://docs.godotengine.org/en/stable/tutorials/3d/resolution_scaling.html) — Viewport FSR2 / scaling_3d_scale profiles used to hold locked 30/60 FPS on weak SKUs.
132- [Saving games](https://docs.godotengine.org/en/stable/tutorials/io/saving_games.html) — user:// persistence, save indicators, and why res:// writes are invalid on exported console builds.
133- [Background loading](https://docs.godotengine.org/en/stable/tutorials/io/background_loading.html) — Threaded ResourceLoader prefetch so slow console storage does not hitch level transitions.
134- [Using multiple threads](https://docs.godotengine.org/en/stable/tutorials/performance/using_multiple_threads.html) — WorkerThreadPool offload for atomic saves and prefetch without main-thread TCR frame spikes.
135- [Feature tags](https://docs.godotengine.org/en/stable/tutorials/export/feature_tags.html) — OS.has_feature / export tags that gate console boot overrides (VSync, max FPS, low-end GI).
136- [Reducing stutter from shader/pipeline compilations](https://docs.godotengine.org/en/stable/tutorials/performance/pipeline_compilations.html) — Shader/pipeline caching on fixed console GPUs to avoid first-use hitch rejections.
137
138### Related Skills
139
140#### Prerequisites
141- [godot-project-foundations](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-project-foundations/SKILL.md) — Project layout, Input Map, and export/user paths before certification hooks and console boot overrides.
142- [godot-input-handling](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-input-handling/SKILL.md) — Joypad actions, deadzones, and device remapping that controller-first UI and prompt mappers build on.
143- [godot-gdscript-mastery](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-gdscript-mastery/SKILL.md) — Typed notifications, signals, and thread-safe call patterns used by compliance and async save managers.
144
145#### Complements
146- [godot-export-builds](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-export-builds/SKILL.md) — Export presets, feature tags, and template discipline (console SDKs stay NDA-bound outside this skill).
147- [godot-save-load-systems](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-save-load-systems/SKILL.md) — Atomic rename, cloud-ready slots, and save UX that TRC save indicators wrap.
148- [godot-ui-containers](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-ui-containers/SKILL.md) — Focusable Control trees and D-Pad neighbor graphs for gamepad-only menus.
149- [godot-performance-optimization](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-performance-optimization/SKILL.md) — Frame budgets, FSR scaling, and Server-side entity patterns that keep locked FPS under TCR.
150- [godot-debugging-profiling](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-debugging-profiling/SKILL.md) — Memory/profiler tabs and monitors used to enforce Switch-class RAM ceilings.
151- [godot-scene-management](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-scene-management/SKILL.md) — Aggressive queue_free / load queues so scene transitions stay inside console RAM budgets.
152- [godot-resource-data-patterns](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-resource-data-patterns/SKILL.md) — Resource caching and unload strategies paired with memory budget guards.
153
154#### Downstream / consumers
155- [godot-platform-desktop](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-platform-desktop/SKILL.md) — Dual-ship PC builds that must share Input Map/actions while keeping console mouse-hidden and FPS-locked paths.
156- [godot-platform-mobile](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-platform-mobile/SKILL.md) — Shared focus-loss / suspend pause patterns when the same title also targets handhelds.
157- [godot-multiplayer-networking](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-multiplayer-networking/SKILL.md) — Online matchmaking/friends hooks that sit beside achievement queues and platform overlays.
158- [godot-genre-party](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-party/SKILL.md) — Multi-pad local play that consumes dynamic joypad slot discovery and prompt mapping.
159
160#### Master
161- [godot-master](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-master/SKILL.md) — Library router and mirrored module entry for cross-skill discovery.