mirror of
https://github.com/Donchitos/Claude-Code-Game-Studios.git
synced 2026-10-16 01:37:05 +00:00
Release 1.1.2 — the default path works end to end
Fix release for 1.1.1: the minimal path end to end, engine commands that run on Godot, Unity and Unreal, hook warnings you can see, and verdicts that say when they could not check. Details in CHANGELOG.md; upgrade steps in UPGRADING.md (v1.1.1 → v1.1.2). Fixes #67 Fixes #131 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WuJn2FdynEybfL5KC697nJ
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7ed2c3e9c4
commit
b21fa0f7f2
@@ -42,7 +42,7 @@ Engine-specialist agents are instructed to:
|
||||
|
||||
- After upgrading the engine version
|
||||
- When the LLM model is updated (new knowledge cutoff)
|
||||
- After running `/refresh-docs` (if available)
|
||||
- After running `/setup-engine refresh`
|
||||
- When you discover an API the model gets wrong
|
||||
|
||||
### How to Update
|
||||
|
||||
@@ -53,7 +53,7 @@ Changes between Godot versions, focused on post-LLM-cutoff changes (4.4+).
|
||||
| Core | `OS.execute_with_pipe` | Added optional `blocking` parameter |
|
||||
| Core | `RegEx.compile/create_from_string` | Added optional `show_error` parameter |
|
||||
| Rendering | `RenderingDevice.draw_list_begin` | Many parameters removed; `breadcrumb` parameter added |
|
||||
| Rendering | Shader texture types | Parameter/return types changed from `Texture2D` to `Texture` |
|
||||
| Rendering | `Shader.set_default_texture_parameter()` / `get_default_texture_parameter()` | Parameter/return type changed from `Texture2D` to `Texture`; the shading language did not change |
|
||||
| Particles | `.restart()` method | Added optional `keep_seed` parameter (CPU/GPU 2D/3D) |
|
||||
| GUI | `RichTextLabel.push_meta` | Added optional `tooltip` parameter |
|
||||
| GUI | `GraphEdit.connect_node` | Added optional `keep_alive` parameter |
|
||||
|
||||
@@ -7,21 +7,36 @@ This supplements (not replaces) the agent's built-in knowledge.
|
||||
|
||||
## GDScript (4.5+)
|
||||
|
||||
- **Variadic arguments**: Functions can accept arbitrary parameter counts
|
||||
- **Variadic arguments**: Functions can accept arbitrary parameter counts. The
|
||||
rest parameter is written `...name`, comes last, and is typed `Array` or left
|
||||
untyped — `values: Variant...` and `...values: Array[int]` do not parse
|
||||
```gdscript
|
||||
func log_values(prefix: String, values: Variant...) -> void:
|
||||
func log_values(prefix: String, ...values: Array) -> void:
|
||||
for v in values:
|
||||
print(prefix, ": ", v)
|
||||
```
|
||||
|
||||
- **Lambdas capture local variables by value** (every Godot 4 version): a local
|
||||
is captured once, when the lambda is created, and a lambda cannot reassign an
|
||||
outer local — `var hit := false` / `func(): hit = true` leaves the caller's
|
||||
`hit` false. Share state through a reference type (a Dictionary, an Array or
|
||||
an object) and mutate its contents. A rest parameter works in a lambda too, so
|
||||
`func(...args)` connects to a signal with any number of arguments (observed on
|
||||
4.6.1; a one-argument lambda on a zero-argument signal errors "Method expected
|
||||
1 argument(s), but called with 0")
|
||||
```gdscript
|
||||
var state := {"emitted": false}
|
||||
some_signal.connect(func(...args): state.emitted = true)
|
||||
```
|
||||
|
||||
- **Abstract classes and methods**: Use `@abstract` to enforce inheritance
|
||||
```gdscript
|
||||
@abstract
|
||||
class_name BaseEnemy extends CharacterBody3D
|
||||
|
||||
@abstract
|
||||
func get_attack_pattern() -> Array[Attack]:
|
||||
pass # Subclasses MUST override
|
||||
# No body: "a newline or a semicolon is expected after the function header".
|
||||
# Subclasses MUST override it.
|
||||
@abstract func get_attack_pattern() -> Array[Attack]
|
||||
```
|
||||
|
||||
- **Script backtracing**: Detailed call stacks available even in Release builds
|
||||
@@ -99,6 +114,49 @@ This supplements (not replaces) the agent's built-in knowledge.
|
||||
`rg --type gdscript` is a hard error — the search never executes.
|
||||
Always use `rg --glob "*.gd"` (shell) or `glob: "*.gd"` (Grep tool) to filter GDScript files.
|
||||
|
||||
## Command Line — Tests and Parse Check
|
||||
|
||||
Flags, from Godot's command-line tutorial: `--headless` (headless display and a
|
||||
dummy audio driver, "useful for servers and with `--script`"), `--path <dir>`
|
||||
(a directory holding `project.godot`), `-s`/`--script <script>`, `-d`/`--debug`
|
||||
(the local stdout debugger), `--remote-debug <protocol>://<host>[:<port>]`,
|
||||
`--import` (starts the editor, waits for the import, and quits),
|
||||
`--quit-after <n>` (iterations), `--export-debug <preset>` (implies `--import`)
|
||||
and `--check-only` (parse for errors and quit, with `--script`). The editor is
|
||||
not on `PATH` by default: on Windows and Linux run the binary by its relative or
|
||||
absolute path; on macOS run `Godot.app/Contents/MacOS/Godot` inside the bundle.
|
||||
|
||||
gdUnit4's runner is `res://addons/gdUnit4/bin/GdUnitCmdTool.gd`; `-a <dir|suite>`
|
||||
adds suites, reports go to `res://reports/` by default (`-rd` changes it), and
|
||||
the documented exit codes are 0 (all passed), 100 (failures) and 101 (warnings).
|
||||
The command the framework uses:
|
||||
`godot --headless -s -d --remote-debug tcp://127.0.0.1:0 res://addons/gdUnit4/bin/GdUnitCmdTool.gd -a res://tests --ignoreHeadlessMode`.
|
||||
|
||||
Observed on Godot 4.6.1 with gdUnit4 6.1.3 — not in the docs:
|
||||
- 101 is also the exit when every test passed but a test leaked orphan nodes;
|
||||
105 means a test script does not parse; 103 means gdUnit4 refused to run
|
||||
headless (`--ignoreHeadlessMode` missing). 104 is gdUnit4 refusing a Godot
|
||||
older than 4.3 — not reproducible on the pin.
|
||||
- Over zero tests the runner prints `No test cases found` and exits 0.
|
||||
- Without `--remote-debug tcp://127.0.0.1:0`, a script error opens the `-d`
|
||||
debugger and the run waits at a `debug>` prompt; with it, every run prints two
|
||||
`ERROR:` lines about the remote port, which are expected.
|
||||
- A fresh clone has no `.godot/` class cache: run
|
||||
`godot --headless --path . --import` first, or `GdUnitCmdTool.gd` does not
|
||||
load and the run exits 1 having run nothing.
|
||||
- `--check-only` with `-s <file>` exits 1 on valid code that names an autoload
|
||||
(`Identifier not found`), and `--import` / `--quit-after` exit 0 on a parse
|
||||
error — neither is a parse check. The framework's parse check is
|
||||
`godot --headless --path . -s res://.claude/scripts/godot-parse-check.gd -- res://<file>.gd …`
|
||||
(exit 1 when a script does not load).
|
||||
- On Windows, a quoted full path to the editor (`"C:/Program Files/Godot/…exe"`)
|
||||
runs from Git Bash with its stdout and exit code intact.
|
||||
|
||||
Sources:
|
||||
- Command line tutorial: https://docs.godotengine.org/en/stable/tutorials/editor/command_line_tutorial.html
|
||||
- gdUnit4 command line tool: https://godot-gdunit-labs.github.io/gdUnit4/latest/advanced_testing/cmd/
|
||||
- GDScript reference, lambda functions and rest parameters: https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html
|
||||
|
||||
## Platform (4.5+)
|
||||
|
||||
- **visionOS export**: First new platform since open-sourcing (windowed app mode)
|
||||
|
||||
@@ -38,6 +38,6 @@ with the "Use Instead" column.
|
||||
| String-based `connect()` | Typed signal connections | Type-safe, refactor-friendly |
|
||||
| `$NodePath` in `_process()` | `@onready var` cached reference | Performance: path lookup every frame |
|
||||
| Untyped `Array` / `Dictionary` | `Array[Type]`, typed variables | GDScript compiler optimizations |
|
||||
| `Texture2D` in shader parameters | `Texture` base type | Changed in 4.4 |
|
||||
| `Texture2D` in `Shader.set_default_texture_parameter()` / `get_default_texture_parameter()` | `Texture` base type | Changed in 4.4; the shading language's `sampler2D` / `texture()` did not change |
|
||||
| Manual post-process viewport chains | `Compositor` + `CompositorEffect` | Structured post-processing (4.3+) |
|
||||
| GodotPhysics3D for new projects | Jolt Physics 3D | Default since 4.6; better stability |
|
||||
|
||||
@@ -19,7 +19,9 @@ Last verified: 2026-02-12 | Engine: Godot 4.6
|
||||
|
||||
### 4.4 Changes
|
||||
- **`RenderingDevice.draw_list_begin`**: Many parameters removed; optional `breadcrumb` added
|
||||
- **Shader texture types**: Changed from `Texture2D` to `Texture` base type
|
||||
- **`Shader` default-texture methods**: `set_default_texture_parameter()` takes and
|
||||
`get_default_texture_parameter()` returns `Texture`, not `Texture2D` (the shading
|
||||
language's `sampler2D` / `texture()` did not change)
|
||||
- **Particles `.restart()`**: Added optional `keep_seed` parameter
|
||||
|
||||
### 4.3 Changes (in training data)
|
||||
@@ -55,5 +57,7 @@ Windows default backend: D3D12 (was Vulkan pre-4.6)
|
||||
## Common Mistakes
|
||||
- Assuming Vulkan is the default backend on Windows (D3D12 since 4.6)
|
||||
- Using manual viewport chains instead of Compositor for post-processing
|
||||
- Using `Texture2D` in shader uniform types (use `Texture` since 4.4)
|
||||
- Passing or expecting `Texture2D` in `Shader.set_default_texture_parameter()` /
|
||||
`get_default_texture_parameter()` (the type is `Texture` since 4.4 — the shading
|
||||
language's `sampler2D` / `texture()` did not change)
|
||||
- Not using Shader Baker for projects with many shader variants
|
||||
|
||||
@@ -191,6 +191,13 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer
|
||||
|
||||
**Replaces:** Old `CommandBuffer.Execute()` pattern.
|
||||
|
||||
**This is URP's API.** `RecordRenderGraph` overrides URP's `ScriptableRenderPass`.
|
||||
HDRP custom passes are a separate API: a `CustomPass` subclass, run from a Custom
|
||||
Pass Volume, overrides `Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)`,
|
||||
`Execute(CustomPassContext ctx)` and `Cleanup()` (HDRP 17.3, *Create a Custom
|
||||
Pass in a C# script*:
|
||||
https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@17.3/manual/Custom-Pass-Scripting.html).
|
||||
|
||||
---
|
||||
|
||||
## Performance
|
||||
@@ -296,6 +303,40 @@ public IEnumerator Player_TakesDamage_HealthDecreases() {
|
||||
|
||||
---
|
||||
|
||||
## Command Line — Tests
|
||||
|
||||
Documented (Unity Manual, *Run tests from the command line*; Test Framework
|
||||
command-line reference):
|
||||
`<Unity editor> -runTests -batchmode -projectPath <path> -testPlatform <platform> -testResults <file>`.
|
||||
`-batchmode` removes the need for user input. `-testPlatform` takes `EditMode`,
|
||||
`PlayMode` (Play Mode tests in the Editor) or a player platform; with no value,
|
||||
tests run in Edit Mode. `-testResults` defaults to the project root, and the
|
||||
file follows NUnit's XML format: the `<test-run>` element carries
|
||||
`testcasecount`, `result`, `passed` and `failed`, and each `<test-case>` a
|
||||
`fullname` and a `result` of `Passed`, `Failed`, `Inconclusive` or `Skipped`.
|
||||
Unity defines no common exit codes for test runs.
|
||||
|
||||
Observed on Unity 6000.3.23f1 — not in the docs:
|
||||
- `-runTests` exits 0 when every test passes and 2 when one fails; 1 is a
|
||||
compile error (no results file is written), 3 a failed run, 4 an unknown
|
||||
`-testPlatform`. It exits by itself — no `-quit`.
|
||||
- Tests outside `Assets/` are never compiled: the run reports
|
||||
`testcasecount="0"`, `result="Passed"` and exits 0 — a false pass.
|
||||
- Without the `com.unity.test-framework` package, `-runTests` hangs rather
|
||||
than failing.
|
||||
- `Unity` on `PATH` may be Unity's separate CLI, not the editor; it rejects
|
||||
`-batchmode` and `-version` with exit 2. Name the editor executable by its
|
||||
full path.
|
||||
- `-batchmode -quit -projectPath . -logFile -` exits 1 on a compile error and
|
||||
0 when clean.
|
||||
|
||||
Sources:
|
||||
- Run tests from the command line: https://docs.unity3d.com/6000.3/Documentation/Manual/test-framework/run-tests-from-command-line.html
|
||||
- Test Framework command-line arguments: https://docs.unity3d.com/Packages/com.unity.test-framework@1.4/manual/reference-command-line.html
|
||||
- NUnit test result XML format: https://docs.nunit.org/articles/nunit/technical-notes/usage/Test-Result-XML-Format.html
|
||||
|
||||
---
|
||||
|
||||
## Debugging
|
||||
|
||||
### Use Logging Best Practices
|
||||
|
||||
@@ -366,9 +366,11 @@ async void CheckForUpdates() {
|
||||
// ❌ OLD: Resources.Load (synchronous, blocks frame)
|
||||
GameObject prefab = Resources.Load<GameObject>("Enemies/Goblin");
|
||||
|
||||
// ✅ NEW: Addressables (async, non-blocking)
|
||||
var handle = await Addressables.LoadAssetAsync<GameObject>("Enemies/Goblin").Task;
|
||||
GameObject prefab = handle.Result;
|
||||
// ✅ NEW: Addressables (async, non-blocking) — keep the handle so it can be released
|
||||
AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>("Enemies/Goblin");
|
||||
GameObject prefab = await handle.Task;
|
||||
// ... when the asset is no longer needed:
|
||||
Addressables.Release(handle);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -21,6 +21,42 @@ These are production-ready recommendations as of UE 5.7.
|
||||
|
||||
---
|
||||
|
||||
## Command Line — Build and Automation Tests (per platform)
|
||||
|
||||
Build the project's own editor target before running tests (a fresh checkout has
|
||||
no compiled game module), then run the automation tests with the editor. Epic
|
||||
recommends building `<Project>Editor` rather than `UnrealEditor`, so the modules
|
||||
the `.uproject` disables stay disabled. Give the project as an absolute path.
|
||||
|
||||
| Step | Windows | Linux | macOS |
|
||||
|------|---------|-------|-------|
|
||||
| Build the editor target | `Engine/Binaries/DotNET/UnrealBuildTool/UnrealBuildTool.exe <Project>Editor Win64 Development -Project="<abs>/<Project>.uproject"` | `Engine/Build/BatchFiles/Linux/Build.sh <Project>Editor Linux Development -Project="<abs>/<Project>.uproject"` | `Engine/Build/BatchFiles/Mac/Build.sh <Project>Editor Mac Development -Project="<abs>/<Project>.uproject"` |
|
||||
| Editor executable for a command-line run | `Engine/Binaries/Win64/UnrealEditor-Cmd.exe` | `Engine/Binaries/Linux/UnrealEditor` | **NOT SOURCEABLE** — Epic documents only the `Engine/Binaries/Mac/UnrealEditor.app` bundle, not a command-line editor inside it |
|
||||
| Packaged build | `Engine/Binaries/DotNET/AutomationTool/AutomationTool.exe BuildCookRun … -platform=Win64` | `Engine/Build/BatchFiles/RunUAT.sh BuildCookRun … -platform=Linux` | `Engine/Build/BatchFiles/RunUAT.sh BuildCookRun … -platform=Mac` |
|
||||
|
||||
The automation arguments are the same on every platform:
|
||||
`"<abs>/<Project>.uproject" -ExecCmds="Automation RunTests <Project>.; Quit" -unattended -nullrhi -stdout -FullStdOutLogOutput`.
|
||||
`RunTests` is a partial (substring) match. Each test prints
|
||||
`Test Completed. Result={<status>}`, and the run ends with
|
||||
`**** TEST COMPLETE. EXIT CODE: <n> ****` — exit code 0 means no test failed.
|
||||
Only one `Automation` run request is allowed per `-ExecCmds`, and `-testexit=` is
|
||||
legacy.
|
||||
|
||||
The Windows column was run on UE 5.7. The Linux and macOS columns come from
|
||||
Epic's documentation and forum answers by Epic staff (sources below); Epic never
|
||||
prints the full Linux test line, so it is assembled from the executable and the
|
||||
platform-neutral arguments.
|
||||
|
||||
Sources:
|
||||
- Build.sh on Linux and Mac, platform names — *Create an Installed Build*: https://dev.epicgames.com/documentation/en-us/unreal-engine/create-an-installed-build-of-unreal-engine?application_version=5.7
|
||||
- `RunUBT.sh <Target> [Linux|Mac] Development` — *Unreal Insights*: https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-insights-in-unreal-engine?application_version=5.7
|
||||
- `Engine/Binaries/Linux/UnrealEditor`, `Engine/Binaries/Mac/UnrealEditor.app` — *Onboarding Licensees*: https://dev.epicgames.com/documentation/en-us/unreal-engine/onboarding-licensees-in-unreal-engine?application_version=5.7 and *Linux Development Quickstart*: https://dev.epicgames.com/documentation/en-us/unreal-engine/linux-development-quickstart-for-unreal-engine?application_version=5.7
|
||||
- `-nullrhi`, `-unattended`, `-stdout`, `-ExecCmds` — *Command-Line Arguments Reference*: https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-command-line-arguments-reference?application_version=5.7
|
||||
- Running tests from the command line — *Run Automation Tests*: https://dev.epicgames.com/documentation/en-us/unreal-engine/run-automation-tests-in-unreal-engine?application_version=5.7 ; result lines and exit code — *Review Test Results*: https://dev.epicgames.com/documentation/en-us/unreal-engine/review-test-results-in-unreal-engine?application_version=5.7
|
||||
- `RunUAT.sh` from `Engine/Build/BatchFiles` on Mac/Linux — *Unreal Automation Tool Overview*: https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-automation-tool-overview-for-unreal-engine?application_version=5.7
|
||||
|
||||
---
|
||||
|
||||
## C++ Coding
|
||||
|
||||
### Use Modern C++ Features (C++20 in UE5.7)
|
||||
|
||||
@@ -107,8 +107,8 @@ void OnRep_Health() {
|
||||
### Server RPC (Client → Server)
|
||||
|
||||
```cpp
|
||||
// Client calls, server executes
|
||||
UFUNCTION(Server, Reliable)
|
||||
// Client calls, server executes. WithValidation declares Server_TakeDamage_Validate.
|
||||
UFUNCTION(Server, Reliable, WithValidation)
|
||||
void Server_TakeDamage(int32 Damage);
|
||||
|
||||
void AMyCharacter::Server_TakeDamage_Implementation(int32 Damage) {
|
||||
|
||||
@@ -176,6 +176,21 @@ void UMyAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) {
|
||||
// Implement other OnRep functions similarly...
|
||||
```
|
||||
|
||||
### Clamping Attributes
|
||||
|
||||
Attribute Sets have no built-in clamping: the Data Table `Min Value` and
|
||||
`Max Value` columns have no effect. Clamp in the Attribute Set:
|
||||
- `PreAttributeChange()` is called just before any modification to an
|
||||
attribute, and is the hook for rules like
|
||||
`Health = Clamp(Health, 0, MaxHealth)` — its `NewValue` is mutable.
|
||||
- `PreAttributeBaseChange()` is called just before a change to an attribute's
|
||||
**base** value when an aggregator exists, and `PostGameplayEffectExecute()`
|
||||
just after a Gameplay Effect is executed to modify the base value — clamp
|
||||
base-value changes from instant effects there.
|
||||
|
||||
Stacking rules govern re-applications of the same Gameplay Effect; they do not
|
||||
bound one attribute pushed by different effects.
|
||||
|
||||
---
|
||||
|
||||
## Gameplay Abilities
|
||||
@@ -391,4 +406,5 @@ void AMyCharacter::OnHealthChanged(const FOnAttributeChangeData& Data) {
|
||||
|
||||
## Sources
|
||||
- https://docs.unrealengine.com/5.7/en-US/gameplay-ability-system-for-unreal-engine/
|
||||
- Clamping: *Gameplay Attributes and Attribute Sets* https://dev.epicgames.com/documentation/en-us/unreal-engine/gameplay-attributes-and-attribute-sets-for-the-gameplay-ability-system-in-unreal-engine ; `UAttributeSet` API https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Plugins/GameplayAbilities/UAttributeSet ; `PreAttributeChange` https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Plugins/GameplayAbilities/UAttributeSet/PreAttributeChange
|
||||
- https://github.com/tranek/GASDocumentation (community guide)
|
||||
|
||||
Reference in New Issue
Block a user