@ericrisco/rsc 0.1.51 → 0.1.53
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.
- package/manifest.json +12 -12
- package/package.json +1 -1
- package/skills/gamedev-multiplayer/SKILL.md +35 -48
- package/skills/gamedev-pathing/SKILL.md +20 -29
- package/skills/gamedev-shaders/SKILL.md +23 -43
- package/skills/gamedev-shaders/evals/cases.yaml +2 -2
- package/skills/gcp-essentials/SKILL.md +16 -19
- package/skills/hetzner/SKILL.md +18 -36
- package/skills/knowledge-ops/SKILL.md +14 -17
- package/skills/medium-publishing/SKILL.md +5 -13
- package/skills/n8n/SKILL.md +37 -65
- package/skills/notion-connector/SKILL.md +13 -26
- package/skills/planetscale/SKILL.md +18 -43
- package/skills/planetscale/references/no-foreign-keys.md +2 -2
- package/skills/security-scan/SKILL.md +46 -67
- package/skills/security-scan/references/tools.md +0 -1
- package/skills/security-scan/references/triage.md +0 -1
package/manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.1.
|
|
2
|
+
"version": "0.1.53",
|
|
3
3
|
"counts": {
|
|
4
4
|
"skills": 258
|
|
5
5
|
},
|
|
@@ -1889,7 +1889,7 @@
|
|
|
1889
1889
|
},
|
|
1890
1890
|
{
|
|
1891
1891
|
"id": "gamedev-multiplayer",
|
|
1892
|
-
"description": "Use when adding multiplayer
|
|
1892
|
+
"description": "Use when adding multiplayer or netcode to a game — client-server vs P2P, server authority and anti-cheat, state replication vs RPCs, prediction and reconciliation, lag compensation, plus Godot 4 / Unity NGO / Unreal wiring. NOT single-player gameplay (that is `godot`, `unity`, `unreal`), NOT matchmaking or server hosting (that is `deployment`).",
|
|
1893
1893
|
"tags": [
|
|
1894
1894
|
"multiplayer",
|
|
1895
1895
|
"netcode",
|
|
@@ -1910,7 +1910,7 @@
|
|
|
1910
1910
|
},
|
|
1911
1911
|
{
|
|
1912
1912
|
"id": "gamedev-pathing",
|
|
1913
|
-
"description": "Use when
|
|
1913
|
+
"description": "Use when making NPCs, enemies, or units navigate a level — grid vs waypoint vs navmesh, A*/JPS, navmesh baking and agent radius, off-mesh links, steering, RVO crowd avoidance, and flow fields in Godot 4.x, Unity, Unreal. NOT collision response or character controllers (that is gamedev-physics), NOT aggro or difficulty design (that is game-design).",
|
|
1914
1914
|
"tags": [
|
|
1915
1915
|
"pathfinding",
|
|
1916
1916
|
"navmesh",
|
|
@@ -1950,7 +1950,7 @@
|
|
|
1950
1950
|
},
|
|
1951
1951
|
{
|
|
1952
1952
|
"id": "gamedev-shaders",
|
|
1953
|
-
"description": "Use when
|
|
1953
|
+
"description": "Use when authoring or debugging a shader, material, VFX, or full-screen post-process in a game engine — Godot 4.x `.gdshader`, Unity 6 URP/HDRP, Unreal 5.x Materials, effect recipes, shader performance. NOT gameplay or engine-API code (that is `godot`/`unity`/`unreal`), NOT physics (`gamedev-physics`), NOT build variant stripping (`gamedev-shipping`).",
|
|
1954
1954
|
"tags": [
|
|
1955
1955
|
"shaders",
|
|
1956
1956
|
"vfx",
|
|
@@ -1995,7 +1995,7 @@
|
|
|
1995
1995
|
},
|
|
1996
1996
|
{
|
|
1997
1997
|
"id": "gcp-essentials",
|
|
1998
|
-
"description": "Use when running a small product on
|
|
1998
|
+
"description": "Use when running a small product on core Google Cloud via the gcloud CLI: a project, Cloud Run deploys, a locked-down Cloud Storage bucket, managed Cloud SQL, and least-privilege IAM wiring them together. NOT AWS (that is `aws-essentials`), NOT the CI pipeline that ships the image (that is `deployment`), NOT Postgres schema/query tuning (that is `postgresdb`).",
|
|
1999
1999
|
"tags": [
|
|
2000
2000
|
"gcp",
|
|
2001
2001
|
"cloud-run",
|
|
@@ -2192,7 +2192,7 @@
|
|
|
2192
2192
|
},
|
|
2193
2193
|
{
|
|
2194
2194
|
"id": "hetzner",
|
|
2195
|
-
"description": "Use when provisioning or hardening a Hetzner Cloud VPS
|
|
2195
|
+
"description": "Use when provisioning or hardening a Hetzner Cloud VPS: picking the plan/location (CX/CPX/CAX/CCX), bringing it up reproducibly with hcloud + cloud-init, locking down SSH, and wiring the Cloud Firewall to hand off a Docker-ready host. NOT app deploys on Coolify (that is `coolify`), NOT Dockerfiles (that is `docker`), NOT another provider (that is `digitalocean`).",
|
|
2196
2196
|
"tags": [
|
|
2197
2197
|
"hetzner",
|
|
2198
2198
|
"vps",
|
|
@@ -2439,7 +2439,7 @@
|
|
|
2439
2439
|
},
|
|
2440
2440
|
{
|
|
2441
2441
|
"id": "knowledge-ops",
|
|
2442
|
-
"description": "Use when an already-running 02-DOCS/ wiki needs
|
|
2442
|
+
"description": "Use when an already-running 02-DOCS/ wiki needs gardening judgment — what is worth capturing (default: nothing), where a loose note belongs, whether to split a bloated article or merge near-duplicates, how to link orphans back in, and what retires to _archive (never delete). NOT building or sweeping the wiki engine itself (that is `harness`).",
|
|
2443
2443
|
"tags": [
|
|
2444
2444
|
"knowledge-ops",
|
|
2445
2445
|
"wiki",
|
|
@@ -2827,7 +2827,7 @@
|
|
|
2827
2827
|
},
|
|
2828
2828
|
{
|
|
2829
2829
|
"id": "medium-publishing",
|
|
2830
|
-
"description": "Use when
|
|
2830
|
+
"description": "Use when a finished article has to land on Medium correctly — profile vs publication, cross-posting under a canonical link so your own site keeps the SEO credit, import-tool failures, the 5-tag cap, pseudo-Markdown gotchas. NOT writing or headlining the piece (that is `medium-writing`), NOT cadence or earnings (that is `medium-strategy`).",
|
|
2831
2831
|
"tags": [
|
|
2832
2832
|
"medium",
|
|
2833
2833
|
"publishing",
|
|
@@ -2992,7 +2992,7 @@
|
|
|
2992
2992
|
},
|
|
2993
2993
|
{
|
|
2994
2994
|
"id": "n8n",
|
|
2995
|
-
"description": "Use when operating a live n8n instance programmatically —
|
|
2995
|
+
"description": "Use when operating a live n8n instance programmatically — its REST API (`{host}/api/v1`, `X-N8N-API-KEY`) or the n8n-mcp server — to create, validate, test, activate, update, delete workflows and read executions on self-host or n8n.cloud. NOT designing the flow or its importable JSON (that is `automation-flows`), NOT another platform (`make`, `zapier`).",
|
|
2996
2996
|
"tags": [
|
|
2997
2997
|
"n8n",
|
|
2998
2998
|
"automation",
|
|
@@ -3177,7 +3177,7 @@
|
|
|
3177
3177
|
},
|
|
3178
3178
|
{
|
|
3179
3179
|
"id": "notion-connector",
|
|
3180
|
-
"description": "Use when wiring
|
|
3180
|
+
"description": "Use when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an integration broken by the 2025-09-03 data-source split. NOT generic REST wiring (that is `api-connector-builder`), NOT inbound Notion webhook events (that is `webhooks`).",
|
|
3181
3181
|
"tags": [
|
|
3182
3182
|
"notion",
|
|
3183
3183
|
"ops-backend",
|
|
@@ -3406,7 +3406,7 @@
|
|
|
3406
3406
|
},
|
|
3407
3407
|
{
|
|
3408
3408
|
"id": "planetscale",
|
|
3409
|
-
"description": "Use when operating PlanetScale serverless MySQL
|
|
3409
|
+
"description": "Use when operating PlanetScale (Vitess serverless MySQL) — branches and the `pscale` CLI, schema changes through deploy requests (Online DDL cutover, ~30-min revert window), tables without foreign keys, or the edge HTTP driver. NOT MySQL engine work like EXPLAIN or index choice (that is `mysql`), NOT generic migration theory (that is `db-migrations`).",
|
|
3410
3410
|
"tags": [
|
|
3411
3411
|
"planetscale",
|
|
3412
3412
|
"vitess",
|
|
@@ -4175,7 +4175,7 @@
|
|
|
4175
4175
|
},
|
|
4176
4176
|
{
|
|
4177
4177
|
"id": "security-scan",
|
|
4178
|
-
"description": "Use when
|
|
4178
|
+
"description": "Use when automated scanners drive a security sweep of a repo or app — SAST, dependency/lockfile CVEs, secrets in the tree or git history, IaC misconfig — and the raw output has to become one deduped, exploitability-ranked report CI can gate on. NOT threat-modeling, OWASP design reasoning, or hand-authoring the fix (that is `secure-coding`).",
|
|
4179
4179
|
"tags": [
|
|
4180
4180
|
"security",
|
|
4181
4181
|
"sast",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gamedev-multiplayer
|
|
3
|
-
description: "Use when adding multiplayer
|
|
3
|
+
description: "Use when adding multiplayer or netcode to a game — client-server vs P2P, server authority and anti-cheat, state replication vs RPCs, prediction and reconciliation, lag compensation, plus Godot 4 / Unity NGO / Unreal wiring. NOT single-player gameplay (that is `godot`, `unity`, `unreal`), NOT matchmaking or server hosting (that is `deployment`)."
|
|
4
4
|
tags: [multiplayer, netcode, replication, networking, prediction, authority]
|
|
5
5
|
recommends: [godot, unity, unreal, gamedev-physics]
|
|
6
6
|
profiles: [full]
|
|
@@ -14,6 +14,16 @@ topology, put authority in the right place, replicate the right state, and hide
|
|
|
14
14
|
opening the door to cheaters. This skill owns the *networking* decisions; the engine skills own
|
|
15
15
|
the local gameplay those decisions sit on top of.
|
|
16
16
|
|
|
17
|
+
Route elsewhere when the ask is not netcode:
|
|
18
|
+
|
|
19
|
+
| The ask | Route to | Why not here |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| Single-player movement, AI, input, animation, save files | [`godot`](../godot/SKILL.md) / [`unity`](../unity/SKILL.md) / [`unreal`](../unreal/SKILL.md) | The engine skill owns local gameplay; no network dimension. |
|
|
22
|
+
| Physics determinism, collision, character controllers | [`gamedev-physics`](../gamedev-physics/SKILL.md) | Netcode *consumes* determinism; it does not own the physics fix. |
|
|
23
|
+
| Matchmaking, lobby backend, dedicated-server hosting, relays, DB, game-server CI | [`deployment`](../deployment/SKILL.md) | Running the fleet, not designing the in-game net layer. |
|
|
24
|
+
| Web realtime — chat, presence, a generic WebSocket app | [`webhooks`](../webhooks/SKILL.md) | Not a game world/simulation. |
|
|
25
|
+
| General threat modeling, authz review | [`secure-coding`](../secure-coding/SKILL.md) | This skill keeps only the game-specific anti-cheat controls. |
|
|
26
|
+
|
|
17
27
|
## Version contract — read first
|
|
18
28
|
|
|
19
29
|
Target the current APIs. **Never emit these deprecated / removed APIs:**
|
|
@@ -30,19 +40,6 @@ community UNet-like fork), say so; this skill targets first-party NGO. In NGO 2.
|
|
|
30
40
|
`[ServerRpc]` / `[ClientRpc]` still compile (and enforce `…ServerRpc` / `…ClientRpc` method-name
|
|
31
41
|
suffixes) — cover them but prefer the unified form on new code.
|
|
32
42
|
|
|
33
|
-
## Fires on / When NOT
|
|
34
|
-
|
|
35
|
-
**Fires on:** "how do I sync players", replication, netcode, RPCs, authority, online co-op or PvP,
|
|
36
|
-
"client and server disagree", rubber-banding / teleporting players, prediction & reconciliation,
|
|
37
|
-
lag compensation, tick rate / send rate, spawning networked objects, "the client can cheat".
|
|
38
|
-
|
|
39
|
-
**When NOT (route away):**
|
|
40
|
-
|
|
41
|
-
- Single-player movement, AI, input, animation, save files → the engine skill: `godot`, `unity`, `unreal`.
|
|
42
|
-
- Physics determinism, collision, character controllers → `gamedev-physics` (netcode *consumes* it).
|
|
43
|
-
- Matchmaking service, lobby backend, dedicated-server hosting/orchestration, relays, DB → `deployment`.
|
|
44
|
-
- Web realtime (chat, presence, generic WebSocket app) that is not a game world → `webhooks` / a backend skill.
|
|
45
|
-
|
|
46
43
|
## Topologies & authority
|
|
47
44
|
|
|
48
45
|
Pick the topology first; everything else follows from it.
|
|
@@ -61,7 +58,8 @@ requests), never results. **Never trust the client:** the client cannot set its
|
|
|
61
58
|
score, currency, or hit results — it *asks*, the server *decides*, everyone else *observes*. A client
|
|
62
59
|
that says "I moved to X / I did 40 damage / I have 999 gold" is either lagging or cheating; treat both
|
|
63
60
|
the same. The one thing a client legitimately owns is its own input and, by convention, cosmetic-only
|
|
64
|
-
state. See references/prediction-and-latency.md for how to
|
|
61
|
+
state. See **[references/prediction-and-latency.md](references/prediction-and-latency.md)** for how to
|
|
62
|
+
keep this responsive.
|
|
65
63
|
|
|
66
64
|
## State replication vs RPCs
|
|
67
65
|
|
|
@@ -88,7 +86,7 @@ is the #1 cause of "it works for the host but not the client" bugs.
|
|
|
88
86
|
## The hard problems
|
|
89
87
|
|
|
90
88
|
Latency (round-trip time, RTT) is the enemy; jitter and packet loss make it worse. Four techniques,
|
|
91
|
-
covered in depth in **references/prediction-and-latency.md**:
|
|
89
|
+
covered in depth in **[references/prediction-and-latency.md](references/prediction-and-latency.md)**:
|
|
92
90
|
|
|
93
91
|
1. **Client-side prediction** — the owning client applies its own input *immediately* instead of waiting a
|
|
94
92
|
full RTT for the server, so local movement feels instant.
|
|
@@ -140,7 +138,8 @@ func request_fire(target: Vector3) -> void:
|
|
|
140
138
|
- `MultiplayerSynchronizer` streams a chosen property list (position, etc.) from the authority to peers;
|
|
141
139
|
set its replication interval and visibility (`set_visibility_for(peer, bool)`) to scope bandwidth.
|
|
142
140
|
- `MultiplayerSpawner` replicates instancing of scenes under a path so late peers get existing objects.
|
|
143
|
-
- Details, prediction wiring, and the full player-scene pattern:
|
|
141
|
+
- Details, prediction wiring, and the full player-scene pattern:
|
|
142
|
+
**[references/godot-high-level-multiplayer.md](references/godot-high-level-multiplayer.md)**.
|
|
144
143
|
|
|
145
144
|
### Unity — Netcode for GameObjects
|
|
146
145
|
|
|
@@ -168,7 +167,8 @@ public class Player : NetworkBehaviour {
|
|
|
168
167
|
- `NetworkVariable<T>(value, readPerm, writePerm)` — `NetworkVariableWritePermission.Server` (default) vs
|
|
169
168
|
`.Owner`; subscribe via `OnValueChanged`. Use `NetworkTransform` for pos/rot sync.
|
|
170
169
|
- Prefer the unified `[Rpc(SendTo.X)]`; legacy `[ServerRpc]`/`[ClientRpc]` still work but need the
|
|
171
|
-
method-name suffixes. Full patterns:
|
|
170
|
+
method-name suffixes. Full patterns:
|
|
171
|
+
**[references/unity-and-unreal-netcode.md](references/unity-and-unreal-netcode.md)**.
|
|
172
172
|
|
|
173
173
|
### Unreal — Actor replication
|
|
174
174
|
|
|
@@ -196,7 +196,8 @@ void AMyPawn::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Out) const {
|
|
|
196
196
|
- **Relevancy** keeps bandwidth sane: `NetCullDistanceSquared`, `bAlwaysRelevant`, `IsNetRelevantFor`, and
|
|
197
197
|
dormancy (`SetNetDormancy`) stop replicating actors a client can't perceive. Movement replicates via
|
|
198
198
|
`CharacterMovementComponent`, which already does prediction+reconciliation for you.
|
|
199
|
-
- RepNotify vs Multicast, GAS/Network Prediction notes:
|
|
199
|
+
- RepNotify vs Multicast, GAS/Network Prediction notes:
|
|
200
|
+
**[references/unity-and-unreal-netcode.md](references/unity-and-unreal-netcode.md)**.
|
|
200
201
|
|
|
201
202
|
## Security / anti-cheat basics
|
|
202
203
|
|
|
@@ -219,32 +220,18 @@ void AMyPawn::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Out) const {
|
|
|
219
220
|
- Always test **with simulated latency and packet loss**, not just on localhost — localhost hides every
|
|
220
221
|
prediction/reconciliation bug. Test the client path, not only the host's.
|
|
221
222
|
|
|
222
|
-
##
|
|
223
|
-
|
|
224
|
-
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
- **`deployment`** — dedicated-server hosting, matchmaking/lobby backend, relays, and CI for game servers.
|
|
238
|
-
- **`secure-coding`** — general threat modeling; this skill keeps only the game-specific anti-cheat controls.
|
|
239
|
-
|
|
240
|
-
## Checklist
|
|
241
|
-
|
|
242
|
-
- [ ] Topology chosen (dedicated / listen / P2P) and the *same code* runs on server and listen host.
|
|
243
|
-
- [ ] Server-authoritative: clients send intent only; server validates and owns all gameplay state.
|
|
244
|
-
- [ ] Each networked value is either replicated (state/nouns) or an RPC (events/verbs) — not the wrong one.
|
|
245
|
-
- [ ] Ownership/authority set explicitly per object; authority-only logic guarded on the host.
|
|
246
|
-
- [ ] Owning-client movement predicted + reconciled; remote entities snapshot-interpolated.
|
|
247
|
-
- [ ] Hitscan uses server-side lag compensation; simulation on a fixed tick, decoupled from render FPS.
|
|
248
|
-
- [ ] Only need-to-know state replicated per client (relevancy/visibility scoped); RPCs rate-limited.
|
|
249
|
-
- [ ] Tested with simulated latency + packet loss across multiple instances, exercising the client path.
|
|
250
|
-
- [ ] No banned APIs (UNet/HLAPI, Godot 3.x `master`/`puppet`/`rset`, `Tick`-polled Unreal replication).
|
|
223
|
+
## Anti-patterns
|
|
224
|
+
|
|
225
|
+
| Anti-pattern | Why it bites | Do instead |
|
|
226
|
+
| --- | --- | --- |
|
|
227
|
+
| Writing net code before the topology is chosen | Authority and cost model change everything downstream | Pick dedicated / listen / P2P first, and make the *same code* run on server and listen host |
|
|
228
|
+
| Trusting a client-reported result (health, position, score, hit) | That is the cheat surface, and lag looks identical to cheating | Clients send intent only; the server validates and owns all gameplay state |
|
|
229
|
+
| RPCing state that must stay consistent | A dropped unreliable event desyncs that client permanently | Replicate nouns (state), RPC verbs (events) — replicated values self-correct |
|
|
230
|
+
| Ownership/authority left implicit | The #1 cause of "works for the host, breaks for the client" | Set authority/ownership explicitly on spawn |
|
|
231
|
+
| Forgetting the listen-server host is also a client | Authority-only logic double-executes on the host | Guard it behind `is_server()` / `HasAuthority()` |
|
|
232
|
+
| Making the owning client wait a full RTT for its own input | Movement feels sluggish and unresponsive | Predict locally + reconcile; snapshot-interpolate remote entities |
|
|
233
|
+
| Client-side hit detection for hitscan | Trivially spoofed, and unfair to the higher-ping shooter | Server-side lag compensation: rewind to the shooter's render time |
|
|
234
|
+
| Tying simulation to render FPS | Sim diverges between machines at different frame rates | Fixed timestep on the sim, interpolate on the render |
|
|
235
|
+
| Replicating everything, every tick, to everyone | Melts bandwidth and leaks wallhack fuel | Scope by relevancy/visibility and send rate; rate-limit RPCs |
|
|
236
|
+
| Testing only on localhost | 0 ms RTT masks the exact desync/rubber-band bugs players will hit | Inject latency + packet loss across instances, exercising the client path |
|
|
237
|
+
| Emitting UNet/HLAPI, Godot 3.x `master`/`puppet`/`rset`, or `Tick`-polled Unreal replication | Removed or legacy — it will not compile or will silently underperform | The current APIs in the version contract above |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gamedev-pathing
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when making NPCs, enemies, or units navigate a level — grid vs waypoint vs navmesh, A*/JPS, navmesh baking and agent radius, off-mesh links, steering, RVO crowd avoidance, and flow fields in Godot 4.x, Unity, Unreal. NOT collision response or character controllers (that is gamedev-physics), NOT aggro or difficulty design (that is game-design)."
|
|
4
4
|
tags: [pathfinding, navmesh, navigation, steering, a-star]
|
|
5
5
|
recommends: [godot, unity, unreal, gamedev-physics]
|
|
6
6
|
profiles: [full]
|
|
@@ -102,7 +102,8 @@ Combine either as a **weighted sum** (simple) or **priority/arbitration** (avoid
|
|
|
102
102
|
**Local avoidance (RVO / ORCA):** each agent picks a velocity that is collision-free assuming neighbours
|
|
103
103
|
share the burden (*reciprocal* — hence no oscillating "dance"). This is avoidance, **not** collision
|
|
104
104
|
*response*: it changes intended velocity *before* moving; the physics/collision solver is a separate,
|
|
105
|
-
last-resort backstop (→ `gamedev-physics`). For dense crowds use the
|
|
105
|
+
last-resort backstop (→ [`gamedev-physics`](../gamedev-physics/SKILL.md)). For dense crowds use the
|
|
106
|
+
engine's crowd/avoidance system.
|
|
106
107
|
|
|
107
108
|
**Flow fields** — for **many agents → one (or few) goals** (RTS swarm, tower-defense creeps): run one
|
|
108
109
|
**Dijkstra from the goal** over the grid to build a cost/integration field, derive a per-cell direction
|
|
@@ -182,30 +183,26 @@ AICon->MoveToActor(TargetActor, /*AcceptanceRadius*/ 50.f); // or MoveToLocati
|
|
|
182
183
|
4. Costs/holes: **`NavModifierVolume`** + `NavArea` classes. Off-mesh: **`NavLinkProxy`**. Crowd
|
|
183
184
|
avoidance: enable the **Detour Crowd** manager (or `DetourCrowdAIController`) for RVO on many agents.
|
|
184
185
|
|
|
185
|
-
> High-level BT *design* (states, aggro, difficulty) is `game-design
|
|
186
|
+
> High-level BT *design* (states, aggro, difficulty) is [`game-design`](../game-design/SKILL.md); this skill wires the BT's
|
|
186
187
|
> movement/EQS tasks to navigation, not the decision tree's semantics.
|
|
187
188
|
|
|
188
|
-
##
|
|
189
|
+
## Anti-patterns
|
|
189
190
|
|
|
190
|
-
-
|
|
191
|
-
- Bake covers **static** geometry; runtime-spawned meshes need a rebake, a carving obstacle, or a nav link.
|
|
192
|
-
- Path returns empty when start/end are **off the navmesh** or in disconnected islands — snap to nearest poly and check reachability first.
|
|
193
|
-
- Avoidance (RVO) ≠ collision (physics). Agents can still overlap under pressure; that is expected, not a physics bug.
|
|
194
|
-
- Off-mesh links are **directional and manual** — a jump-down link does not imply a jump-up link.
|
|
195
|
-
- Smooth grid paths (funnel / string-pull) or agents walk visible zig-zag staircases.
|
|
196
|
-
|
|
197
|
-
## Anti-patterns / rationalizations → STOP
|
|
198
|
-
|
|
199
|
-
| Rationalization | Reality / do instead |
|
|
191
|
+
| Anti-pattern | Do instead |
|
|
200
192
|
| --- | --- |
|
|
201
|
-
|
|
|
202
|
-
|
|
|
203
|
-
|
|
|
204
|
-
|
|
|
205
|
-
|
|
|
206
|
-
|
|
|
207
|
-
|
|
|
208
|
-
|
|
|
193
|
+
| Running a full A* every frame | Path on goal-change (or throttled) and steer between frames — per-frame search melts CPU at scale. |
|
|
194
|
+
| One navmesh bake shared by every unit | Radius/height differ; bake per agent size or use agent-type profiles. |
|
|
195
|
+
| Baking with a placeholder agent radius | Bake with the real radius — mismatch is the top "stuck in doorways / clipping walls" cause. |
|
|
196
|
+
| Treating agents that clip through each other as a physics bug | Missing **local avoidance**; enable RVO/crowd — that is the navigation layer. |
|
|
197
|
+
| Expecting RVO to prevent every overlap | Avoidance ≠ collision. Agents can still overlap under pressure; that is expected, not a physics bug. |
|
|
198
|
+
| Expecting a **static** bake to see runtime-spawned geometry | Set Dynamic runtime generation / rebake, or add a carving obstacle or nav link. |
|
|
199
|
+
| Hand-rolling your own grid A* in Unity/Unreal | Reinvents the built-in navmesh; use `NavMeshAgent` / `AAIController::MoveTo`. |
|
|
200
|
+
| 500 zombies each running A* to the player | That's a **flow field**: one Dijkstra from the goal, agents sample cells. |
|
|
201
|
+
| Setting `agent.destination` and reading the path the same frame | Path is async (`pathPending`); gate on it before trusting `remainingDistance`. |
|
|
202
|
+
| Inflating `h` because a bigger heuristic seems smarter | Over-estimating `h` breaks A* optimality; keep it admissible (or weight it *knowingly*). |
|
|
203
|
+
| Trusting a path query that came back empty | Start/end are **off the navmesh** or in disconnected islands — snap to the nearest poly and check reachability first. |
|
|
204
|
+
| Assuming an off-mesh link works both ways | Links are **directional and manual** — a jump-down link does not imply a jump-up link. |
|
|
205
|
+
| Feeding raw grid paths to the mover | Smooth them (funnel / string-pull) or agents walk visible zig-zag staircases. |
|
|
209
206
|
|
|
210
207
|
## Related skills
|
|
211
208
|
|
|
@@ -213,7 +210,7 @@ AICon->MoveToActor(TargetActor, /*AcceptanceRadius*/ 50.f); // or MoveToLocati
|
|
|
213
210
|
- [`unity`](../unity/SKILL.md) — Unity/C# project setup; here for the NavMesh + AI Navigation package details.
|
|
214
211
|
- [`unreal`](../unreal/SKILL.md) — UE5/Blueprint/C++; here for RecastNavMesh + AIController/BT/EQS wiring.
|
|
215
212
|
- [`gamedev-physics`](../gamedev-physics/SKILL.md) — collision *response*, rigidbodies, character controllers; steering decides intended velocity, physics resolves the contact.
|
|
216
|
-
- `game-design` — high-level enemy behaviour, aggro, encounter/difficulty design (what the AI *decides*, not how it *moves*).
|
|
213
|
+
- [`game-design`](../game-design/SKILL.md) — high-level enemy behaviour, aggro, encounter/difficulty design (what the AI *decides*, not how it *moves*).
|
|
217
214
|
|
|
218
215
|
## Checklist
|
|
219
216
|
|
|
@@ -234,9 +231,3 @@ the project's navigation decisions in `02-DOCS/wiki/stack/gamedev-pathing.md` (i
|
|
|
234
231
|
`02-DOCS/wiki/index.md`): engine + version, chosen representation, bake settings (agent sizes, cell
|
|
235
232
|
size), avoidance/crowd choice, custom links/areas. Read it first on every use; bump its `Updated` date
|
|
236
233
|
when a convention changes. No `02-DOCS/` layer? Skip silently — conventions are *recorded, not gated*.
|
|
237
|
-
|
|
238
|
-
## See Also — local references (read when)
|
|
239
|
-
|
|
240
|
-
- `references/search-algorithms.md` — representations, A*/Dijkstra/JPS/HPA* pseudocode, heuristics & admissibility, tie-breaking, any-angle, funnel smoothing.
|
|
241
|
-
- `references/navmesh-workflow.md` — bake-parameter table, areas/costs, off-mesh links, obstacles vs carving vs partial rebake, per-engine baking, debugging.
|
|
242
|
-
- `references/steering-and-avoidance.md` — steering primitives, path following, boids weights, RVO/ORCA intuition, crowds, flow-field construction.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gamedev-shaders
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when authoring or debugging a shader, material, VFX, or full-screen post-process in a game engine — Godot 4.x `.gdshader`, Unity 6 URP/HDRP, Unreal 5.x Materials, effect recipes, shader performance. NOT gameplay or engine-API code (that is `godot`/`unity`/`unreal`), NOT physics (`gamedev-physics`), NOT build variant stripping (`gamedev-shipping`)."
|
|
4
4
|
tags: [shaders, vfx, materials, post-processing, shadergraph]
|
|
5
5
|
recommends: [godot, unity, unreal, gamedev-shipping]
|
|
6
6
|
profiles: [full]
|
|
@@ -11,8 +11,7 @@ origin: risco
|
|
|
11
11
|
|
|
12
12
|
Author shaders, materials, and full-screen effects across Godot, Unity, and Unreal. One
|
|
13
13
|
mental model — the GPU pipeline — mapped onto each engine's authoring surface, plus recipes
|
|
14
|
-
for the effects people actually ask for.
|
|
15
|
-
building a VFX/post-process effect, or "how do I make X look like Y".
|
|
14
|
+
for the effects people actually ask for.
|
|
16
15
|
|
|
17
16
|
## Version contract — read first
|
|
18
17
|
|
|
@@ -28,22 +27,6 @@ symbol is current, say so rather than guess.
|
|
|
28
27
|
`shader_type` tokens in Godot 4 are exact: `spatial`, `canvas_item` (underscore), `particles`
|
|
29
28
|
(plural), `sky`, `fog`.
|
|
30
29
|
|
|
31
|
-
## When to use / When NOT to use
|
|
32
|
-
|
|
33
|
-
**Use when:** writing or debugging a `.gdshader`/`ShaderMaterial`, a `.shader`/Shader Graph, or
|
|
34
|
-
a UE Material; building a VFX look (dissolve, rim, toon, water, shield, hologram, trails);
|
|
35
|
-
authoring post-processing / screen-space effects; a shader is slow, flickers, or looks wrong;
|
|
36
|
-
choosing per-vertex vs per-pixel; converting an effect between engines.
|
|
37
|
-
|
|
38
|
-
**When NOT to use (delegate):**
|
|
39
|
-
|
|
40
|
-
- Gameplay logic, nodes/components, input, engine APIs, scene setup → [`godot`](../godot/SKILL.md) /
|
|
41
|
-
[`unity`](../unity/SKILL.md) / [`unreal`](../unreal/SKILL.md). This skill owns the *shading*, not the C#/GDScript/Blueprint around it.
|
|
42
|
-
- Physics simulation, collisions, rigid bodies, character controllers → [`gamedev-physics`](../gamedev-physics/SKILL.md).
|
|
43
|
-
(A shader that *fakes* refraction is here; simulating fluid dynamics is not.)
|
|
44
|
-
- Shipping, platform export, shader-variant stripping in the build pipeline → [`gamedev-shipping`](../gamedev-shipping/SKILL.md)
|
|
45
|
-
(this skill keeps the per-shader performance work).
|
|
46
|
-
|
|
47
30
|
## Shader fundamentals (the pipeline)
|
|
48
31
|
|
|
49
32
|
Every engine compiles your material into the same GPU stages. Two you write:
|
|
@@ -131,10 +114,10 @@ for high-end):
|
|
|
131
114
|
blocks; the program goes in an `HLSLPROGRAM … ENDHLSL` block that `#include`s URP's `Core.hlsl`
|
|
132
115
|
/ `Lighting.hlsl`. Use for full control, custom lighting, or compute-driven effects.
|
|
133
116
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
117
|
+
Surface shaders are not an option under URP/HDRP (see the Version contract) — a lit look is an
|
|
118
|
+
HLSL pass or a Shader Graph. Set parameters at runtime through a `MaterialPropertyBlock` or
|
|
119
|
+
`Material.SetFloat/SetColor/SetTexture`. Full URP unlit + lit HLSL pass and a Shader Graph
|
|
120
|
+
mapping → `references/unity-and-unreal-shaders.md`.
|
|
138
121
|
|
|
139
122
|
### Unreal 5.x
|
|
140
123
|
|
|
@@ -216,24 +199,27 @@ per engine → `references/effect-recipes.md`.
|
|
|
216
199
|
- **Mobile / tile GPUs**: bandwidth-bound — keep render targets small, avoid mid-pass framebuffer
|
|
217
200
|
reads, and note that `discard` and large full-screen passes break tile hidden-surface removal.
|
|
218
201
|
|
|
219
|
-
##
|
|
202
|
+
## Anti-patterns
|
|
220
203
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
204
|
+
| Anti-pattern | Do instead |
|
|
205
|
+
| --- | --- |
|
|
206
|
+
| Porting a tutorial verbatim from Godot 3, Built-in RP, or pre-5.0 UE | Translate it through the Version contract table first — retired symbols still compile in old guides, not in your project. |
|
|
207
|
+
| Reading a texture or writing a color without minding linear vs sRGB | Author color uniforms as `source_color` (Godot) / sRGB-marked properties and check the space at every read and output — the #1 "looks washed out / too dark" bug. |
|
|
208
|
+
| Using interpolated normals raw, or a normal map straight from the sample | Re-normalize per pixel; unpack with `×2−1` and mind tangent handedness. |
|
|
209
|
+
| Writing the shader before choosing the target surface | Pick `shader_type` / render pipeline / material domain first (2D vs 3D, URP vs HDRP, Surface vs Post Process) — it decides which built-ins and blend modes exist. |
|
|
210
|
+
| Fresnel, normalization, or lighting math in the vertex stage | Only linearly-interpolating work goes per-vertex; exact math stays per-pixel. |
|
|
211
|
+
| `discard`/`clip` as a cheap "make it invisible" | Cull it or scale to zero — `discard` disables early-Z and breaks tile hidden-surface removal on mobile. |
|
|
212
|
+
| Stacking additive/translucent layers until the look works | Count the overdraw: each layer re-shades the same pixels. Prefer opaque, minimize overlap, keep particle fill low. |
|
|
213
|
+
| Full-screen effects via `OnRenderImage`/`Graphics.Blit`, or `SceneTexture` outside the Post Process domain | Use the engine's supported path — URP Renderer Feature / Fullscreen Shader Graph, UE Post Process material, Godot `ColorRect` + `hint_screen_texture` or `CompositorEffect`. |
|
|
230
214
|
|
|
231
215
|
## Related skills
|
|
232
216
|
|
|
233
|
-
- [`godot`](../godot/SKILL.md) / [`unity`](../unity/SKILL.md) / [`unreal`](../unreal/SKILL.md) —
|
|
234
|
-
|
|
235
|
-
- [`gamedev-physics`](../gamedev-physics/SKILL.md) — simulation, collision, rigid bodies
|
|
236
|
-
|
|
217
|
+
- [`godot`](../godot/SKILL.md) / [`unity`](../unity/SKILL.md) / [`unreal`](../unreal/SKILL.md) — gameplay
|
|
218
|
+
code, nodes/components, input, scene wiring; this skill owns the *shading*, not the C#/GDScript/Blueprint around it.
|
|
219
|
+
- [`gamedev-physics`](../gamedev-physics/SKILL.md) — simulation, collision, rigid bodies, character
|
|
220
|
+
controllers (a shader that *fakes* refraction is here; simulating fluid dynamics is not).
|
|
221
|
+
- [`gamedev-shipping`](../gamedev-shipping/SKILL.md) — platform export and shader-variant stripping in
|
|
222
|
+
the build (this skill keeps the per-shader performance work).
|
|
237
223
|
|
|
238
224
|
## Checklist
|
|
239
225
|
|
|
@@ -244,9 +230,3 @@ per engine → `references/effect-recipes.md`.
|
|
|
244
230
|
- [ ] Uniforms/parameters exposed and driven from code or an animation track — not hard-coded.
|
|
245
231
|
- [ ] Performance sanity: overdraw, sample count, and branching considered; mobile precision set if targeted.
|
|
246
232
|
- [ ] Post-process uses the engine's supported full-screen path (not a retired Built-in-RP mechanism).
|
|
247
|
-
|
|
248
|
-
## References
|
|
249
|
-
|
|
250
|
-
- `references/godot-shading-language.md` — shader types, built-ins per type, render_modes, `varying`, screen/depth reads, ShaderMaterial from code.
|
|
251
|
-
- `references/unity-and-unreal-shaders.md` — Unity URP HLSL pass + Shader Graph mapping; Unreal domains, Custom node HLSL, Material Instances.
|
|
252
|
-
- `references/effect-recipes.md` — dissolve, rim/outline, toon/cel, water/flow, force field, hologram — full code per engine.
|
|
@@ -4,13 +4,13 @@ should_trigger:
|
|
|
4
4
|
- prompt: "Write me a dissolve shader in Godot 4 that burns an object away from bottom to top with a glowing orange edge."
|
|
5
5
|
why: "Dissolve is a named recipe and the core use case; Godot 4 .gdshader authoring is owned here."
|
|
6
6
|
- prompt: "How do I make a rim light / fresnel glow on a 3D character in Unity URP?"
|
|
7
|
-
why: "Rim/fresnel is a named recipe; 'how do I make X effect' is
|
|
7
|
+
why: "Rim/fresnel is a named recipe; 'how do I make X effect' is the core shape of a shader request; Unity shader authoring is per-engine mapped here."
|
|
8
8
|
- prompt: "My translucent particle shader tanks the framerate on mobile. How do I fix the overdraw?"
|
|
9
9
|
why: "Shader performance — overdraw, transparency, mobile — is a dedicated section; symptom-only trigger routes here, not to a generic profiler."
|
|
10
10
|
- prompt: "Set up a full-screen post-process effect in Unreal that reads scene depth and draws outlines."
|
|
11
11
|
why: "Post-processing / full-screen effects per engine is a core section; Unreal Post Process material + SceneTexture is covered."
|
|
12
12
|
- prompt: "Cómo hago un shader de agua con refracción y espuma en los bordes."
|
|
13
|
-
why: "Spanish water/flow recipe request;
|
|
13
|
+
why: "Spanish water/flow recipe request; water/flow is a named recipe and matching is by meaning, not by language."
|
|
14
14
|
- prompt: "Convert this toon/cel shading effect from my Godot project to a Unity Shader Graph."
|
|
15
15
|
why: "Toon/cel is a named recipe and cross-engine conversion is an explicit use case; the skill carries a Godot↔Unity↔Unreal map."
|
|
16
16
|
- prompt: "What coordinate space are NORMAL and VIEW in inside a Godot spatial fragment shader, and why does my world-space fresnel look wrong?"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gcp-essentials
|
|
3
|
-
description: "Use when running a small product on
|
|
3
|
+
description: "Use when running a small product on core Google Cloud via the gcloud CLI: a project, Cloud Run deploys, a locked-down Cloud Storage bucket, managed Cloud SQL, and least-privilege IAM wiring them together. NOT AWS (that is `aws-essentials`), NOT the CI pipeline that ships the image (that is `deployment`), NOT Postgres schema/query tuning (that is `postgresdb`)."
|
|
4
4
|
tags: [gcp, cloud-run, cloud-sql, cloud-storage, iam, gcloud, serverless, devops]
|
|
5
5
|
recommends: [aws-essentials, docker, github-actions, secure-coding, postgresdb, deployment, monitoring, backups]
|
|
6
6
|
origin: risco
|
|
@@ -20,12 +20,14 @@ Four primitives carry most products, plus the project/billing scaffold under the
|
|
|
20
20
|
- **Cloud Storage** — object storage (buckets).
|
|
21
21
|
- **Cloud SQL** — managed Postgres/MySQL.
|
|
22
22
|
|
|
23
|
-
Out of scope, route elsewhere: AWS -> `aws-essentials
|
|
24
|
-
|
|
23
|
+
Out of scope, route elsewhere: AWS -> [`../aws-essentials/SKILL.md`](../aws-essentials/SKILL.md).
|
|
24
|
+
Building/shipping the image itself -> [`../docker/SKILL.md`](../docker/SKILL.md)
|
|
25
|
+
/ [`../github-actions/SKILL.md`](../github-actions/SKILL.md) / [`../deployment/SKILL.md`](../deployment/SKILL.md).
|
|
25
26
|
Postgres schema/index/query tuning -> [`../postgresdb/SKILL.md`](../postgresdb/SKILL.md).
|
|
26
27
|
App-level injection/secret-handling review -> [`../secure-coding/SKILL.md`](../secure-coding/SKILL.md).
|
|
27
|
-
Logging/alerting/SLOs as a practice -> `monitoring
|
|
28
|
-
|
|
28
|
+
Logging/alerting/SLOs as a practice -> [`../monitoring/SKILL.md`](../monitoring/SKILL.md).
|
|
29
|
+
Backup strategy as a discipline -> [`../backups/SKILL.md`](../backups/SKILL.md).
|
|
30
|
+
One-click PaaS where you never touch IAM/VPC -> [`../vercel/SKILL.md`](../vercel/SKILL.md)
|
|
29
31
|
/ [`../railway/SKILL.md`](../railway/SKILL.md) / [`../render/SKILL.md`](../render/SKILL.md)
|
|
30
32
|
/ [`../fly-io/SKILL.md`](../fly-io/SKILL.md).
|
|
31
33
|
|
|
@@ -96,8 +98,8 @@ Two hard rules, each with teeth:
|
|
|
96
98
|
Identity Federation for external/CI auth (GitHub Actions). If `... keys create` is
|
|
97
99
|
in your runbook, the runbook is wrong.
|
|
98
100
|
|
|
99
|
-
WIF for keyless CI, SA impersonation, IAM Recommender and
|
|
100
|
-
[`references/iam-and-auth.md`](references/iam-and-auth.md).
|
|
101
|
+
The predefined-role catalog, WIF for keyless CI, SA impersonation, IAM Recommender and
|
|
102
|
+
Conditions live in [`references/iam-and-auth.md`](references/iam-and-auth.md).
|
|
101
103
|
|
|
102
104
|
## 2. Cloud Run
|
|
103
105
|
|
|
@@ -233,8 +235,9 @@ gcloud run deploy api --region=europe-west1 \
|
|
|
233
235
|
```
|
|
234
236
|
|
|
235
237
|
The Cloud SQL **Auth Proxy** (short-lived certs, TLS 1.3) is for connecting from
|
|
236
|
-
*outside* — local dev or a non-serverless host — not for Cloud Run.
|
|
237
|
-
|
|
238
|
+
*outside* — local dev or a non-serverless host — not for Cloud Run. Direct VPC egress vs
|
|
239
|
+
legacy connectors, private IP / PSC, proxy invocation and pooling are in
|
|
240
|
+
[`references/networking-and-sql.md`](references/networking-and-sql.md).
|
|
238
241
|
|
|
239
242
|
## 5. Wire it together
|
|
240
243
|
|
|
@@ -267,6 +270,10 @@ Note the scoping: `cloudsql.client` is project-wide (the role needs it), but the
|
|
|
267
270
|
storage and secret grants are bound to the *specific* bucket and secret, not the
|
|
268
271
|
project. Grant narrow.
|
|
269
272
|
|
|
273
|
+
Copy-paste runbooks for each piece — image build and push, private container deploy,
|
|
274
|
+
attach SQL, mount a secret, full teardown — are in
|
|
275
|
+
[`references/deploy-recipes.md`](references/deploy-recipes.md).
|
|
276
|
+
|
|
270
277
|
## 6. Cost & teardown
|
|
271
278
|
|
|
272
279
|
- Cloud Run scales to zero by default — an idle service costs ~nothing. Keep
|
|
@@ -315,13 +322,3 @@ bash scripts/verify.sh path/to/dir/ # recurse a directory
|
|
|
315
322
|
|
|
316
323
|
It prints `PASS`/`FAIL` per check and exits nonzero on any FAIL. An empty or
|
|
317
324
|
clean target passes (exit 0).
|
|
318
|
-
|
|
319
|
-
## References
|
|
320
|
-
|
|
321
|
-
- [`references/iam-and-auth.md`](references/iam-and-auth.md) — predefined-role catalog,
|
|
322
|
-
Workload Identity Federation for GitHub Actions, SA impersonation, IAM Recommender,
|
|
323
|
-
Conditions.
|
|
324
|
-
- [`references/networking-and-sql.md`](references/networking-and-sql.md) — Direct VPC
|
|
325
|
-
egress vs legacy connectors, Cloud SQL private IP / PSC, Auth Proxy, pooling.
|
|
326
|
-
- [`references/deploy-recipes.md`](references/deploy-recipes.md) — copy-paste runbooks:
|
|
327
|
-
container deploy, attach SQL, mount a secret, budget alert, full teardown.
|