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
@@ -11,7 +11,8 @@ exemption exists because the memory is the agent's own working notes about how t
|
||||
do its job, not a project artifact.
|
||||
|
||||
It does **not** extend anywhere else. The Collaboration Protocol still governs
|
||||
every file under `src/`, `design/`, `docs/`, `production/` and `assets/`: ask
|
||||
every file under the code root (`src/`, `Assets/` or `Source/`), `design/`,
|
||||
`docs/`, `production/` and `assets/`: ask
|
||||
first, naming the path. Writing a memory is never a substitute for asking, and a
|
||||
memory must never be used to record something the user declined to have written.
|
||||
|
||||
@@ -21,7 +22,7 @@ This is the failure this file exists to prevent, and this repo is unusually
|
||||
exposed to it.
|
||||
|
||||
**CCGS ships as a template the user clones *as their game*.** So on day one every
|
||||
agent observes the same things — no `src/`, no GDDs, no engine configured, no
|
||||
agent observes the same things — no game code, no GDDs, no engine configured, no
|
||||
`tests/performance/` — and every one of those observations is **guaranteed to
|
||||
stop being true**. A memory reading *"this repo is the framework, not a game;
|
||||
perf requests have no target"* is accurate when written and actively harmful two
|
||||
@@ -34,7 +35,7 @@ So:
|
||||
captured profile exist before profiling; return BLOCKED naming what is missing
|
||||
rather than estimating" is durable. "There is no game here" is a timestamp.
|
||||
- **If you must record a state, state what invalidates it**, on the same line:
|
||||
`INVALIDATED WHEN: project.yaml declares an engine, or src/ contains game code.`
|
||||
`INVALIDATED WHEN: project.yaml declares an engine, or the code root (src/, Assets/ or Source/) contains game code.`
|
||||
A reader with no other context must be able to tell whether the note still
|
||||
holds.
|
||||
- **Never record absence of a game, of assets, of tests or of config as a
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
paths:
|
||||
- "src/ai/**"
|
||||
- "Assets/**/{AI,Ai,ai}/**/*.cs"
|
||||
- "Source/**/{AI,Ai,ai}/**/*.{h,cpp}"
|
||||
---
|
||||
|
||||
# AI Code Rules
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
paths:
|
||||
- "assets/data/**"
|
||||
- "assets/data/**/*.json"
|
||||
- "Assets/**/{Data,data}/**/*.json"
|
||||
- "Content/**/{Data,data}/**/*.json"
|
||||
---
|
||||
|
||||
# Data File Rules
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
paths:
|
||||
- "src/core/**"
|
||||
- "Assets/**/{Core,core}/**/*.cs"
|
||||
- "Source/**/{Core,core}/**/*.{h,cpp}"
|
||||
---
|
||||
|
||||
# Engine Code Rules
|
||||
@@ -17,7 +19,7 @@ paths:
|
||||
|
||||
## Examples
|
||||
|
||||
**Correct** (zero-alloc hot path):
|
||||
**Correct** (zero-alloc hot path) — Godot:
|
||||
|
||||
```gdscript
|
||||
# Pre-allocated array reused each frame
|
||||
@@ -28,6 +30,29 @@ func _physics_process(delta: float) -> void:
|
||||
_spatial_grid.query_radius(position, radius, _nearby_cache)
|
||||
```
|
||||
|
||||
Unity:
|
||||
|
||||
```csharp
|
||||
private readonly Collider[] _nearbyCache = new Collider[64]; // allocated once
|
||||
|
||||
void FixedUpdate()
|
||||
{
|
||||
int count = Physics.OverlapSphereNonAlloc(transform.position, radius, _nearbyCache);
|
||||
}
|
||||
```
|
||||
|
||||
Unreal:
|
||||
|
||||
```cpp
|
||||
// TArray member, reserved once; Reset() keeps the allocation
|
||||
void UProximityComponent::TickComponent(float DeltaTime, ELevelTick TickType,
|
||||
FActorComponentTickFunction* ThisTickFunction)
|
||||
{
|
||||
NearbyCache.Reset();
|
||||
SpatialGrid->QueryRadius(GetComponentLocation(), Radius, NearbyCache);
|
||||
}
|
||||
```
|
||||
|
||||
**Incorrect** (allocating in hot path):
|
||||
|
||||
```gdscript
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
---
|
||||
paths:
|
||||
- "src/gameplay/**"
|
||||
- "Assets/**/{Gameplay,gameplay}/**/*.cs"
|
||||
- "Source/**/{Gameplay,gameplay}/**/*.{h,cpp}"
|
||||
---
|
||||
|
||||
# Gameplay Code Rules
|
||||
|
||||
- ALL gameplay values MUST come from external config/data files, NEVER hardcoded
|
||||
- Use delta time for ALL time-dependent calculations (frame-rate independence)
|
||||
- NO direct references to UI code — use events/signals for cross-system communication
|
||||
- NO direct references to UI code — use events for cross-system communication
|
||||
(Godot signals, C# events, Unreal delegates)
|
||||
- Every gameplay system must implement a clear interface
|
||||
- State machines must have explicit transition tables with documented states
|
||||
- Write unit tests for all gameplay logic — separate logic from presentation
|
||||
@@ -16,13 +19,27 @@ paths:
|
||||
|
||||
## Examples
|
||||
|
||||
**Correct** (data-driven):
|
||||
**Correct** (data-driven) — Godot:
|
||||
|
||||
```gdscript
|
||||
var damage: float = config.get_value("combat", "base_damage", 10.0)
|
||||
var speed: float = stats_resource.movement_speed * delta
|
||||
```
|
||||
|
||||
Unity (values from a ScriptableObject):
|
||||
|
||||
```csharp
|
||||
float damage = combatConfig.BaseDamage;
|
||||
float speed = stats.MovementSpeed * Time.deltaTime;
|
||||
```
|
||||
|
||||
Unreal (values from a data asset):
|
||||
|
||||
```cpp
|
||||
const float Damage = CombatConfig->BaseDamage;
|
||||
const float Speed = Stats->MovementSpeed * DeltaTime;
|
||||
```
|
||||
|
||||
**Incorrect** (hardcoded):
|
||||
|
||||
```gdscript
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
paths:
|
||||
- "src/networking/**"
|
||||
- "Assets/**/{Networking,networking,Network,network}/**/*.cs"
|
||||
- "Source/**/{Networking,networking,Network,network}/**/*.{h,cpp}"
|
||||
---
|
||||
|
||||
# Network Code Rules
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
---
|
||||
paths:
|
||||
- "assets/shaders/**"
|
||||
- "**/*.gdshader"
|
||||
- "Assets/**/*.{shader,hlsl,cginc,compute,shadergraph}"
|
||||
- "Shaders/**"
|
||||
- "**/*.{usf,ush}"
|
||||
---
|
||||
|
||||
# Shader Code Standards
|
||||
|
||||
All shader files in `assets/shaders/` must follow these standards to maintain
|
||||
All shader files, in every engine, must follow these standards to maintain
|
||||
visual quality, performance, and cross-platform compatibility.
|
||||
|
||||
## Naming Conventions
|
||||
@@ -14,7 +18,8 @@ visual quality, performance, and cross-platform compatibility.
|
||||
- `SG_Env_Water` (Unity Shader Graph)
|
||||
- `M_Env_Water` (Unreal Material)
|
||||
- Use descriptive names that indicate the material purpose
|
||||
- Prefix with shader type: `spatial_`, `canvas_`, `particles_`, `post_`
|
||||
- Prefix with the engine's shader type — Godot `spatial_`, `canvas_`, `particles_`,
|
||||
`post_`; Unity `SG_` (Shader Graph); Unreal `M_`, `MI_` (instance), `MF_` (function)
|
||||
|
||||
## Code Quality
|
||||
- All uniforms/parameters must have descriptive names and appropriate hints
|
||||
@@ -27,7 +32,8 @@ visual quality, performance, and cross-platform compatibility.
|
||||
- Document the target platform and complexity budget for each shader
|
||||
- Use appropriate precision: `half`/`mediump` on mobile where full precision isn't needed
|
||||
- Minimize texture samples in fragment shaders
|
||||
- Avoid dynamic branching in fragment shaders — use `step()`, `mix()`, `smoothstep()`
|
||||
- Avoid dynamic branching in fragment shaders — use `step()`, `smoothstep()` and
|
||||
`mix()` (Godot, GLSL) or `lerp()` (HLSL: Unity, Unreal)
|
||||
- No texture reads inside loops
|
||||
- Two-pass approach for blur effects (horizontal then vertical)
|
||||
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
---
|
||||
paths:
|
||||
- "tests/**"
|
||||
- "Assets/Tests/**/*.cs"
|
||||
- "Source/**/Tests/**/*.{h,cpp}"
|
||||
---
|
||||
|
||||
# Test Standards
|
||||
|
||||
- Test naming: `test_[system]_[scenario]_[expected_result]` pattern
|
||||
- Test naming follows the engine's language — every name says the scenario and
|
||||
the expected result:
|
||||
- **Godot (gdUnit4):** file `[system]_[feature]_test.gd`, function
|
||||
`test_[scenario]_[expected]`
|
||||
- **Unity (NUnit):** class `[System]Tests` in a file of the same name, method
|
||||
`[Scenario]_[Expected]` in PascalCase
|
||||
- **Unreal (Automation):** class `F[System][Scenario]Test` — one per test:
|
||||
each `IMPLEMENT_SIMPLE_AUTOMATION_TEST` defines its class, so a second test
|
||||
reusing a name fails to link — test name
|
||||
`<Project>.[System].[Scenario]` — the project's test command,
|
||||
`Automation RunTests <Project>.`, runs every test whose name contains
|
||||
`<Project>.` (a substring match, not a prefix). `<Project>.` is the root
|
||||
that filter in `commands.test` uses: the project name, or the distinct root
|
||||
`/setup-engine` chose when the project's name is also an engine area
|
||||
(`Audio`, `Core`, `Input`, …) — name tests under whichever it is
|
||||
- Every test must have a clear arrange/act/assert structure
|
||||
- Unit tests must not depend on external state (filesystem, network, database)
|
||||
- Integration tests must clean up after themselves
|
||||
@@ -27,12 +43,14 @@ paths:
|
||||
|
||||
## Examples
|
||||
|
||||
**Correct** (proper naming + Arrange/Act/Assert):
|
||||
**Correct** (proper naming + Arrange/Act/Assert) — Godot, gdUnit4:
|
||||
|
||||
```gdscript
|
||||
func test_health_system_take_damage_reduces_health() -> void:
|
||||
# Arrange
|
||||
var health := HealthComponent.new()
|
||||
extends GdUnitTestSuite
|
||||
|
||||
func test_take_damage_reduces_health() -> void:
|
||||
# Arrange — auto_free: a Node left alive is an orphan (gdUnit4 exit 101)
|
||||
var health: HealthComponent = auto_free(HealthComponent.new())
|
||||
health.max_health = 100
|
||||
health.current_health = 100
|
||||
|
||||
@@ -40,7 +58,55 @@ func test_health_system_take_damage_reduces_health() -> void:
|
||||
health.take_damage(25)
|
||||
|
||||
# Assert
|
||||
assert_eq(health.current_health, 75)
|
||||
assert_int(health.current_health).is_equal(75)
|
||||
```
|
||||
|
||||
Unity, NUnit (`Assets/Tests/EditMode/HealthTests.cs`):
|
||||
|
||||
```csharp
|
||||
using NUnit.Framework;
|
||||
|
||||
public class HealthTests
|
||||
{
|
||||
[Test]
|
||||
public void TakeDamage_ReducesHealth()
|
||||
{
|
||||
// Arrange
|
||||
var health = new Health(maxHealth: 100);
|
||||
|
||||
// Act
|
||||
health.TakeDamage(25);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(75, health.Current);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Unreal, Automation (`Source/<Module>/Private/Tests/HealthTest.cpp`):
|
||||
|
||||
```cpp
|
||||
#include "Misc/AutomationTest.h"
|
||||
|
||||
#if WITH_DEV_AUTOMATION_TESTS
|
||||
|
||||
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FHealthTakeDamageTest, "<Project>.Health.TakeDamageReducesHealth",
|
||||
EAutomationTestFlags::EditorContext | EAutomationTestFlags::ProductFilter)
|
||||
|
||||
bool FHealthTakeDamageTest::RunTest(const FString& Parameters)
|
||||
{
|
||||
// Arrange
|
||||
FHealthPool Health(100);
|
||||
|
||||
// Act
|
||||
Health.TakeDamage(25);
|
||||
|
||||
// Assert
|
||||
TestEqual(TEXT("health after 25 damage"), Health.GetCurrent(), 75);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
```
|
||||
|
||||
**Incorrect**:
|
||||
@@ -49,5 +115,5 @@ func test_health_system_take_damage_reduces_health() -> void:
|
||||
func test1() -> void: # VIOLATION: no descriptive name
|
||||
var h := HealthComponent.new()
|
||||
h.take_damage(25) # VIOLATION: no arrange step, no clear assert
|
||||
assert_true(h.current_health < 100) # VIOLATION: imprecise assertion
|
||||
assert_bool(h.current_health < 100).is_true() # VIOLATION: imprecise assertion
|
||||
```
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
paths:
|
||||
- "src/ui/**"
|
||||
- "Assets/**/{UI,Ui,ui}/**/*.cs"
|
||||
- "Source/**/{UI,Ui,ui}/**/*.{h,cpp}"
|
||||
---
|
||||
|
||||
# UI Code Rules
|
||||
|
||||
Reference in New Issue
Block a user