@ericrisco/rsc 0.1.34 → 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 (130) hide show
  1. package/README.md +28 -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/agent-eval/SKILL.md +1 -1
  7. package/skills/analyze/SKILL.md +1 -1
  8. package/skills/brand-voice/SKILL.md +1 -1
  9. package/skills/brand-voice/references/voice-guide-template.md +14 -0
  10. package/skills/building-agents/SKILL.md +2 -2
  11. package/skills/competitor-watch/SKILL.md +9 -4
  12. package/skills/competitor-watch/references/tracker-schema.md +19 -0
  13. package/skills/constitution/references/constitution-template.md +10 -0
  14. package/skills/content-engine/SKILL.md +1 -1
  15. package/skills/content-engine/references/brief-and-pipeline.md +15 -1
  16. package/skills/course-builder/references/grounding-and-scoping.md +23 -0
  17. package/skills/course-storytelling/references/learner-grounding.md +22 -2
  18. package/skills/decision-records/SKILL.md +14 -1
  19. package/skills/decision-records/references/templates.md +20 -0
  20. package/skills/design/references/brand-grounding.md +11 -1
  21. package/skills/game-design/SKILL.md +170 -0
  22. package/skills/game-design/evals/README.md +13 -0
  23. package/skills/game-design/evals/cases.yaml +47 -0
  24. package/skills/game-design/references/mechanics-and-loops.md +78 -0
  25. package/skills/game-design/references/playtesting-and-scope.md +58 -0
  26. package/skills/game-design/references/progression-and-economy.md +70 -0
  27. package/skills/game-storytelling/SKILL.md +159 -0
  28. package/skills/game-storytelling/evals/README.md +28 -0
  29. package/skills/game-storytelling/evals/cases.yaml +51 -0
  30. package/skills/game-storytelling/references/branching-and-state.md +134 -0
  31. package/skills/game-storytelling/references/dialogue-tools.md +117 -0
  32. package/skills/game-storytelling/references/environmental-storytelling.md +71 -0
  33. package/skills/gamedev-multiplayer/SKILL.md +250 -0
  34. package/skills/gamedev-multiplayer/evals/README.md +12 -0
  35. package/skills/gamedev-multiplayer/evals/cases.yaml +44 -0
  36. package/skills/gamedev-multiplayer/references/godot-high-level-multiplayer.md +133 -0
  37. package/skills/gamedev-multiplayer/references/prediction-and-latency.md +104 -0
  38. package/skills/gamedev-multiplayer/references/unity-and-unreal-netcode.md +166 -0
  39. package/skills/gamedev-pathing/SKILL.md +242 -0
  40. package/skills/gamedev-pathing/evals/README.md +14 -0
  41. package/skills/gamedev-pathing/evals/cases.yaml +49 -0
  42. package/skills/gamedev-pathing/references/navmesh-workflow.md +110 -0
  43. package/skills/gamedev-pathing/references/search-algorithms.md +135 -0
  44. package/skills/gamedev-pathing/references/steering-and-avoidance.md +120 -0
  45. package/skills/gamedev-physics/SKILL.md +225 -0
  46. package/skills/gamedev-physics/evals/README.md +12 -0
  47. package/skills/gamedev-physics/evals/cases.yaml +54 -0
  48. package/skills/gamedev-physics/references/character-controllers.md +120 -0
  49. package/skills/gamedev-physics/references/determinism-and-queries.md +124 -0
  50. package/skills/gamedev-physics/references/layers-and-masks.md +115 -0
  51. package/skills/gamedev-shaders/SKILL.md +252 -0
  52. package/skills/gamedev-shaders/evals/README.md +14 -0
  53. package/skills/gamedev-shaders/evals/cases.yaml +45 -0
  54. package/skills/gamedev-shaders/references/effect-recipes.md +205 -0
  55. package/skills/gamedev-shaders/references/godot-shading-language.md +133 -0
  56. package/skills/gamedev-shaders/references/unity-and-unreal-shaders.md +169 -0
  57. package/skills/gamedev-shipping/SKILL.md +236 -0
  58. package/skills/gamedev-shipping/evals/README.md +9 -0
  59. package/skills/gamedev-shipping/evals/cases.yaml +55 -0
  60. package/skills/gamedev-shipping/references/mobile-and-desktop.md +127 -0
  61. package/skills/gamedev-shipping/references/stores-and-ci.md +162 -0
  62. package/skills/gamedev-shipping/references/web-export-headers.md +140 -0
  63. package/skills/godot/SKILL.md +319 -0
  64. package/skills/godot/evals/README.md +13 -0
  65. package/skills/godot/evals/cases.yaml +50 -0
  66. package/skills/godot/references/export-and-testing.md +102 -0
  67. package/skills/godot/references/gdscript-style.md +84 -0
  68. package/skills/godot/references/godot3-to-4-traps.md +89 -0
  69. package/skills/godot/references/nodes-scenes-resources.md +109 -0
  70. package/skills/harness/SKILL.md +3 -3
  71. package/skills/harness/references/daily-curation-automation.md +8 -6
  72. package/skills/harness/references/obsidian-scaffolding.md +16 -9
  73. package/skills/harness/references/wiki-article-template.md +31 -14
  74. package/skills/harness/references/wiki-index-template.md +7 -3
  75. package/skills/harness/references/wiki-protocol.md +120 -54
  76. package/skills/harness/references/wiki-worklog-template.md +5 -1
  77. package/skills/instagram-api/SKILL.md +8 -1
  78. package/skills/instagram-api/references/insights-metrics.md +8 -1
  79. package/skills/knowledge-ops/SKILL.md +9 -9
  80. package/skills/knowledge-ops/evals/cases.yaml +1 -1
  81. package/skills/knowledge-ops/references/gardening-playbook.md +18 -8
  82. package/skills/level-design/SKILL.md +175 -0
  83. package/skills/level-design/evals/README.md +35 -0
  84. package/skills/level-design/evals/cases.yaml +58 -0
  85. package/skills/level-design/references/blockout-to-art.md +118 -0
  86. package/skills/level-design/references/guidance-and-readability.md +152 -0
  87. package/skills/level-design/references/pacing-and-encounters.md +142 -0
  88. package/skills/linkedin-api/SKILL.md +10 -1
  89. package/skills/linkedin-strategy/SKILL.md +12 -0
  90. package/skills/linkedin-strategy/references/wiki-records.md +27 -1
  91. package/skills/marketing/references/brand-grounding.md +22 -2
  92. package/skills/medium-strategy/SKILL.md +12 -0
  93. package/skills/medium-strategy/references/wiki-records.md +39 -1
  94. package/skills/medium-writing/SKILL.md +19 -0
  95. package/skills/plan/references/plan-template.md +12 -1
  96. package/skills/roast-me/tools/adapters/__pycache__/__init__.cpython-312.pyc +0 -0
  97. package/skills/roast-me/tools/adapters/__pycache__/base.cpython-312.pyc +0 -0
  98. package/skills/roast-me/tools/adapters/__pycache__/claude.cpython-312.pyc +0 -0
  99. package/skills/roast-me/tools/adapters/__pycache__/codex.cpython-312.pyc +0 -0
  100. package/skills/roast-me/tools/adapters/__pycache__/gemini.cpython-312.pyc +0 -0
  101. package/skills/roast-me/tools/adapters/__pycache__/registry.cpython-312.pyc +0 -0
  102. package/skills/shortform-packaging/SKILL.md +7 -2
  103. package/skills/shortform-packaging/references/package-templates.md +13 -2
  104. package/skills/shortform-strategy/SKILL.md +30 -6
  105. package/skills/shortform-strategy/references/learning-loop-template.md +9 -1
  106. package/skills/specify/references/spec-template.md +12 -1
  107. package/skills/tiktok-api/SKILL.md +6 -2
  108. package/skills/tiktok-api/references/wiki-schema.md +38 -4
  109. package/skills/unity/SKILL.md +282 -0
  110. package/skills/unity/evals/README.md +8 -0
  111. package/skills/unity/evals/cases.yaml +43 -0
  112. package/skills/unity/references/build-and-platforms.md +65 -0
  113. package/skills/unity/references/input-system.md +102 -0
  114. package/skills/unity/references/lifecycle-deep-dive.md +75 -0
  115. package/skills/unreal/SKILL.md +270 -0
  116. package/skills/unreal/evals/README.md +12 -0
  117. package/skills/unreal/evals/cases.yaml +45 -0
  118. package/skills/unreal/references/blueprint-cpp-parity.md +109 -0
  119. package/skills/unreal/references/gameplay-framework.md +95 -0
  120. package/skills/unreal/references/packaging.md +83 -0
  121. package/skills/verify/SKILL.md +11 -1
  122. package/skills/youtube-api/SKILL.md +7 -2
  123. package/skills/youtube-api/references/wiki-schema.md +25 -4
  124. package/skills/youtube-packaging/SKILL.md +10 -2
  125. package/skills/youtube-packaging/references/description-and-chapters.md +70 -2
  126. package/skills/youtube-strategy/SKILL.md +9 -2
  127. package/skills/youtube-strategy/references/wiki-records.md +39 -6
  128. package/skills/youtube-strategy/scripts/verify.sh +4 -0
  129. package/skills/youtube-thumbnails/SKILL.md +10 -5
  130. package/skills/youtube-thumbnails/references/experiment-log-format.md +28 -2
@@ -0,0 +1,84 @@
1
+ # GDScript style & formatting cheat-sheet (Godot 4.x)
2
+
3
+ Mirrors the official GDScript style guide. When in doubt, run the editor's built-in formatter
4
+ (Ctrl/Cmd+Shift+I) and `gdformat` (from `gdtoolkit`) in CI.
5
+
6
+ ## Naming
7
+
8
+ | Thing | Case | Example |
9
+ | --- | --- | --- |
10
+ | File (script/scene) | `snake_case` | `player_controller.gd`, `main_menu.tscn` |
11
+ | `class_name` / type | `PascalCase` | `class_name EnemyStats` |
12
+ | Node name in tree | `PascalCase` | `HealthBar`, `AttackTimer` |
13
+ | Variable / function | `snake_case` | `var max_health`, `func take_damage()` |
14
+ | Signal | `snake_case`, past tense | `signal health_depleted` |
15
+ | Constant | `CONSTANT_CASE` | `const MAX_SPEED := 400.0` |
16
+ | Enum type / members | `PascalCase` / `CONSTANT_CASE` | `enum State { IDLE, RUN }` |
17
+ | Private (convention) | leading underscore | `var _internal_timer` |
18
+ | Virtual/lifecycle | leading underscore | `_ready`, `_process`, `_on_body_entered` |
19
+
20
+ ## Formatting
21
+
22
+ - **Tabs** for indentation (not spaces). Editor default.
23
+ - Lines **< 100 columns**.
24
+ - One space around binary operators (`a + b`, `x := 1`), none inside call parens.
25
+ - Two blank lines between functions at top level; one inside classes as needed.
26
+ - Prefer `:=` (inferred) when the RHS makes the type obvious; `: Type =` when it does not.
27
+
28
+ ## Typed by default
29
+
30
+ ```gdscript
31
+ var speed: float = 300.0 # explicit annotation
32
+ var dir := Vector2.ZERO # inferred
33
+ var slots: Array[Item] = [] # typed collection
34
+ const GRAVITY := 980.0
35
+
36
+ func heal(amount: int) -> void: # typed params AND return
37
+ _health = mini(_health + amount, _max_health)
38
+
39
+ func find_target() -> Node2D: # return type declared
40
+ return get_tree().get_first_node_in_group("player")
41
+ ```
42
+
43
+ - Declare `-> void` on functions that return nothing; declare the real type otherwise.
44
+ - Use `as` for safe downcasts: `var e := body as Enemy` → `null` on mismatch (no crash).
45
+ - Avoid untyped `var x` and `Variant` params — they disable the compiler's checks and the VM's
46
+ typed fast paths.
47
+
48
+ ## Script layout order (recommended top-to-bottom)
49
+
50
+ 1. `@tool` (if any) — must be the very first line.
51
+ 2. `class_name` then `extends` (or `extends` alone).
52
+ 3. `## docstring` comment.
53
+ 4. `signal` declarations.
54
+ 5. `enum` / `const`.
55
+ 6. `@export` vars, then plain member vars, then `@onready` vars.
56
+ 7. Built-in virtuals: `_init`, `_ready`, `_process`, `_physics_process`, `_input`, …
57
+ 8. Public methods, then private (`_underscore`) methods, then signal handlers (`_on_*`).
58
+
59
+ ```gdscript
60
+ @tool
61
+ class_name Turret extends Node2D
62
+ ## Auto-aiming turret; @export the fire rate in the inspector.
63
+
64
+ signal fired(at: Vector2)
65
+
66
+ const MAX_RANGE := 600.0
67
+ enum Mode { IDLE, TRACKING }
68
+
69
+ @export var fire_rate := 2.0
70
+ var _cooldown := 0.0
71
+ @onready var muzzle: Marker2D = %Muzzle
72
+
73
+ func _physics_process(delta: float) -> void:
74
+ _cooldown = maxf(_cooldown - delta, 0.0)
75
+
76
+ func _on_area_entered(_area: Area2D) -> void:
77
+ pass
78
+ ```
79
+
80
+ ## Common built-in math helpers (Godot 4 names)
81
+
82
+ `absf/absi`, `minf/mini`, `maxf/maxi`, `clampf/clampi`, `snappedf`, `lerpf`, `move_toward`,
83
+ `deg_to_rad` / `rad_to_deg`, `randf_range`, `randi_range`. The unsuffixed `abs/min/max/clamp` still
84
+ work on Variants but the typed suffixed forms are faster and clearer.
@@ -0,0 +1,89 @@
1
+ # Godot 3 → 4.x migration ban-list (full table)
2
+
3
+ Godot 4 is a hard break from 3.x. The engine ships a project converter, but it does **not** catch
4
+ everything — and an agent generating fresh code must simply never emit the left column. Use this as
5
+ the authoritative reference when porting or reviewing.
6
+
7
+ ## Won't-parse renames (hard errors)
8
+
9
+ | Godot 3 | Godot 4.x | Note |
10
+ | --- | --- | --- |
11
+ | `yield(obj, "signal")` | `await obj.signal` | Coroutines are now `await`; the function must not need `yield`'s return-value trick. |
12
+ | `yield(get_tree().create_timer(1),"timeout")` | `await get_tree().create_timer(1.0).timeout` | |
13
+ | `onready var` | `@onready var` | Annotation. |
14
+ | `export var` / `export(int) var` | `@export var` / `@export_range(...) var` | Typed annotations replace the `export(Type)` hint syntax. |
15
+ | `tool` | `@tool` | Must be the first line. |
16
+ | `remote`/`master`/`puppet func` | `@rpc(...)` annotations | Networking model changed entirely. |
17
+ | `setget set_fn, get_fn` | `set(v): ...` / `get: ...` inline accessors | |
18
+
19
+ ## Node / class renames
20
+
21
+ | Godot 3 | Godot 4.x |
22
+ | --- | --- |
23
+ | `Spatial` | `Node3D` |
24
+ | `KinematicBody` / `KinematicBody2D` | `CharacterBody3D` / `CharacterBody2D` |
25
+ | `Area` | `Area3D` |
26
+ | `RigidBody` / `StaticBody` | `RigidBody3D` / `StaticBody3D` |
27
+ | `Sprite` | `Sprite2D` |
28
+ | `Sprite3D` | `Sprite3D` (unchanged) |
29
+ | `AnimatedSprite` | `AnimatedSprite2D` |
30
+ | `CollisionShape` | `CollisionShape3D` |
31
+ | `Camera` | `Camera3D` |
32
+ | `Light2D` (old) / `Light` | `PointLight2D` / `DirectionalLight2D` / `OmniLight3D` etc. |
33
+ | `Viewport` (as node) | `SubViewport` (embedded) |
34
+ | `YSort` (node) | `y_sort_enabled` property on `Node2D`/`CanvasItem` |
35
+ | `ARVROrigin` / `ARVRCamera` | `XROrigin3D` / `XRCamera3D` |
36
+ | `Reference` | `RefCounted` |
37
+ | `TileMap` | `TileMapLayer` (one per layer; `TileMap` deprecated 4.3+) |
38
+
39
+ ## Method / API changes
40
+
41
+ | Godot 3 | Godot 4.x |
42
+ | --- | --- |
43
+ | `scene.instance()` | `scene.instantiate()` |
44
+ | `move_and_slide(velocity, up_direction)` | set `velocity` property → `move_and_slide()` (no args) |
45
+ | `move_and_slide_with_snap(...)` | set `floor_snap_length` → `move_and_slide()` |
46
+ | `connect("sig", obj, "method", [args])` | `obj.sig.connect(method.bind(args))` (Callable) |
47
+ | `disconnect("sig", obj, "method")` | `obj.sig.disconnect(method)` |
48
+ | `emit_signal("sig", a)` | `sig.emit(a)` (string form still exists but prefer the property) |
49
+ | `is_connected("sig", obj, "m")` | `sig.is_connected(m)` |
50
+ | `call_deferred("method", a)` | `method.bind(a).call_deferred()` or `call_deferred("method", a)` |
51
+ | `File.new()` + `open()` | `FileAccess.open(path, FileAccess.READ)` |
52
+ | `Directory.new()` | `DirAccess.open(path)` / `DirAccess.dir_exists_absolute(...)` |
53
+ | `OS.get_ticks_msec()` | `Time.get_ticks_msec()` |
54
+ | `OS.get_datetime()` | `Time.get_datetime_dict_from_system()` |
55
+ | `PoolByteArray` / `PoolStringArray` / `PoolVector2Array` | `PackedByteArray` / `PackedStringArray` / `PackedVector2Array` |
56
+ | `Tween` node + `interpolate_property` | `var t := create_tween(); t.tween_property(node, "position", target, 0.5)` |
57
+ | `rand_range(a, b)` | `randf_range(a, b)` (float) / `randi_range(a, b)` (int) |
58
+ | `deg2rad` / `rad2deg` | `deg_to_rad` / `rad_to_deg` |
59
+ | `stepify(x, s)` | `snapped(x, s)` |
60
+ | `.empty()` | `.is_empty()` |
61
+ | `get_node("Path")` still valid | prefer `%UniqueName` for refactor-safety |
62
+ | `KEY_*` / input constants mostly renamed | check `Key`, `MouseButton` enums |
63
+
64
+ ## Silent behavior changes (compile clean, act wrong)
65
+
66
+ - **`Array.slice(begin, end, step, deep)`** — `end` is **exclusive** in Godot 4 (was inclusive in 3).
67
+ `[10,20,30,40].slice(1,3)` → `[20,30]`.
68
+ - **`Camera2D.zoom`** — meaning **inverted**. Larger value = zoom **in**. `zoom = Vector2(2,2)`
69
+ magnifies 2×; in Godot 3 that zoomed out. To zoom out now, use values **below** 1.
70
+ - **Y-sort** is a property (`y_sort_enabled`), not a node — porting a `YSort` parent silently loses
71
+ sorting unless you set the property.
72
+ - **Physics interpolation / gravity** — read gravity via `get_gravity()` (2D/3D) or
73
+ `ProjectSettings`; the old default constants changed.
74
+ - **Signal argument order** on some built-in signals changed; verify against the 4.x docs, don't
75
+ assume the 3.x signature.
76
+ - **`_ready`/`_process` no longer auto-call the base** — you must `super()` when extending a script
77
+ that defines them.
78
+ - **Integer division** with typed ints truncates as expected; mixing float/int in Godot 4 follows
79
+ stricter typed rules — annotate to avoid surprises.
80
+
81
+ ## Porting workflow
82
+
83
+ 1. Open the Godot 3 project in Godot 4 → run the built-in **Project Converter** (backs up first).
84
+ 2. Fix red parse errors top-down (renames above).
85
+ 3. Search the codebase for each string-form `connect(`, `yield(`, `.instance()`, `File.new`,
86
+ `Directory.new`, `Pool*Array`, `move_and_slide(` with args — the converter misses some.
87
+ 4. Fix the silent-breakers deliberately (slice bounds, Camera2D zoom, y-sort) — tests or a manual
88
+ pass, since nothing errors.
89
+ 5. Re-open every scene once; a converter-mangled `.tscn` fails loudly in the editor.
@@ -0,0 +1,109 @@
1
+ # Nodes, scenes, scripts & custom Resources (Godot 4.x)
2
+
3
+ The four building blocks and when each is the right tool. Getting this decomposition right is what
4
+ separates a maintainable Godot project from a monolithic scene that nobody can touch.
5
+
6
+ ## The mental model
7
+
8
+ - **Node** — a live object in the running tree. It has a transform (2D/3D), can render, process,
9
+ collide, receive input. Everything on screen is a node. Pick the most specific typed subclass
10
+ (`Sprite2D`, `Area3D`, `CharacterBody2D`, `Timer`, `AudioStreamPlayer`).
11
+ - **Scene** (`.tscn`) — a saved tree of nodes with a designated **root**, instanceable N times. The
12
+ reusable unit of a Godot game. A scene can instance other scenes (composition).
13
+ - **Script** (`.gd` / `.cs`) — code attached to one node, giving it behavior. Attach to the scene
14
+ root; treat children as parts the root drives.
15
+ - **Resource** (`.tres` / `.res`) — a reference-counted **data** object, not in the tree. Textures,
16
+ audio, materials are Resources; so are your **custom** data classes.
17
+
18
+ ## Composition over inheritance / deep trees
19
+
20
+ Prefer assembling small scenes over one giant tree or a deep script inheritance chain.
21
+
22
+ - A `Player` scene = `CharacterBody2D` root + `Sprite2D` + `CollisionShape2D` + `Camera2D` +
23
+ instanced `HealthComponent` + `HurtboxComponent` sub-scenes.
24
+ - Behaviors as **components**: a `HealthComponent` (its own scene/script exposing `signal died`) can
25
+ be dropped onto a player, an enemy, or a crate — no shared base class needed.
26
+ - Reach for `extends MyBase` only for genuine "is-a" specialization; reach for composed child nodes
27
+ for "has-a" behavior. The latter is the Godot-idiomatic default.
28
+
29
+ ## `class_name` — when to register a global type
30
+
31
+ ```gdscript
32
+ class_name HealthComponent extends Node
33
+ signal died
34
+ @export var max_health := 100
35
+ var _current := max_health
36
+ ```
37
+
38
+ - Register (`class_name`) reusable scripts and **all** custom Resources — it enables `is`/`as`
39
+ checks, `HealthComponent.new()`, and a proper inspector type/slot.
40
+ - Skip it for one-off scene-root scripts that nothing else references by type.
41
+ - Names are global and must be unique across the project.
42
+
43
+ ## Custom Resources — typed game data
44
+
45
+ Use a custom `Resource` instead of loose `Dictionary`/JSON whenever you have structured game data:
46
+ stats, items, dialogue lines, wave definitions, ability configs. You get inspector editing, type
47
+ safety, `@export` slots, and save/load for free.
48
+
49
+ ```gdscript
50
+ # item.gd
51
+ class_name Item extends Resource
52
+ @export var display_name: String = ""
53
+ @export var icon: Texture2D
54
+ @export var max_stack: int = 99
55
+ @export var value: int = 0
56
+ ```
57
+ ```gdscript
58
+ # Use it as a typed @export slot on any node:
59
+ @export var starting_items: Array[Item] = []
60
+
61
+ # Create/save/load in code:
62
+ var potion := Item.new()
63
+ potion.display_name = "Potion"
64
+ ResourceSaver.save(potion, "res://data/potion.tres")
65
+ var loaded := load("res://data/potion.tres") as Item
66
+ ```
67
+
68
+ **Gotcha — shared vs unique**: a Resource assigned in the inspector is **shared by reference** across
69
+ all instances by default. If each node must own its copy (e.g. runtime-mutated stats), enable
70
+ **Local to Scene** on the resource, or `duplicate()` it in `_ready()`. Otherwise mutating one
71
+ enemy's `stats.health` mutates every enemy sharing that `.tres`.
72
+
73
+ ## `preload` vs `load`
74
+
75
+ | | `preload("res://x")` | `load("res://x")` |
76
+ | --- | --- | --- |
77
+ | Resolved | parse/compile time | runtime, when the line runs |
78
+ | Path | must be a constant literal | can be a variable/computed |
79
+ | Use for | assets you always need; breaks fast if the path is wrong | dynamic/optional assets, avoiding circular preloads |
80
+ | Returns | the Resource/`PackedScene` | same |
81
+
82
+ ```gdscript
83
+ const BULLET := preload("res://bullet.tscn") # PackedScene, baked in
84
+ func shoot() -> void:
85
+ var b := BULLET.instantiate() # -> a Node
86
+ add_child(b)
87
+
88
+ # runtime path
89
+ var scene := load("res://enemies/%s.tscn" % enemy_id) as PackedScene
90
+ ```
91
+
92
+ ## Instancing & freeing lifecycle
93
+
94
+ - `PackedScene.instantiate()` → a detached node; add it with `add_child(node)` (or
95
+ `add_sibling`) to bring it into the tree and trigger `_ready`.
96
+ - Free with `queue_free()` (deferred to end of frame — safe during signals/physics). Avoid `free()`
97
+ unless you know the node is out of the tree and not mid-callback.
98
+ - After freeing, guard any retained reference with `is_instance_valid(node)` before touching it.
99
+ - `add_child(node, true)` forces a readable unique name; useful when spawning many of one scene.
100
+
101
+ ## `.tscn` / `.tres` are strict text — validation rule
102
+
103
+ Both formats are line-oriented with a header (`[gd_scene load_steps=N format=3 ...]`),
104
+ `[ext_resource ...]` / `[sub_resource ...]` blocks, and `[node ...]` / property lines. A wrong
105
+ `load_steps` count, a dangling `ExtResource("x")` id, or a malformed `[node]` path makes Godot
106
+ refuse to open the file. **Do not machine-generate or hand-edit these beyond trivial value tweaks,
107
+ and always open the project in the editor once before relying on a changed scene** — the editor is
108
+ the only reliable validator. Build data-Resources in code + `ResourceSaver.save()` instead of
109
+ writing `.tres` by hand.
@@ -11,7 +11,7 @@ profiles: [minimal, core, full]
11
11
  The **harness** is the control plane of a workspace. A workspace need not be code: it can be a company, an ops desk, a legal archive, a personal knowledge vault. Whatever it is, the harness is the durable apparatus that keeps it operable and legible, made of three parts:
12
12
 
13
13
  - **`01-TOOLS/<PROVIDER>/`** — the operational tooling layer. One folder per external provider, co-locating credentials (`.env`) with the scripts that consume them. Each tool ships a working `test_connection` against the real API.
14
- - **`02-DOCS/`** — the **Karpathy chaos→knowledge engine**: a domain-agnostic LLM wiki (`inbox/` + `raw/` + `raw/worklog/` + `wiki/` + `wiki/index.md` + `wiki/log.md` + `wiki/gaps.md` + `wiki/scores.json` + the `.base` views), fully embedded in this skill. It feeds from **two on-ramps**: (1) the user drops **any raw file in any format** (PDF, image, CSV, JSON, txt, html…) into `inbox/`, and an **Auto-Ingest Sweep** ("the agent goes for a walk") extracts, classifies, cross-links, and compiles it — and goes further, **discovering un-ingested documents anywhere in the workspace** (a stray `/transcripts`, `/facturas`…), bounded by `.rscignore` and de-duplicated by the `wiki/.ingested.json` ledger, fired automatically at SessionStart (when the inbox has material) and by the daily cron. Ingest is non-destructive (originals are copied, never moved); removing an emptied folder needs explicit consent; (2) a **Worklog Sweep** captures **what we do** — every meaningful session of work is itself a `raw` source (`raw/worklog/`) compiled into the wiki, fired by a `PreCompact`/`SessionEnd` hook, by an explicit milestone (a commit), or by the daily curation automation (`references/daily-curation-automation.md`). The wiki is **Obsidian-native**: wikilinks, YAML frontmatter (Properties), readable filenames, and `.base` views give a real graph + live tables — structure, **not vector DB / embeddings / RAG**. The agent writes it; the human reads it in Obsidian. See `references/wiki-protocol.md` for the protocol, `references/ingest-formats.md` for the multiformat Fetch, `references/wiki-worklog-template.md` for the work capture, and `references/obsidian-scaffolding.md` for the vault scaffolding. Topics are inferred from content (`finanzas/`, `legal/`, `crm/`…), never hardcoded. The wiki **self-improves continuously**: every Ingest, Sweep and Query triggers a Maintenance Pass (deterministic lint, score recomputation, gap detection, Related/See-Also sweep), and every N interactions a Micro-Improve runs. Deep Improve runs on explicit request or via the scheduled daily curation. No external skill needed.
14
+ - **`02-DOCS/`** — the **Karpathy chaos→knowledge engine**: a domain-agnostic LLM wiki (`inbox/` + `raw/` + `raw/worklog/` + `wiki/` + `wiki/index.md` + `wiki/log.md` + `wiki/gaps.md` + `wiki/scores.json` + the `.base` views), fully embedded in this skill. It feeds from **two on-ramps**: (1) the user drops **any raw file in any format** (PDF, image, CSV, JSON, txt, html…) into `inbox/`, and an **Auto-Ingest Sweep** ("the agent goes for a walk") extracts, classifies, cross-links, and compiles it — and goes further, **discovering un-ingested documents anywhere in the workspace** (a stray `/transcripts`, `/facturas`…), bounded by `.rscignore` and de-duplicated by the `wiki/.ingested.json` ledger, fired automatically at SessionStart (when the inbox has material) and by the daily cron. Ingest keeps the repo clean: a loose file it ingests at the workspace root (or anything in `inbox/`) is **moved into `raw/`** (relocated, never deleted — a dropped PDF ends up in `raw/`, not at the root), while files inside a user-maintained folder are copied and consolidation is proposed; removing a redundant folder needs explicit consent; (2) a **Worklog Sweep** captures **what we do** — every meaningful session of work is itself a `raw` source (`raw/worklog/`) compiled into the wiki, fired by a `PreCompact`/`SessionEnd` hook, by an explicit milestone (a commit), or by the daily curation automation (`references/daily-curation-automation.md`). The `wiki/` is a **100%-OKF-v0.1 bundle** (Google's [Open Knowledge Format](https://github.com/GoogleCloudPlatform/knowledge-catalog/tree/main/okf)) AND an **Obsidian-native** vault at the same time — standard markdown links, OKF-standard YAML frontmatter (Properties), readable filenames, and `.base` views give a real graph + live tables — structure, **not vector DB / embeddings / RAG**. The agent writes it; the human reads it in Obsidian. See `references/wiki-protocol.md` for the protocol, `references/ingest-formats.md` for the multiformat Fetch, `references/wiki-worklog-template.md` for the work capture, and `references/obsidian-scaffolding.md` for the vault scaffolding. Topics are inferred from content (`finanzas/`, `legal/`, `crm/`…), never hardcoded. The wiki **self-improves continuously**: every Ingest, Sweep and Query triggers a Maintenance Pass (deterministic lint, score recomputation, gap detection, Related/See-Also sweep), and every N interactions a Micro-Improve runs. Deep Improve runs on explicit request or via the scheduled daily curation. No external skill needed.
15
15
  - **The Knowledge map** — the `## Knowledge map` section of the root `CLAUDE.md` that indexes the wiki (including the `harness/` topic) and is read by every other skill before it works in its area.
16
16
 
17
17
  `harness` is the **protagonist concept**. `init` is the bootstrap front door — it gauges the user, drafts the profile, and hands off the first scaffold. THIS skill (`harness`) is the **ongoing control**: it audits, migrates, scaffolds, sweeps the inbox, and keeps the wiki, the tooling and the Knowledge map honest over the life of the workspace. It also generates root `CLAUDE.md` and `AGENTS.md`, and migrates legacy `XX-*` numbered folders into the canonical layout.
@@ -105,7 +105,7 @@ harness/
105
105
  │ ├── inbox-readme-template.md ← the inbox/README.md drop-zone contract
106
106
  │ ├── wiki-raw-template.md ← format for raw/<topic>/*.md
107
107
  │ ├── wiki-worklog-template.md ← format for raw/worklog/*.md (work-driven capture)
108
- │ ├── wiki-article-template.md ← format for wiki/<topic>/*.md (Obsidian frontmatter + wikilinks)
108
+ │ ├── wiki-article-template.md ← format for wiki/<topic>/*.md (OKF frontmatter + markdown links)
109
109
  │ ├── wiki-index-template.md ← format for wiki/index.md (machine catalog; .base = human nav)
110
110
  │ ├── obsidian-scaffolding.md ← .base views, .gitignore, attachments, .obsidian config
111
111
  │ ├── daily-curation-automation.md ← portable scheduled compounding pass (the third trigger)
@@ -356,7 +356,7 @@ If any of these occur, stop and report:
356
356
  - `references/inbox-readme-template.md` — the `inbox/README.md` drop-zone contract shown to the user.
357
357
  - `references/wiki-raw-template.md` — format for `02-DOCS/raw/<topic>/*.md`.
358
358
  - `references/wiki-worklog-template.md` — format for `02-DOCS/raw/worklog/*.md` (the work-driven capture; the session as a raw source).
359
- - `references/wiki-article-template.md` — format for `02-DOCS/wiki/<topic>/*.md` (Obsidian frontmatter + wikilinks + `## Related`).
359
+ - `references/wiki-article-template.md` — format for `02-DOCS/wiki/<topic>/*.md` (OKF v0.1 frontmatter + relative markdown links + `## Related`).
360
360
  - `references/wiki-index-template.md` — format for `02-DOCS/wiki/index.md` (machine catalog; the `.base` views are the human navigation).
361
361
  - `references/obsidian-scaffolding.md` — the vault scaffolding: `.base` views, `.gitignore`, `attachments/`, `.obsidian` config (no vector DB / RAG).
362
362
  - `references/daily-curation-automation.md` — portable scheduled compounding pass; on Claude Code wired via the `schedule` skill.
@@ -39,12 +39,14 @@ Run the daily curation pass for this 02-DOCS second brain.
39
39
 
40
40
  Use the harness wiki-protocol.md as the contract. First run the Auto-Ingest Sweep:
41
41
  process inbox/, then scan the workspace (minus .rscignore) for un-ingested documents,
42
- ingest the clearly-documentary folders (copy originals, never move), record them in
43
- wiki/.ingested.json, and list ambiguous folders as proposals (do not grab them).
44
- Then compile pending raw/worklog/ material into wiki/ pages (update existing before
45
- creating new), keep frontmatter + wikilinks consistent, append significant decisions
46
- to wiki/harness/decisions.md, refresh the .base-backed navigation, recompute
47
- scores.json + the score: property, and append a dated entry to wiki/log.md.
42
+ applying Clean-as-you-go (move loose root-level + inbox files into raw/ after a
43
+ verified ingest; copy files nested in user-maintained folders and propose
44
+ consolidation), record them in wiki/.ingested.json, and list ambiguous folders as
45
+ proposals (do not grab them). Then compile pending raw/worklog/ material into wiki/
46
+ pages (update existing before creating new), keep frontmatter + relative markdown
47
+ links OKF-consistent, append significant decisions to wiki/harness/decisions.md,
48
+ refresh the .base-backed navigation, recompute scores.json + the score: property,
49
+ and prepend a dated entry (newest first) to wiki/log.md.
48
50
 
49
51
  Be conservative. If the topic map no longer fits, record a recommendation in
50
52
  wiki/gaps.md or a page's Open Questions instead of moving large parts of the
@@ -31,17 +31,24 @@ not bundled with a specific raw source. Link them from the page that depends on
31
31
  them. Source-bundled originals stay in `raw/<topic>/_originals/`.
32
32
  ```
33
33
 
34
- ## `02-DOCS/.obsidian/app.json` (attachment folder)
34
+ ## `02-DOCS/.obsidian/app.json` (attachment folder + OKF link mode)
35
35
 
36
36
  ```json
37
37
  {
38
38
  "attachmentFolderPath": "attachments",
39
- "newLinkFormat": "shortest",
40
- "useMarkdownLinks": false
39
+ "newLinkFormat": "relative",
40
+ "useMarkdownLinks": true,
41
+ "alwaysUpdateLinks": true
41
42
  }
42
43
  ```
43
44
 
44
- `useMarkdownLinks: false` makes new internal links wikilinks. `userIgnoreFilters`
45
+ `useMarkdownLinks: true` makes new internal links **standard markdown links**, not
46
+ wikilinks — this is what keeps `wiki/` a 100%-OKF-conformant bundle (OKF consumers
47
+ follow markdown links; wikilinks `[[...]]` are non-conformant). `newLinkFormat:
48
+ relative` writes paths relative to the current file (`../topic/page.md`), which OKF
49
+ supports and which resolves both in Obsidian and in any OKF consumer.
50
+ `alwaysUpdateLinks: true` makes Obsidian rewrite those relative links automatically
51
+ on rename, so links survive moves the way wikilinks used to. `userIgnoreFilters`
45
52
  (Settings → Files & Links → Excluded files) should hide noise from search/graph:
46
53
  `raw/_originals/`, `inbox/_processed/`, `audits/`.
47
54
 
@@ -59,7 +66,7 @@ filters:
59
66
  views:
60
67
  - type: table
61
68
  name: All Articles
62
- order: [file.name, topic, status, score, updated]
69
+ order: [file.name, topic, status, score, timestamp]
63
70
  sort:
64
71
  - property: score
65
72
  direction: DESC
@@ -74,9 +81,9 @@ filters:
74
81
  views:
75
82
  - type: table
76
83
  name: Worklog
77
- order: [file.name, topic, date, status]
84
+ order: [file.name, topic, timestamp, status]
78
85
  sort:
79
- - property: date
86
+ - property: timestamp
80
87
  direction: DESC
81
88
  ```
82
89
 
@@ -89,8 +96,8 @@ filters:
89
96
  views:
90
97
  - type: table
91
98
  name: Decisions
92
- order: [file.name, topic, status, updated]
99
+ order: [file.name, topic, status, timestamp]
93
100
  sort:
94
- - property: updated
101
+ - property: timestamp
95
102
  direction: DESC
96
103
  ```
@@ -1,19 +1,23 @@
1
1
  ---
2
+ # OKF v0.1 standard surface — `type` is the only REQUIRED field (non-empty).
3
+ type: article
2
4
  title: {Title}
3
- aliases: [{old-slug}]
5
+ description: {One-sentence summary, for previews + search.}
6
+ resource: {URL or path to the underlying source/asset — omit the line if none}
4
7
  tags: []
5
- type: article
8
+ timestamp: {YYYY-MM-DDTHH:MM:SSZ}
9
+ # rsc custom fields (OKF allows any; conformant consumers preserve unknown keys)
10
+ aliases: [{old-slug}]
6
11
  topic: {topic}
7
12
  status: draft
8
13
  sources: []
9
- updated: {YYYY-MM-DD}
10
14
  score: 0.0
11
15
  ---
12
16
 
13
17
  # {Title}
14
18
 
15
19
  > Sources: {Author1, YYYY-MM-DD; Author2, YYYY-MM-DD}
16
- > Raw: [[{raw-source-1}]]; [[{raw-source-2}]]
20
+ > Raw: [{raw-source-1}](../../raw/{topic}/{raw-source-1}.md); [{raw-source-2}](../../raw/{topic}/{raw-source-2}.md)
17
21
 
18
22
  ## Overview
19
23
 
@@ -25,19 +29,32 @@ score: 0.0
25
29
 
26
30
  ## Related
27
31
 
28
- {OPTIONAL — include only when cross-references exist. Maintained during lint. Use wikilinks so the link survives renames and shows in the Obsidian graph + backlinks:
29
- - Same or different topic: `- [[Other Article]] — why it connects.`
30
- - With display text: `- [[Other Article|how we say it here]] — why it connects.`}
32
+ {OPTIONAL — include only when cross-references exist. Maintained during lint. Use
33
+ standard markdown links (OKF-conformant — they ARE the knowledge graph; an OKF
34
+ consumer follows them, and the Obsidian graph + backlinks render them too):
35
+ - Same topic: `- [Other Article](./other-article.md) — why it connects.`
36
+ - Different topic: `- [Other Article](../other-topic/other-article.md) — why it connects.`
37
+ - With display text: `- [how we say it here](../other-topic/other-article.md) — why it connects.`}
31
38
 
32
39
  <!--
33
- FRONTMATTER CONTRACT (this is what powers Obsidian Properties + Bases + graph):
34
- - title human-readable; the H1 matches it.
35
- - aliases keep the old kebab slug here so pre-migration links/wikilinks still resolve.
36
- - tags cross-cutting qualities ONLY — never the main category (that is `topic`).
37
- - type article | decision | worklog | brief | spec | profile
40
+ FRONTMATTER CONTRACT — OKF v0.1 conformant. Powers OKF consumers AND Obsidian
41
+ Properties + Bases + graph (same file, no translation).
42
+ OKF standard surface:
43
+ - type REQUIRED, non-empty. article | decision | worklog | brief | spec | profile.
44
+ (OKF type values are not registered centrally; consumers tolerate unknown ones.)
45
+ - title human-readable; the H1 matches it. Consumers may derive from filename if absent.
46
+ - description single-sentence summary for previews/search.
47
+ - resource URI/path to the underlying asset this concept documents (omit if none).
48
+ - tags cross-cutting qualities ONLY — never the main category (that is `topic`).
49
+ - timestamp ISO 8601 datetime of the last meaningful edit (e.g. 2026-06-28T14:30:00Z).
50
+ rsc custom fields (allowed by OKF; never required for conformance):
51
+ - aliases keep the old kebab slug here so pre-migration links still resolve.
38
52
  - topic the wiki/<topic>/ folder, one level. Inferred from content, never hardcoded.
39
53
  - status draft | stable | stale (lifecycle; filterable in a Base).
40
- - sources wikilinks to raw/ pages this was distilled from (cite your evidence).
41
- - updated YYYY-MM-DD of the last meaningful edit.
54
+ - sources markdown links to raw/ pages this was distilled from (cite your evidence).
42
55
  - score mirror of scores.json, written by the Maintenance Pass (single writer → no drift).
56
+
57
+ LINKS: standard markdown links only — NEVER wikilinks ([[...]]). Relative paths
58
+ (./same-topic.md, ../other-topic/page.md, ../../raw/<topic>/<file>.md). This is
59
+ what keeps wiki/ a portable, 100%-OKF-conformant bundle.
43
60
  -->
@@ -1,5 +1,9 @@
1
1
  # Knowledge Base Index
2
2
 
3
+ > **OKF v0.1 reserved file** — `index.md` carries **no frontmatter** (it is a
4
+ > directory listing for progressive disclosure, per the OKF spec). Links are
5
+ > standard markdown, relative to this file (`topic/article.md`), NEVER wikilinks.
6
+ >
3
7
  > **Human navigation lives in the `.base` views** (`Articles.base`, `Worklog.base`,
4
8
  > `Decisions.base`) — live tables over frontmatter, sorted by score/status/date.
5
9
  > This index is the **machine-readable catalog + fallback** the agent maintains;
@@ -11,8 +15,8 @@
11
15
 
12
16
  | Article | Summary | Updated | Score |
13
17
  |---------|---------|---------|-------|
14
- | [[{Article Title}]] | {One-line summary} | {YYYY-MM-DD} | {N.N} |
15
- | [[{Archived Article}]] | [Archived] {One-line summary} | {YYYY-MM-DD} | {N.N} |
18
+ | [{Article Title}]({topic-name}/{article-file}.md) | {One-line summary} | {YYYY-MM-DD} | {N.N} |
19
+ | [{Archived Article}]({topic-name}/{archived-file}.html) | [Archived] {One-line summary} | {YYYY-MM-DD} | {N.N} |
16
20
 
17
21
  ## {another-topic}
18
22
 
@@ -20,7 +24,7 @@
20
24
 
21
25
  | Article | Summary | Updated | Score |
22
26
  |---------|---------|---------|-------|
23
- | [[{Article Title}]] | {One-line summary} | {YYYY-MM-DD} | {N.N} |
27
+ | [{Article Title}]({another-topic}/{article-file}.md) | {One-line summary} | {YYYY-MM-DD} | {N.N} |
24
28
 
25
29
  > **Score**: composite quality score (inbound links, source count, cited count,
26
30
  > freshness; minus conflicts and orphan penalty). Regenerated on every