@ericrisco/rsc 0.1.35 → 0.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +8 -2
  2. package/manifest.json +241 -2
  3. package/package.json +1 -1
  4. package/scripts/lib/domains.js +1 -0
  5. package/scripts/lib/recommend.js +4 -0
  6. package/skills/game-design/SKILL.md +170 -0
  7. package/skills/game-design/evals/README.md +13 -0
  8. package/skills/game-design/evals/cases.yaml +47 -0
  9. package/skills/game-design/references/mechanics-and-loops.md +78 -0
  10. package/skills/game-design/references/playtesting-and-scope.md +58 -0
  11. package/skills/game-design/references/progression-and-economy.md +70 -0
  12. package/skills/game-storytelling/SKILL.md +159 -0
  13. package/skills/game-storytelling/evals/README.md +28 -0
  14. package/skills/game-storytelling/evals/cases.yaml +51 -0
  15. package/skills/game-storytelling/references/branching-and-state.md +134 -0
  16. package/skills/game-storytelling/references/dialogue-tools.md +117 -0
  17. package/skills/game-storytelling/references/environmental-storytelling.md +71 -0
  18. package/skills/gamedev-multiplayer/SKILL.md +250 -0
  19. package/skills/gamedev-multiplayer/evals/README.md +12 -0
  20. package/skills/gamedev-multiplayer/evals/cases.yaml +44 -0
  21. package/skills/gamedev-multiplayer/references/godot-high-level-multiplayer.md +133 -0
  22. package/skills/gamedev-multiplayer/references/prediction-and-latency.md +104 -0
  23. package/skills/gamedev-multiplayer/references/unity-and-unreal-netcode.md +166 -0
  24. package/skills/gamedev-pathing/SKILL.md +242 -0
  25. package/skills/gamedev-pathing/evals/README.md +14 -0
  26. package/skills/gamedev-pathing/evals/cases.yaml +49 -0
  27. package/skills/gamedev-pathing/references/navmesh-workflow.md +110 -0
  28. package/skills/gamedev-pathing/references/search-algorithms.md +135 -0
  29. package/skills/gamedev-pathing/references/steering-and-avoidance.md +120 -0
  30. package/skills/gamedev-physics/SKILL.md +225 -0
  31. package/skills/gamedev-physics/evals/README.md +12 -0
  32. package/skills/gamedev-physics/evals/cases.yaml +54 -0
  33. package/skills/gamedev-physics/references/character-controllers.md +120 -0
  34. package/skills/gamedev-physics/references/determinism-and-queries.md +124 -0
  35. package/skills/gamedev-physics/references/layers-and-masks.md +115 -0
  36. package/skills/gamedev-shaders/SKILL.md +252 -0
  37. package/skills/gamedev-shaders/evals/README.md +14 -0
  38. package/skills/gamedev-shaders/evals/cases.yaml +45 -0
  39. package/skills/gamedev-shaders/references/effect-recipes.md +205 -0
  40. package/skills/gamedev-shaders/references/godot-shading-language.md +133 -0
  41. package/skills/gamedev-shaders/references/unity-and-unreal-shaders.md +169 -0
  42. package/skills/gamedev-shipping/SKILL.md +236 -0
  43. package/skills/gamedev-shipping/evals/README.md +9 -0
  44. package/skills/gamedev-shipping/evals/cases.yaml +55 -0
  45. package/skills/gamedev-shipping/references/mobile-and-desktop.md +127 -0
  46. package/skills/gamedev-shipping/references/stores-and-ci.md +162 -0
  47. package/skills/gamedev-shipping/references/web-export-headers.md +140 -0
  48. package/skills/godot/SKILL.md +319 -0
  49. package/skills/godot/evals/README.md +13 -0
  50. package/skills/godot/evals/cases.yaml +50 -0
  51. package/skills/godot/references/export-and-testing.md +102 -0
  52. package/skills/godot/references/gdscript-style.md +84 -0
  53. package/skills/godot/references/godot3-to-4-traps.md +89 -0
  54. package/skills/godot/references/nodes-scenes-resources.md +109 -0
  55. package/skills/level-design/SKILL.md +175 -0
  56. package/skills/level-design/evals/README.md +35 -0
  57. package/skills/level-design/evals/cases.yaml +58 -0
  58. package/skills/level-design/references/blockout-to-art.md +118 -0
  59. package/skills/level-design/references/guidance-and-readability.md +152 -0
  60. package/skills/level-design/references/pacing-and-encounters.md +142 -0
  61. package/skills/roast-me/tools/adapters/__pycache__/__init__.cpython-312.pyc +0 -0
  62. package/skills/roast-me/tools/adapters/__pycache__/base.cpython-312.pyc +0 -0
  63. package/skills/roast-me/tools/adapters/__pycache__/claude.cpython-312.pyc +0 -0
  64. package/skills/roast-me/tools/adapters/__pycache__/codex.cpython-312.pyc +0 -0
  65. package/skills/roast-me/tools/adapters/__pycache__/gemini.cpython-312.pyc +0 -0
  66. package/skills/roast-me/tools/adapters/__pycache__/registry.cpython-312.pyc +0 -0
  67. package/skills/unity/SKILL.md +282 -0
  68. package/skills/unity/evals/README.md +8 -0
  69. package/skills/unity/evals/cases.yaml +43 -0
  70. package/skills/unity/references/build-and-platforms.md +65 -0
  71. package/skills/unity/references/input-system.md +102 -0
  72. package/skills/unity/references/lifecycle-deep-dive.md +75 -0
  73. package/skills/unreal/SKILL.md +270 -0
  74. package/skills/unreal/evals/README.md +12 -0
  75. package/skills/unreal/evals/cases.yaml +45 -0
  76. package/skills/unreal/references/blueprint-cpp-parity.md +109 -0
  77. package/skills/unreal/references/gameplay-framework.md +95 -0
  78. package/skills/unreal/references/packaging.md +83 -0
@@ -0,0 +1,169 @@
1
+ # Unity 6 & Unreal 5.x shaders
2
+
3
+ Depth behind SKILL.md's Unity and Unreal sections.
4
+
5
+ ---
6
+
7
+ ## Unity 6 (URP / HDRP)
8
+
9
+ Unity 6 (6000.x LTS) ships the Scriptable Render Pipeline as the norm: **URP** (Universal) for
10
+ most projects, **HDRP** (High Definition) for high-end PC/console. The retired Built-in RP still
11
+ exists but do not author new shaders for it.
12
+
13
+ ### Choosing the authoring path
14
+
15
+ | Path | When | Notes |
16
+ | --- | --- | --- |
17
+ | **Shader Graph** | Surface looks, VFX, artist iteration | Visual master stack (Vertex + Fragment blocks); URP/HDRP; compiles to HLSL. |
18
+ | **Hand-written HLSL** | Custom lighting, tight control, compute-driven | ShaderLab wrapper + `HLSLPROGRAM` block including URP libraries. |
19
+
20
+ **Surface shaders (`#pragma surface`) do NOT compile under URP/HDRP** — they are a Built-in-RP
21
+ feature. Under SRP write a lit HLSL pass or use Shader Graph.
22
+
23
+ ### Minimal URP unlit HLSL shader
24
+
25
+ ```hlsl
26
+ Shader "Custom/URPUnlitScroll" {
27
+ Properties {
28
+ _BaseMap ("Texture", 2D) = "white" {}
29
+ _Tint ("Tint", Color) = (1,1,1,1)
30
+ _Speed ("Scroll Speed", Float) = 0.1
31
+ }
32
+ SubShader {
33
+ Tags { "RenderPipeline"="UniversalPipeline" "RenderType"="Opaque" }
34
+ Pass {
35
+ HLSLPROGRAM
36
+ #pragma vertex vert
37
+ #pragma fragment frag
38
+ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
39
+
40
+ struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; };
41
+ struct Varyings { float4 positionHCS : SV_POSITION; float2 uv : TEXCOORD0; };
42
+
43
+ TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);
44
+ CBUFFER_START(UnityPerMaterial)
45
+ float4 _BaseMap_ST; float4 _Tint; float _Speed;
46
+ CBUFFER_END
47
+
48
+ Varyings vert (Attributes IN) {
49
+ Varyings o;
50
+ o.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); // NOT UnityObjectToClipPos
51
+ o.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
52
+ return o;
53
+ }
54
+ half4 frag (Varyings IN) : SV_Target {
55
+ float2 uv = IN.uv + float2(_Time.y * _Speed, 0);
56
+ return SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv) * _Tint;
57
+ }
58
+ ENDHLSL
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ For a **lit** pass add `#include ".../Lighting.hlsl"`, compute normals in world space, and call
65
+ `UniversalFragmentPBR` / light loops. `mul(UNITY_MATRIX_MVP, v)` and `UnityObjectToClipPos` are
66
+ Built-in-RP idioms — never emit them for URP.
67
+
68
+ ### Shader Graph mapping (concepts)
69
+
70
+ - **Master stack** = Vertex block (Position/Normal/Tangent) + Fragment block (Base Color, Metallic,
71
+ Smoothness, Emission, Alpha, Normal (Tangent Space)).
72
+ - Time node → scrolling; Fresnel Effect node → rim; Sample Texture 2D → maps; Step/Smoothstep →
73
+ toon banding; Scene Color / Scene Depth nodes need the URP opaque texture / depth toggles on.
74
+ - **Custom Function node** embeds an `.hlsl` snippet inside the graph (the Shader Graph analog of
75
+ UE's Custom node).
76
+
77
+ ### Runtime parameters
78
+
79
+ `Material.SetFloat/SetColor/SetTexture`, or a `MaterialPropertyBlock` on the renderer for
80
+ per-instance values without new material instances. Enable keyword variants with `#pragma
81
+ multi_compile` / `shader_feature` and `Material.EnableKeyword`.
82
+
83
+ ### Full-screen / post-process (URP)
84
+
85
+ Add a **Full Screen Pass Renderer Feature** to the URP Renderer and point it at a *Fullscreen*
86
+ Shader Graph (Fullscreen master) or a Blit material. HDRP uses a Custom Pass Volume / Fullscreen
87
+ Custom Pass. `OnRenderImage`/`Graphics.Blit` image effects are Built-in-RP only.
88
+
89
+ ---
90
+
91
+ ## Unreal 5.x
92
+
93
+ A **Material** is a node graph compiled to HLSL. Targets UE 5.4+.
94
+
95
+ ### Result-node outputs
96
+
97
+ Base Color, Metallic, Specular, Roughness, Anisotropy, Emissive Color, Opacity, Opacity Mask,
98
+ Normal, World Position Offset, Ambient Occlusion, Refraction, Pixel Depth Offset. Which are active
99
+ depends on the Blend Mode and Shading Model.
100
+
101
+ ### Material Domain — pick what it drives
102
+
103
+ | Domain | Use |
104
+ | --- | --- |
105
+ | **Surface** | Standard meshes (default). |
106
+ | **Deferred Decal** | Projected decals onto the g-buffer. |
107
+ | **Light Function** | Modulates a light's contribution. |
108
+ | **Volume** | Volumetric fog/clouds. |
109
+ | **Post Process** | Full-screen effect on a Post Process Volume (see below). |
110
+ | **User Interface** | UMG widget materials. |
111
+
112
+ **Blend Mode**: Opaque / Masked (uses Opacity Mask + a mask clip value) / Translucent (uses
113
+ Opacity) / Additive / Modulate. **Shading Model**: Default Lit / Unlit / Subsurface / Clear Coat /
114
+ Two Sided Foliage / Hair / Eye / Cloth / Single Layer Water.
115
+
116
+ Match the pin to the mode: Opacity needs Translucent/Additive; Opacity Mask needs Masked; feeding
117
+ the wrong one is a silent no-op.
118
+
119
+ ### Custom HLSL node
120
+
121
+ The escape hatch when the node set can't express the logic (loops, bitwise, custom math). Set the
122
+ node's **Output Type**, add named **Inputs** (they become HLSL variables), write HLSL, `return`:
123
+
124
+ ```hlsl
125
+ // Inputs: Time (Scalar), UV (Vector2), Freq (Scalar). Output Type: CMOT Float3.
126
+ float scan = 0.5 + 0.5 * sin(UV.y * Freq + Time * 6.2831);
127
+ float rim = pow(1.0 - saturate(dot(normalize(V), normalize(N))), 3.0); // wire V,N as inputs
128
+ return float3(scan, scan, scan) * rim;
129
+ ```
130
+
131
+ Prefer graph nodes for anything nodes *can* express — Custom nodes block constant-folding and
132
+ some cross-platform optimizations. Reuse shared logic via **Material Functions**.
133
+
134
+ ### Material Instances
135
+
136
+ Mark parameters (right-click a constant → *Convert to Parameter*): Scalar, Vector, Texture,
137
+ StaticSwitch. A **Material Instance Constant** is an authored variant; a **Dynamic Material
138
+ Instance** (`CreateDynamicMaterialInstance`) is set at runtime:
139
+
140
+ ```cpp
141
+ UMaterialInstanceDynamic* MID = Mesh->CreateDynamicMaterialInstance(0, BaseMat);
142
+ MID->SetScalarParameterValue("Dissolve", 0.7f);
143
+ MID->SetVectorParameterValue("EdgeColor", FLinearColor(1, 0.4f, 0));
144
+ ```
145
+
146
+ Static switches compile out branches into variants; use them for feature toggles rather than a
147
+ runtime `if`.
148
+
149
+ ### Post-process material
150
+
151
+ Set Material Domain = **Post Process**, add it to a **Post Process Volume** (or camera). Read the
152
+ frame with **SceneTexture** nodes — `PostProcessInput0` (scene color), `SceneDepth`, world normal,
153
+ custom-depth/custom-stencil for masking specific actors. **Blendable Location** (Before/After
154
+ Tonemapping, etc.) sets ordering; SceneTexture nodes only work in this domain.
155
+
156
+ ---
157
+
158
+ ## Godot ↔ Unity ↔ Unreal quick map
159
+
160
+ | Concept | Godot 4 | Unity URP | Unreal 5 |
161
+ | --- | --- | --- | --- |
162
+ | Color output | `ALBEDO` / `EMISSION` | Base Color / Emission block | Base Color / Emissive Color |
163
+ | Alpha cutout | `discard` / `ALPHA_SCISSOR_THRESHOLD` | `clip()` / Alpha Clip Threshold | Opacity Mask (Masked) |
164
+ | Fresnel/rim | `1 - dot(NORMAL, VIEW)` | Fresnel Effect node | Fresnel node |
165
+ | Screen color | `hint_screen_texture` | Scene Color node / opaque texture | SceneTexture: PostProcessInput0 |
166
+ | Scene depth | `hint_depth_texture` | Scene Depth node | SceneTexture: SceneDepth |
167
+ | Time | `TIME` | Time node / `_Time.y` | Time node |
168
+ | Runtime param | `set_shader_parameter` | `Material.SetFloat` | `SetScalarParameterValue` (MID) |
169
+ | Full-screen FX | ColorRect + `hint_screen_texture` / CompositorEffect | Full Screen Pass Renderer Feature | Post Process material + volume |
@@ -0,0 +1,236 @@
1
+ ---
2
+ name: gamedev-shipping
3
+ description: "Use when exporting, building, packaging, or publishing a game — per engine (Godot export templates, Unity Build Profiles, Unreal Shipping vs Development) and per platform: desktop (Windows/macOS/Linux; macOS codesign + notarytool notarization), web (the COOP same-origin + COEP require-corp headers threaded SharedArrayBuffer WebAssembly builds need, and that Godot's C#/.NET edition can't export to web), mobile (Android JDK 17 build template, AAB vs APK, release keystore; iOS provisioning). Also store prep (icons/splash, metadata, age ratings, AAB for Play, Mac App Store, Steamworks/SteamPipe, itch.io butler), headless-export CI/CD, build/version numbers, and ship-time size/startup optimization. Triggers: 'export my game', 'build for Steam', 'ship to web/mobile', 'publish to the Play Store', 'notarize my Mac build', 'itch.io upload', 'SharedArrayBuffer is not defined'. NOT for writing gameplay/runtime code (that's the engine skill — godot/unity/unreal) or hosting a normal web app/API/container (→ deployment)."
4
+ tags: [export, build, release, packaging, store, steam, itch, notarization, webassembly, aab]
5
+ recommends: [godot, unity, unreal, deployment]
6
+ profiles: [full]
7
+ origin: risco
8
+ ---
9
+
10
+ # Ship the game — export, build & release (per engine · per platform)
11
+
12
+ Take a finished project from editor → signed, correctly-configured artifact → live on the
13
+ right target (desktop / web / mobile / store), with the platform gotchas that silently break a
14
+ build handled up front. This skill owns the *packaging and release boundary*; the engine skills
15
+ own the code that runs inside the artifact.
16
+
17
+ ```text
18
+ project ──[engine export/build]──▶ artifact ──[per-platform sign/config]──▶ target
19
+ Godot templates·Unity Build Profiles·Unreal Shipping desktop·web·mobile Steam·Play·App Store·itch
20
+ ```
21
+
22
+ ## Version anchors (what "current" means here — July 2026)
23
+
24
+ | Tool | Target | Ship note |
25
+ | --- | --- | --- |
26
+ | Godot | 4.5 stable (4.6 dev) | Export templates must match the editor build **exactly** (4.5.1 editor ⇒ 4.5.1 templates). **C#/.NET edition has NO web export** — GDScript/standard only. |
27
+ | Unity | Unity 6 (6000.x) | "Build Settings" is now **Build Profiles**. IL2CPP backend for iOS/Android/WebGL. |
28
+ | Unreal | 5.6 | Ship in the **Shipping** config; test packaged builds in **Development**. |
29
+ | Android | JDK **17**, target a recent API level | AAB required for Google Play (new apps + updates). APK only for sideload/itch/direct. |
30
+ | iOS/macOS | Xcode 16+, `notarytool` | `altool` notarization is dead — use `xcrun notarytool`. |
31
+
32
+ ## When to use / When NOT to use
33
+
34
+ **Use when:**
35
+ - Configuring export templates / build presets / packaging settings for any target.
36
+ - Signing & notarizing a desktop build, or debugging Gatekeeper/SmartScreen rejections.
37
+ - Fixing a web build that boots to `SharedArrayBuffer is not defined` or a blank canvas.
38
+ - Producing an AAB/APK or an iOS archive; wiring keystores/provisioning.
39
+ - Store submission prep (icons, metadata, ratings) or uploading to Steam/itch/Play/App Store.
40
+ - Automating headless exports in CI, or setting version/build numbers.
41
+ - Shrinking build size / startup time before release.
42
+
43
+ **NOT for (route elsewhere, say so, stop):**
44
+ - Writing gameplay, shaders, netcode, or any runtime logic → the **engine** skill (`godot`/`unity`/`unreal`) or `gamedev-shaders`/`gamedev-multiplayer`. This skill packages code; it does not write it.
45
+ - Hosting a normal web app, API, or container (Dockerfile, Coolify, Vercel, VPS) → **`deployment`**. A WebAssembly game is *static files*; only its **headers** are special (below).
46
+ - Designing game feel, economy, or narrative → `game-design` / `game-storytelling`.
47
+
48
+ ## Decision rules (settle these before touching a build)
49
+
50
+ | Question | Rule |
51
+ | --- | --- |
52
+ | Web build uses threads / SharedArrayBuffer? | You **must** serve `COOP: same-origin` + `COEP: require-corp` (cross-origin isolation). No headers ⇒ no threads ⇒ boot failure. |
53
+ | Godot + C# + web? | **Impossible today.** Switch to GDScript for web, or ship that title desktop/mobile only. |
54
+ | Play Store? | **AAB**, signed with an upload key, Play App Signing on. Not APK. |
55
+ | macOS distribution outside the App Store? | codesign (Developer ID) → **notarize** → **staple**. Skipping = Gatekeeper blocks it. |
56
+ | Mac **App Store**? | Different cert (Apple Distribution) + sandbox entitlements; notarization is automatic, not manual. |
57
+ | Steam? | SteamPipe upload via `steamcmd` + an `app_build` VDF; set the default branch live in the partner site. |
58
+ | Quick public build / demo / jam? | **itch.io** + `butler push`. Tick "SharedArrayBuffer support" for threaded web builds. |
59
+ | Release config? | Godot **release** preset (debug off), Unity release/**IL2CPP**, Unreal **Shipping**. Never ship a debug/Development build. |
60
+
61
+ ## Export / build per engine
62
+
63
+ **Godot** — `Editor ▸ Manage Export Templates` (match version), then `Project ▸ Export`, add one
64
+ preset per platform. Headless for CI:
65
+
66
+ ```bash
67
+ godot --headless --export-release "Windows Desktop" build/game.exe
68
+ godot --headless --export-release "Web" build/index.html
69
+ # Android AAB needs the Gradle build template + JDK 17 + a release keystore (see references)
70
+ ```
71
+
72
+ Web preset toggles: **Thread Support** (⇒ needs COOP/COEP) and **Extensions Support**. Android
73
+ needs `Project ▸ Install Android Build Template` (enables *Use Gradle Build*).
74
+
75
+ **Unity** — `File ▸ Build Profiles` (formerly Build Settings). Create a profile per platform;
76
+ override **Player Settings** per profile (company/product name, bundle id, icons, scripting
77
+ backend). iOS/Android/WebGL force **IL2CPP**. CI headless:
78
+
79
+ ```bash
80
+ Unity -quit -batchmode -nographics -projectPath . \
81
+ -buildTarget Android -executeMethod BuildScript.PerformBuild -logFile -
82
+ ```
83
+
84
+ Android: tick **Build App Bundle (Google Play)** for AAB; set the keystore in *Publishing Settings*.
85
+ WebGL: threads ⇒ COOP/COEP; keep **decompression fallback** for hosts that can't set gzip/br headers.
86
+
87
+ **Unreal** — build **configurations**, not "modes": Debug, DebugGame, **Development** (test packaged
88
+ builds — keeps logs/console), Test, **Shipping** (release — strips logging, most optimized). Package
89
+ via `Platforms ▸ <target> ▸ Package Project`, the Project Launcher, or UAT for CI:
90
+
91
+ ```bash
92
+ RunUAT BuildCookRun -project="Game.uproject" -platform=Win64 \
93
+ -clientconfig=Shipping -cook -stage -pak -package -archivedirectory=build
94
+ ```
95
+
96
+ Android adds `-distribution` for an AAB; iOS requires a Mac + provisioning. Run the platform
97
+ **Turnkey**/SDK setup once (Android Studio + NDK, or Xcode) or the cook fails.
98
+
99
+ → full per-engine preset/flag tables: `references/mobile-and-desktop.md` and `references/stores-and-ci.md`.
100
+
101
+ ## Per-platform
102
+
103
+ ### Desktop (Windows / macOS / Linux) — the simplest path
104
+
105
+ | OS | Sign? | Gotcha |
106
+ | --- | --- | --- |
107
+ | Windows | Optional (Authenticode; EV avoids SmartScreen warm-up) | Unsigned still runs but SmartScreen warns; ship `.exe` + engine data next to it, or an installer. |
108
+ | Linux | No | Ship binary + data, or wrap as **AppImage**/**Flatpak** for a portable single file. |
109
+ | macOS | **Required** | Must codesign (Developer ID Application) **+ notarize + staple**, or Gatekeeper refuses to open it. |
110
+
111
+ macOS notarization (the step everyone forgets):
112
+
113
+ ```bash
114
+ codesign --deep --force --timestamp --options runtime \
115
+ --sign "Developer ID Application: Studio (TEAMID)" Game.app
116
+ ditto -c -k --keepParent Game.app Game.zip
117
+ xcrun notarytool submit Game.zip --keychain-profile "AC" --wait # store creds once via store-credentials
118
+ xcrun stapler staple Game.app # staple so it verifies offline
119
+ ```
120
+
121
+ `--options runtime` (Hardened Runtime) is **mandatory** for notarization. Codesign every bundled
122
+ `.dylib`/helper *before* the outer `.app`, inside-out.
123
+
124
+ ### Web — the header trap (read this before blaming your build)
125
+
126
+ Threaded WebAssembly builds (Godot with Thread Support, Unity WebGL with threads) use
127
+ **`SharedArrayBuffer`**, which browsers gate behind **cross-origin isolation**. The server must send:
128
+
129
+ ```
130
+ Cross-Origin-Opener-Policy: same-origin
131
+ Cross-Origin-Embedder-Policy: require-corp
132
+ ```
133
+
134
+ Missing them ⇒ `SharedArrayBuffer is not defined`, a hang, or a blank canvas — even though the
135
+ files are fine. Where to set them:
136
+
137
+ - **Netlify** `_headers`, **Vercel** `vercel.json` headers, **nginx** `add_header` — set both on the game path.
138
+ - **itch.io** — tick **"This file will be played in the browser" ▸ SharedArrayBuffer support**; itch sets the headers for you.
139
+ - **GitHub Pages** — **cannot** set headers. Use a non-threaded export, or the `coi-serviceworker` shim (a service worker that re-serves with the headers).
140
+
141
+ `COEP: require-corp` also means every cross-origin subresource (fonts, analytics, embeds) must
142
+ send CORP/CORS or it's blocked. **Godot C#/.NET has no web export at all** — use GDScript.
143
+
144
+ → hosts, exact configs, the service-worker shim, self-test: `references/web-export-headers.md`.
145
+
146
+ ### Mobile
147
+
148
+ **Android** — needs **JDK 17** and the engine's Gradle build template. Ship **AAB** to Play
149
+ (Google re-signs and generates per-device APKs), **APK** for sideload/itch/direct. Generate a
150
+ release keystore once and reuse it forever (lose it = you can't update the app without Play App
151
+ Signing key reset):
152
+
153
+ ```bash
154
+ keytool -genkey -v -keystore release.keystore -alias game \
155
+ -keyalg RSA -keysize 2048 -validity 10000
156
+ ```
157
+
158
+ Keep the keystore + passwords out of git (CI secret). `versionCode` must increase every upload.
159
+
160
+ **iOS** — Mac + Xcode + Apple Developer account. Bundle ID must match an **App ID**; pick a
161
+ **provisioning profile** (development / ad-hoc / App Store) and a signing certificate. Archive,
162
+ then upload to App Store Connect / TestFlight via Xcode Organizer or **Transporter**. `CFBundleVersion`
163
+ must increase per upload.
164
+
165
+ → full keystore, Play App Signing, provisioning, TestFlight walkthrough: `references/mobile-and-desktop.md`.
166
+
167
+ ## Store prep
168
+
169
+ - **Assets**: platform icons (Android adaptive, iOS icon set, Windows `.ico`, macOS `.icns`), splash/launch, store screenshots per device class, a trailer where required.
170
+ - **Metadata**: title, short + full description, keywords, category, support/privacy URLs, localized strings.
171
+ - **Age ratings**: fill the **IARC** questionnaire (Play, Microsoft, Nintendo) or ESRB/PEGI/USK; Apple has its own age-rating questionnaire. Wrong answers = removal.
172
+ - **Google Play**: AAB + **Play App Signing**, a recent **target API level**, content rating, and the **Data safety** form.
173
+ - **Steam**: Steamworks partner + appid; define **depots**; upload with **SteamPipe** (`steamcmd +run_app_build app_build_APPID.vdf`); store page assets; set the branch live.
174
+ - **itch.io**: `butler push build/ user/game:channel --userversion 1.2.3` — channel name (e.g. `windows`, `html5`) picks the platform.
175
+ - **Mac App Store**: Apple Distribution cert + App Sandbox entitlements (not Developer ID); notarization is handled by App Store submission.
176
+
177
+ → Steamworks/SteamPipe VDF, butler channels, Play/App Store checklists: `references/stores-and-ci.md`.
178
+
179
+ ## CI/CD for builds
180
+
181
+ Headless export in GitHub Actions; version from the run/commit so every artifact is traceable.
182
+
183
+ - **Godot**: run in a container that bundles matching export templates (e.g. a `barichello/godot-ci`-style image), `godot --headless --export-release`.
184
+ - **Unity**: `game-ci/unity-builder` + a license activation step (secrets); matrix over targets.
185
+ - **Unreal**: needs a **self-hosted runner** with the engine installed (multi-GB); UAT `BuildCookRun`.
186
+ - **Signing in CI**: import the keystore/cert from an encrypted secret at runtime, never commit it. macOS notarization runs on a `macos-latest` runner with `notarytool` + an App Store Connect API key.
187
+ - **Versioning**: semver tag for releases; a monotonic build number from `github.run_number` or the git commit count feeds `versionCode`/`CFBundleVersion`/Steam build description.
188
+
189
+ → ready workflows per engine: `references/stores-and-ci.md`.
190
+
191
+ ## Ship-time optimization
192
+
193
+ - **Texture compression per platform**: ASTC (mobile), BCn/DXT (desktop), ETC2 (GLES fallback). Set per-platform import overrides — never ship uncompressed PNGs to mobile.
194
+ - **Strip the fat**: Unity **Managed Stripping Level: High** + IL2CPP; Unreal **Shipping** drops logs/console; Godot — export only used resources and disable unused modules in a custom template.
195
+ - **Startup**: small boot scene, stream/preload heavy assets, compress the `.pck`/data, use Ogg Vorbis over WAV. Web: enable gzip/brotli on `.wasm`/`.pck`.
196
+ - **Budgets**: set a per-platform size budget (web especially — every MB is download latency) and check the final artifact against it before submitting.
197
+
198
+ ## Anti-patterns — rationalization → STOP
199
+
200
+ | Rationalization | STOP — do this instead |
201
+ | --- | --- |
202
+ | "Web build works locally, host later" | Set COOP/COEP now; `file://`/simple servers hide the `SharedArrayBuffer` failure. |
203
+ | "I'll add C# web export for Godot" | It doesn't exist in 4.x. GDScript for web, or no web. |
204
+ | "Notarization is optional" | On macOS, no notarize+staple = Gatekeeper blocks the app for every user. |
205
+ | "Ship an APK to the Play Store" | Play requires **AAB** for new apps and updates. |
206
+ | "Commit the keystore so CI can sign" | Keystore/cert live in encrypted CI secrets, never in git. |
207
+ | "Ship the Development/Debug config" | Ship Godot release / Unity IL2CPP release / Unreal **Shipping** — debug leaks console + is slow. |
208
+ | "Templates are close enough (4.5 vs 4.5.1)" | Godot templates must match the editor build exactly or export breaks. |
209
+ | "Uncompressed textures are fine" | Per-platform compression (ASTC/BCn/ETC2) — raw textures blow memory + size. |
210
+ | "Reuse an old versionCode/CFBundleVersion" | Both must strictly increase or the store rejects the upload. |
211
+
212
+ ## Related skills
213
+
214
+ - `godot`, `unity`, `unreal` — write the game; this skill exports/ships what they build. Draw the line at the export button.
215
+ - `deployment` — Docker/CI/hosting for **web apps & APIs**; borrow its GitHub Actions + header-setting patterns, but a WebAssembly game is static files, not a container.
216
+ - `gamedev-shaders`, `gamedev-multiplayer`, `gamedev-physics` — runtime subsystems packaged into the ship artifact, not configured here.
217
+ - `secure-coding` — signing-key and secret handling this skill assumes for keystores/certs in CI.
218
+
219
+ ## Checklist
220
+
221
+ - [ ] Release/Shipping config, not Debug/Development.
222
+ - [ ] (Godot) export templates match the editor version exactly.
223
+ - [ ] (Web, threaded) COOP `same-origin` + COEP `require-corp` served; boots without `SharedArrayBuffer` errors.
224
+ - [ ] (Godot + web) confirmed GDScript, not C#/.NET.
225
+ - [ ] (macOS) codesigned (Hardened Runtime) + notarized + stapled.
226
+ - [ ] (Android) AAB for Play, JDK 17, release keystore in CI secrets, `versionCode` bumped.
227
+ - [ ] (iOS) provisioning profile + signing cert correct, `CFBundleVersion` bumped.
228
+ - [ ] Store assets: icons, splash, screenshots, metadata, age rating done.
229
+ - [ ] Version/build number set from CI and traceable.
230
+ - [ ] Textures compressed per platform; build size within budget.
231
+
232
+ ## References
233
+
234
+ - `references/web-export-headers.md` — cross-origin isolation deep dive: COOP/COEP per host (Netlify/Vercel/nginx/itch/GitHub Pages), the `coi-serviceworker` shim, COEP subresource fallout, self-test snippet, Godot vs Unity web specifics.
235
+ - `references/mobile-and-desktop.md` — Android keystore + Gradle template + Play App Signing; iOS provisioning/TestFlight; full macOS codesign→notarytool→staple; Windows Authenticode; Linux AppImage/Flatpak.
236
+ - `references/stores-and-ci.md` — Steamworks/SteamPipe VDF upload, itch.io butler channels, Play/App Store submission checklists, and per-engine GitHub Actions headless-build workflows with signing.
@@ -0,0 +1,9 @@
1
+ # Evals — gamedev-shipping
2
+
3
+ These cases assert the skill fires on export/build/package/publish requests across engines
4
+ (Godot/Unity/Unreal) and platforms (desktop/web/mobile/store), and that it stays out of runtime
5
+ code (routes gameplay → engine skills, netcode → gamedev-multiplayer) and normal web-app hosting
6
+ (→ deployment). The capability scenarios check the load-bearing, version-correct facts: the
7
+ COOP/COEP cross-origin-isolation headers for threaded web builds, the macOS
8
+ codesign→notarytool→stapler chain, the Android JDK 17 + AAB + keystore release path, and the
9
+ Godot C#/.NET "no web export" limitation.
@@ -0,0 +1,55 @@
1
+ skill: gamedev-shipping
2
+
3
+ should_trigger:
4
+ - prompt: "My Godot game runs in the editor but the exported web build just shows a black screen and the console says 'SharedArrayBuffer is not defined'. How do I host it?"
5
+ why: "The signature web-ship failure: threaded WebAssembly needs COOP same-origin + COEP require-corp headers set at the host — core web-export-headers scope."
6
+ - prompt: "How do I export and package my Unity 6 project as an AAB for the Google Play Store and sign it?"
7
+ why: "Per-engine (Unity Build Profiles) + per-platform Android AAB vs APK + release keystore signing — squarely this skill's packaging boundary."
8
+ - prompt: "I built my macOS game but users get a 'can't be opened because Apple cannot check it for malware' warning. What do I need to do before distributing it?"
9
+ why: "macOS Gatekeeper rejection → the codesign (Hardened Runtime) + notarytool + stapler chain this skill owns."
10
+ - prompt: "Set up a GitHub Actions workflow that headless-exports my Godot game for web and Linux on every tag and uploads the artifacts."
11
+ why: "Headless-export CI/CD with matching export templates and version numbering — the CI section and stores-and-ci reference."
12
+ - prompt: "I'm ready to publish to Steam. How do I upload my build with SteamPipe and push it to a beta branch first?"
13
+ why: "Steamworks/SteamPipe VDF upload via steamcmd and branch promotion — store-prep scope."
14
+ - prompt: "What's the difference between Development and Shipping when packaging my Unreal game, and which do I use for release?"
15
+ why: "Unreal build-configuration choice for release packaging — per-engine export/build scope (Shipping vs Development)."
16
+ - prompt: "Can I export my Godot C# project to the web? It keeps failing."
17
+ why: "The known limitation: Godot's C#/.NET edition has no web export in 4.x — this skill must state that and route the user (GDScript or non-web target)."
18
+ - prompt: "Push my HTML5 and Windows builds to itch.io with butler and bump the version."
19
+ why: "itch.io butler channels + userversion, plus the SharedArrayBuffer support checkbox for web — store-prep scope."
20
+
21
+ should_not_trigger:
22
+ - prompt: "Add double-jump and coyote-time to my player controller in Godot."
23
+ route_to: "godot"
24
+ why: "Gameplay/runtime code is the engine skill's job; this skill only packages and ships what the engine produces."
25
+ - prompt: "Write a Dockerfile and Coolify config to deploy my Next.js web app with a Postgres database."
26
+ route_to: "deployment"
27
+ why: "Hosting a normal containerized web app/API is deployment's domain; a game ship is static WASM files or a native binary, not a container."
28
+ - prompt: "My multiplayer game has rubber-banding; how do I add client-side prediction and server reconciliation?"
29
+ route_to: "gamedev-multiplayer"
30
+ why: "Netcode runtime behavior, not build/release — belongs to the multiplayer skill."
31
+ - prompt: "Help me design the progression curve and reward economy for my roguelike."
32
+ route_to: "game-design"
33
+ why: "Game feel/economy design is not an export or packaging task."
34
+ - prompt: "Optimize this fragment shader that's tanking my frame rate on mobile."
35
+ route_to: "gamedev-shaders"
36
+ why: "Runtime rendering performance is a shader-authoring concern, distinct from ship-time build-size/startup optimization."
37
+
38
+ capability:
39
+ - scenario: "User's threaded Godot 4 web export fails with 'SharedArrayBuffer is not defined' and they plan to host it on Netlify (and later ask about GitHub Pages)."
40
+ must_include:
41
+ - "Explains threaded WASM needs cross-origin isolation via BOTH Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp response headers"
42
+ - "Gives the Netlify _headers (or equivalent) config setting both headers, and notes itch.io's SharedArrayBuffer checkbox as an alternative"
43
+ - "Notes GitHub Pages can't set headers, so use a single-threaded export or the coi-serviceworker shim"
44
+ - "Mentions self.crossOriginIsolated === true as the verification check"
45
+ - "Warns that Godot's C#/.NET edition has no web export in 4.x (only GDScript/standard)"
46
+ - scenario: "User wants to ship a signed macOS desktop build for distribution outside the App Store."
47
+ must_include:
48
+ - "codesign with --options runtime (Hardened Runtime is mandatory for notarization) using a Developer ID Application identity"
49
+ - "Submit with xcrun notarytool submit --wait (not the deprecated altool)"
50
+ - "Staple the ticket with xcrun stapler staple so it verifies offline, and that skipping notarization means Gatekeeper blocks it"
51
+ - scenario: "User asks how to produce and sign an Android release for Google Play from Unity."
52
+ must_include:
53
+ - "Requires JDK 17 and building an AAB (not APK) for Google Play"
54
+ - "Generate/keep a release keystore (keytool) and never commit it; use Play App Signing"
55
+ - "versionCode must strictly increase on every upload"
@@ -0,0 +1,127 @@
1
+ # Mobile & desktop — signing, keystores, provisioning, notarization
2
+
3
+ Back to the entrypoint: `../SKILL.md`. The per-OS steps that gate a shippable build.
4
+
5
+ ## Android
6
+
7
+ ### Toolchain
8
+
9
+ - **JDK 17** — the version the current Gradle build template expects. JDK 21 or 11 breaks the
10
+ build with cryptic Gradle errors. Point the engine's Android settings at a JDK 17 home.
11
+ - **Android SDK + build-tools + platform-tools**; NDK for native/IL2CPP.
12
+ - Godot: `Project ▸ Install Android Build Template`, then tick **Use Gradle Build** on the Android
13
+ preset — required to produce an **AAB** and to use custom Gradle/plugins.
14
+ - Unity: `File ▸ Build Profiles ▸ Android`; **Build App Bundle (Google Play)** for AAB.
15
+ - Unreal: run **Turnkey**/Android setup once (Android Studio + correct NDK), then
16
+ `RunUAT BuildCookRun ... -platform=Android -clientconfig=Shipping -distribution -cook -stage -pak -package`.
17
+
18
+ ### AAB vs APK
19
+
20
+ | Format | Use for | Notes |
21
+ | --- | --- | --- |
22
+ | **AAB** (`.aab`) | Google Play (**required** for new apps + updates) | Play generates optimized per-device APKs; you can't install an AAB directly. |
23
+ | **APK** (`.apk`) | Sideload, itch.io, direct download, other stores | Installs directly; use a universal APK for QA. |
24
+
25
+ ### Signing & keystore
26
+
27
+ Generate a release keystore **once** and guard it — losing it means you can't publish updates
28
+ (unless enrolled in Play App Signing, where Google holds the app-signing key and you rotate the
29
+ upload key):
30
+
31
+ ```bash
32
+ keytool -genkey -v -keystore release.keystore -alias game \
33
+ -keyalg RSA -keysize 2048 -validity 10000
34
+ ```
35
+
36
+ - Godot: set the **Release** keystore path + alias + passwords in the Android preset (and a debug
37
+ keystore for debug exports).
38
+ - Never commit the keystore or passwords. In CI, restore the keystore from a base64-encoded secret
39
+ at runtime and pass passwords via env.
40
+ - **Play App Signing**: you sign the upload with the *upload key*; Google re-signs distribution
41
+ with the *app-signing key* it stores. Recommended — it lets you recover a lost upload key.
42
+ - `versionCode` (integer) must **strictly increase** every upload; `versionName` is the human string.
43
+
44
+ ### Common failures
45
+
46
+ - Editor 4.5.1 + templates 4.5 ⇒ export greyed out or Gradle error. Match versions exactly.
47
+ - Wrong JDK ⇒ Gradle build fails. Use 17.
48
+ - Debug keystore used for a release ⇒ Play rejects it.
49
+ - Target API level too old ⇒ Play blocks the submission.
50
+
51
+ ## iOS
52
+
53
+ - **Mac + Xcode + an Apple Developer Program membership** (paid) are non-negotiable for device/store builds.
54
+ - **Bundle Identifier** must match a registered **App ID** in the developer portal.
55
+ - **Signing certificate** (Apple Development / Apple Distribution) + a **provisioning profile**
56
+ that ties App ID + certificate + devices/distribution method:
57
+ - *Development* — run on registered test devices.
58
+ - *Ad Hoc* — distribute to a fixed device list outside the store.
59
+ - *App Store* — submit to App Store Connect / TestFlight.
60
+ - Enable **Automatically manage signing** in Xcode for the common case; use manual profiles for CI.
61
+ - Flow: engine exports an Xcode project → open in Xcode → set team/signing → **Product ▸ Archive**
62
+ → distribute via the Organizer, or upload with **Transporter** to App Store Connect.
63
+ - **TestFlight** for beta: upload a build, add internal/external testers, then submit for review.
64
+ - `CFBundleShortVersionString` = marketing version; `CFBundleVersion` = build number, must
65
+ **increase** per upload to App Store Connect.
66
+
67
+ ## macOS (desktop, outside the App Store)
68
+
69
+ Gatekeeper will refuse an unsigned/un-notarized app for end users. The full chain is codesign →
70
+ notarize → staple, inside-out.
71
+
72
+ ```bash
73
+ # 1. Sign every nested binary FIRST, then the outer .app (Hardened Runtime is mandatory)
74
+ codesign --deep --force --timestamp --options runtime \
75
+ --sign "Developer ID Application: Studio Name (TEAMID)" Game.app
76
+
77
+ # 2. Store notarization creds once (App Store Connect API key or Apple ID app-password)
78
+ xcrun notarytool store-credentials "AC" \
79
+ --apple-id you@studio.com --team-id TEAMID --password app-specific-pw
80
+
81
+ # 3. Zip and submit; --wait blocks until Apple returns accepted/invalid
82
+ ditto -c -k --keepParent Game.app Game.zip
83
+ xcrun notarytool submit Game.zip --keychain-profile "AC" --wait
84
+
85
+ # 4. Staple the ticket so the app verifies OFFLINE, then verify
86
+ xcrun stapler staple Game.app
87
+ spctl --assess --type execute -vvv Game.app # should say: accepted, source=Notarized Developer ID
88
+ ```
89
+
90
+ - `--options runtime` (Hardened Runtime) is **required** or notarization is rejected.
91
+ - Sign nested `.dylib`s / helper tools / frameworks before the parent bundle.
92
+ - Distributing a `.dmg`? Notarize and staple the **`.dmg`** too (submit the dmg, staple the dmg).
93
+ - `altool` notarization is retired — use `xcrun notarytool`.
94
+ - If `notarytool` returns `Invalid`, fetch the log: `xcrun notarytool log <submission-id> --keychain-profile "AC"`.
95
+
96
+ ### Mac App Store (different path)
97
+
98
+ - Sign with **Apple Distribution** (not Developer ID) + **App Sandbox** entitlements.
99
+ - Submit through App Store Connect (via Xcode/Transporter); the store notarizes automatically —
100
+ you do not run `notarytool`/`stapler` manually for App Store builds.
101
+
102
+ ## Windows
103
+
104
+ - Signing is **optional** but recommended: an Authenticode code-signing certificate reduces the
105
+ SmartScreen "unknown publisher" warning. An **EV** certificate builds reputation faster.
106
+
107
+ ```powershell
108
+ signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 /a Game.exe
109
+ ```
110
+
111
+ - Ship the `.exe` alongside the engine data/`.pck` (or bundle into an installer: Inno Setup / NSIS / MSIX).
112
+ - Unsigned still runs; users just click through a SmartScreen prompt.
113
+
114
+ ## Linux
115
+
116
+ - No signing requirement. Ship the executable + data files, or wrap for portability:
117
+ - **AppImage** — one self-contained file, runs across distros; easiest for direct/itch distribution.
118
+ - **Flatpak** — sandboxed, distributed via Flathub; more packaging work, best store reach.
119
+ - Mark the binary executable (`chmod +x`) and test on a clean distro (glibc version differences bite).
120
+
121
+ ## Cross-platform checklist
122
+
123
+ - [ ] Android: JDK 17, AAB for Play (APK for sideload), release keystore in CI secret, `versionCode` bumped, Play App Signing on.
124
+ - [ ] iOS: App ID + cert + provisioning profile matched, `CFBundleVersion` bumped, archive uploaded.
125
+ - [ ] macOS: codesign (Hardened Runtime) → notarytool → stapler → `spctl` accepted.
126
+ - [ ] Windows: signed (or SmartScreen prompt accepted as known), installer built if needed.
127
+ - [ ] Linux: AppImage/Flatpak or binary+data, tested on a clean distro.