@musashishao/agent-kit 1.8.2 → 1.9.1
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/.agent/agents/ai-architect.md +39 -0
- package/.agent/agents/ai-asset-factory.md +700 -0
- package/.agent/agents/ai-audio-factory.md +503 -0
- package/.agent/agents/cloud-engineer.md +39 -0
- package/.agent/agents/game-developer.md +190 -89
- package/.agent/agents/marketing-specialist.md +41 -0
- package/.agent/agents/orchestrator.md +113 -3
- package/.agent/agents/penetration-tester.md +15 -1
- package/.agent/agents/project-planner.md +67 -0
- package/.agent/agents/unity-mobile-master.md +949 -0
- package/.agent/mcp/config/registry.json +65 -51
- package/.agent/mcp/servers/notebooklm/README.md +114 -0
- package/.agent/mcp/servers/notebooklm/package.json +35 -0
- package/.agent/mcp/servers/notebooklm/src/auth/chrome.ts +225 -0
- package/.agent/mcp/servers/notebooklm/src/auth/index.ts +1 -0
- package/.agent/mcp/servers/notebooklm/src/index.ts +516 -0
- package/.agent/mcp/servers/notebooklm/src/services/index.ts +3 -0
- package/.agent/mcp/servers/notebooklm/src/services/library.ts +217 -0
- package/.agent/mcp/servers/notebooklm/src/services/notebooklm.ts +380 -0
- package/.agent/mcp/servers/notebooklm/tsconfig.json +15 -0
- package/.agent/mcp-gateway/README.md +169 -20
- package/.agent/mcp-gateway/package.json +22 -7
- package/.agent/mcp-gateway/src/auth/index.ts +55 -0
- package/.agent/mcp-gateway/src/auth/middleware.ts +242 -0
- package/.agent/mcp-gateway/src/auth/oauth.ts +462 -0
- package/.agent/mcp-gateway/src/auth/scopes.ts +227 -0
- package/.agent/mcp-gateway/src/index.ts +252 -105
- package/.agent/mcp-gateway/src/observability/index.ts +5 -0
- package/.agent/mcp-gateway/src/observability/otel.ts +405 -0
- package/.agent/mcp-gateway/src/transports/index.ts +5 -0
- package/.agent/mcp-gateway/src/transports/streamableHttp.ts +235 -0
- package/.agent/rules/CODEX.md +115 -2
- package/.agent/rules/CODE_RULES.md +73 -0
- package/.agent/rules/GEMINI.md +26 -1
- package/.agent/rules/MEMORY_STATE.md +110 -0
- package/.agent/rules/REFERENCE.md +40 -58
- package/.agent/rules/REF_SKILLS.md +116 -0
- package/.agent/rules/REF_WORKFLOWS.md +81 -0
- package/.agent/scripts/ak_cli.py +106 -5
- package/.agent/scripts/memory_manager.py +48 -9
- package/.agent/skills/3d-web-experience/SKILL.md +386 -0
- package/.agent/skills/DEPENDENCIES.md +54 -0
- package/.agent/skills/ab-test-setup/SKILL.md +77 -0
- package/.agent/skills/active-directory-attacks/SKILL.md +59 -0
- package/.agent/skills/agent-evaluation/SKILL.md +430 -0
- package/.agent/skills/agent-memory-systems/SKILL.md +426 -0
- package/.agent/skills/agent-tool-builder/SKILL.md +139 -0
- package/.agent/skills/ai-agents-architect/SKILL.md +115 -0
- package/.agent/skills/ai-product/SKILL.md +86 -0
- package/.agent/skills/ai-wrapper-product/SKILL.md +90 -0
- package/.agent/skills/analytics-tracking/SKILL.md +88 -0
- package/.agent/skills/anti-hallucination/SKILL.md +295 -0
- package/.agent/skills/anti-hallucination/scripts/check_hallucination.py +299 -0
- package/.agent/skills/api-fuzzing-bug-bounty/SKILL.md +66 -0
- package/.agent/skills/app-store-optimization/SKILL.md +66 -0
- package/.agent/skills/autonomous-agent-patterns/SKILL.md +414 -0
- package/.agent/skills/aws-penetration-testing/SKILL.md +50 -0
- package/.agent/skills/aws-serverless/SKILL.md +327 -0
- package/.agent/skills/azure-functions/SKILL.md +340 -0
- package/.agent/skills/bifurcation-analysis/SKILL.md +56 -0
- package/.agent/skills/brainstorming/SKILL.md +80 -6
- package/.agent/skills/broken-authentication/SKILL.md +53 -0
- package/.agent/skills/browser-automation/SKILL.md +408 -0
- package/.agent/skills/browser-extension-builder/SKILL.md +422 -0
- package/.agent/skills/bullmq-specialist/SKILL.md +424 -0
- package/.agent/skills/bun-development/SKILL.md +386 -0
- package/.agent/skills/burp-suite-testing/SKILL.md +60 -0
- package/.agent/skills/clerk-auth/SKILL.md +432 -0
- package/.agent/skills/cloud-penetration-testing/SKILL.md +51 -0
- package/.agent/skills/copywriting/SKILL.md +66 -0
- package/.agent/skills/crewai/SKILL.md +470 -0
- package/.agent/skills/decision-memory/SKILL.md +317 -0
- package/.agent/skills/discord-bot-architect/SKILL.md +447 -0
- package/.agent/skills/email-sequence/SKILL.md +73 -0
- package/.agent/skills/emergence-detector/SKILL.md +230 -0
- package/.agent/skills/emergence-detector/scripts/check_emergence.py +265 -0
- package/.agent/skills/ethical-hacking-methodology/SKILL.md +67 -0
- package/.agent/skills/explained-qa/SKILL.md +142 -0
- package/.agent/skills/explained-qa/game-terminology.md +214 -0
- package/.agent/skills/firebase/SKILL.md +377 -0
- package/.agent/skills/game-development/ai-dialogue-engine/SKILL.md +442 -0
- package/.agent/skills/game-development/ai-graphics-generator/SKILL.md +463 -0
- package/.agent/skills/game-development/ai-playtest-framework/SKILL.md +570 -0
- package/.agent/skills/game-development/camera-systems/SKILL.md +607 -0
- package/.agent/skills/game-development/card-battle-engine/SKILL.md +618 -0
- package/.agent/skills/game-development/character-controller-3d/SKILL.md +908 -0
- package/.agent/skills/game-development/cloud-save-sync/SKILL.md +527 -0
- package/.agent/skills/game-development/combat-system/SKILL.md +748 -0
- package/.agent/skills/game-development/compliance-rating/SKILL.md +277 -0
- package/.agent/skills/game-development/crossplatform-build/SKILL.md +386 -0
- package/.agent/skills/game-development/cultivation-progression/SKILL.md +520 -0
- package/.agent/skills/game-development/data-driven-balance/SKILL.md +535 -0
- package/.agent/skills/game-development/game-analytics-integrator/SKILL.md +410 -0
- package/.agent/skills/game-development/game-audio-advanced/SKILL.md +646 -0
- package/.agent/skills/game-development/game-economy-designer/SKILL.md +375 -0
- package/.agent/skills/game-development/game-marketing/SKILL.md +85 -0
- package/.agent/skills/game-development/game-state-manager/SKILL.md +883 -0
- package/.agent/skills/game-development/godot-expert/SKILL.md +462 -0
- package/.agent/skills/game-development/hybrid-game-spec/SKILL.md +220 -0
- package/.agent/skills/game-development/inventory-quest/SKILL.md +747 -0
- package/.agent/skills/game-development/liveops/SKILL.md +308 -0
- package/.agent/skills/game-development/localization/SKILL.md +286 -0
- package/.agent/skills/game-development/mobile-input-patterns/SKILL.md +343 -0
- package/.agent/skills/game-development/monetization-strategy/SKILL.md +94 -0
- package/.agent/skills/game-development/multiplayer-master/SKILL.md +727 -0
- package/.agent/skills/game-development/narrative-branching/SKILL.md +593 -0
- package/.agent/skills/game-development/npc-ai-integration/SKILL.md +110 -0
- package/.agent/skills/game-development/procedural-generation/SKILL.md +168 -0
- package/.agent/skills/game-development/procedural-level-ai/SKILL.md +367 -0
- package/.agent/skills/game-development/prototyping-rapid/SKILL.md +205 -0
- package/.agent/skills/game-development/spec-ecosystem/SKILL.md +155 -0
- package/.agent/skills/game-development/spec-ecosystem/decision-log-format.md +129 -0
- package/.agent/skills/game-development/spec-ecosystem/templates/PLAN-template.md +178 -0
- package/.agent/skills/game-development/spec-ecosystem/templates/SPEC-template.md +110 -0
- package/.agent/skills/game-development/spec-ecosystem/templates/TASKS-template.md +156 -0
- package/.agent/skills/game-development/survival-systems/SKILL.md +493 -0
- package/.agent/skills/game-development/testing-qa/SKILL.md +270 -0
- package/.agent/skills/game-development/unity-integration/SKILL.md +358 -0
- package/.agent/skills/game-development/unity-mobile-optimization/SKILL.md +271 -0
- package/.agent/skills/game-development/webgpu-shading/SKILL.md +209 -0
- package/.agent/skills/gcp-cloud-run/SKILL.md +358 -0
- package/.agent/skills/graphql/SKILL.md +492 -0
- package/.agent/skills/idor-testing/SKILL.md +64 -0
- package/.agent/skills/inngest/SKILL.md +128 -0
- package/.agent/skills/intent-capture/SKILL.md +65 -0
- package/.agent/skills/langfuse/SKILL.md +415 -0
- package/.agent/skills/langgraph/SKILL.md +360 -0
- package/.agent/skills/launch-strategy/SKILL.md +68 -0
- package/.agent/skills/linux-privilege-escalation/SKILL.md +62 -0
- package/.agent/skills/llm-app-patterns/SKILL.md +367 -0
- package/.agent/skills/marketing-ideas/SKILL.md +66 -0
- package/.agent/skills/mcp-composition/SKILL.md +362 -0
- package/.agent/skills/mcp-observability/SKILL.md +323 -0
- package/.agent/skills/mcp-security/SKILL.md +314 -0
- package/.agent/skills/metasploit-framework/SKILL.md +60 -0
- package/.agent/skills/micro-saas-launcher/SKILL.md +93 -0
- package/.agent/skills/neon-postgres/SKILL.md +339 -0
- package/.agent/skills/paid-ads/SKILL.md +64 -0
- package/.agent/skills/supabase-integration/SKILL.md +411 -0
- package/.agent/skills/trust-spectrum/SKILL.md +291 -0
- package/.agent/skills/vibe-coding-guard/SKILL.md +328 -0
- package/.agent/templates/AGENTS.game.md +63 -0
- package/.agent/templates/docs/WORKFLOW_GUIDE.en.md +100 -0
- package/.agent/templates/docs/WORKFLOW_GUIDE.vi.md +100 -0
- package/.agent/workflows/ai-agent.md +38 -0
- package/.agent/workflows/autofix.md +1 -0
- package/.agent/workflows/brainstorm.md +1 -0
- package/.agent/workflows/context.md +1 -0
- package/.agent/workflows/create.md +39 -8
- package/.agent/workflows/dashboard.md +1 -0
- package/.agent/workflows/debug.md +14 -0
- package/.agent/workflows/deploy.md +14 -0
- package/.agent/workflows/enhance.md +44 -0
- package/.agent/workflows/gamekit-init.md +177 -0
- package/.agent/workflows/gamekit-launch.md +338 -0
- package/.agent/workflows/gamekit-plan.md +204 -0
- package/.agent/workflows/gamekit-qa.md +153 -0
- package/.agent/workflows/gamekit-spec.md +243 -0
- package/.agent/workflows/gamekit-tasks.md +208 -0
- package/.agent/workflows/marketing.md +39 -0
- package/.agent/workflows/next.md +1 -0
- package/.agent/workflows/orchestrate.md +12 -0
- package/.agent/workflows/pentest.md +39 -0
- package/.agent/workflows/plan.md +42 -0
- package/.agent/workflows/preview.md +1 -0
- package/.agent/workflows/quality.md +1 -0
- package/.agent/workflows/saas.md +38 -0
- package/.agent/workflows/spec.md +42 -0
- package/.agent/workflows/status.md +1 -0
- package/.agent/workflows/test.md +14 -0
- package/.agent/workflows/ui-ux-pro-max.md +1 -0
- package/README.md +4 -4
- package/bin/cli.js +411 -111
- package/package.json +1 -2
- package/docs/AI_DATA_INFRASTRUCTURE.md +0 -288
- package/docs/CHANGELOG_AI_INFRA.md +0 -111
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: godot-expert
|
|
3
|
+
description: Godot Engine expert skill covering GDScript, C#, Godot 4.3+ features, shader language, and performance optimization. Use when developing games with Godot.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Bash, Grep, WebSearch
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Godot Expert Skill
|
|
8
|
+
|
|
9
|
+
> Master Godot 4.3+ development with modern best practices.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## When to Use This Skill
|
|
14
|
+
|
|
15
|
+
- Building games with Godot Engine
|
|
16
|
+
- Writing GDScript or C# for Godot
|
|
17
|
+
- Optimizing Godot performance
|
|
18
|
+
- Creating custom shaders in Godot
|
|
19
|
+
- Integrating AI with Godot RL Agents
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Godot 4.3+ Key Features (2025)
|
|
24
|
+
|
|
25
|
+
| Feature | Description | Use When |
|
|
26
|
+
|---------|-------------|----------|
|
|
27
|
+
| **Enhanced TileMap** | Multi-layer, physics | 2D games |
|
|
28
|
+
| **Compositor Effects** | Custom post-processing | Visual effects |
|
|
29
|
+
| **Interactive Music** | Adaptive audio streams | Dynamic soundtrack |
|
|
30
|
+
| **Navigation Links** | Better pathfinding | Complex AI |
|
|
31
|
+
| **Typed Collections** | Type-safe Arrays/Dicts | Clean code |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Architecture Patterns
|
|
36
|
+
|
|
37
|
+
### 1. Scene Tree Philosophy
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
MainGame (Node)
|
|
41
|
+
├── World (Node2D/3D)
|
|
42
|
+
│ ├── Level (Node)
|
|
43
|
+
│ │ ├── Tilemap
|
|
44
|
+
│ │ └── Entities (Node)
|
|
45
|
+
│ │ ├── Player
|
|
46
|
+
│ │ └── Enemies
|
|
47
|
+
│ └── Camera
|
|
48
|
+
├── UI (CanvasLayer)
|
|
49
|
+
│ ├── HUD
|
|
50
|
+
│ └── Menus
|
|
51
|
+
├── Audio (Node)
|
|
52
|
+
│ ├── MusicPlayer
|
|
53
|
+
│ └── SFXPool
|
|
54
|
+
└── Managers (Node)
|
|
55
|
+
├── GameManager (Autoload)
|
|
56
|
+
└── SaveManager (Autoload)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 2. Autoload (Singleton) Pattern
|
|
60
|
+
|
|
61
|
+
```gdscript
|
|
62
|
+
# GameManager.gd - Register as Autoload
|
|
63
|
+
extends Node
|
|
64
|
+
|
|
65
|
+
signal game_paused
|
|
66
|
+
signal game_resumed
|
|
67
|
+
signal score_changed(new_score: int)
|
|
68
|
+
|
|
69
|
+
var score: int = 0:
|
|
70
|
+
set(value):
|
|
71
|
+
score = value
|
|
72
|
+
score_changed.emit(score)
|
|
73
|
+
|
|
74
|
+
var is_paused: bool = false:
|
|
75
|
+
set(value):
|
|
76
|
+
is_paused = value
|
|
77
|
+
get_tree().paused = value
|
|
78
|
+
if value:
|
|
79
|
+
game_paused.emit()
|
|
80
|
+
else:
|
|
81
|
+
game_resumed.emit()
|
|
82
|
+
|
|
83
|
+
func reset_game() -> void:
|
|
84
|
+
score = 0
|
|
85
|
+
is_paused = false
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Recommended Project Structure
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
project/
|
|
92
|
+
├── addons/ # Third-party plugins
|
|
93
|
+
├── assets/
|
|
94
|
+
│ ├── art/
|
|
95
|
+
│ ├── audio/
|
|
96
|
+
│ └── fonts/
|
|
97
|
+
├── scenes/
|
|
98
|
+
│ ├── levels/
|
|
99
|
+
│ ├── ui/
|
|
100
|
+
│ └── entities/
|
|
101
|
+
├── scripts/
|
|
102
|
+
│ ├── autoloads/
|
|
103
|
+
│ ├── components/
|
|
104
|
+
│ ├── resources/
|
|
105
|
+
│ └── utils/
|
|
106
|
+
├── shaders/
|
|
107
|
+
└── project.godot
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## GDScript Best Practices
|
|
113
|
+
|
|
114
|
+
### 1. Type Hints (Always Use)
|
|
115
|
+
|
|
116
|
+
```gdscript
|
|
117
|
+
# ✅ GOOD - Fully typed
|
|
118
|
+
class_name Player
|
|
119
|
+
extends CharacterBody2D
|
|
120
|
+
|
|
121
|
+
@export var speed: float = 200.0
|
|
122
|
+
@export var jump_force: float = -400.0
|
|
123
|
+
|
|
124
|
+
var health: int = 100
|
|
125
|
+
var velocity_component: VelocityComponent
|
|
126
|
+
|
|
127
|
+
func take_damage(amount: int) -> void:
|
|
128
|
+
health -= amount
|
|
129
|
+
if health <= 0:
|
|
130
|
+
die()
|
|
131
|
+
|
|
132
|
+
func die() -> void:
|
|
133
|
+
queue_free()
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 2. Signals for Decoupling
|
|
137
|
+
|
|
138
|
+
```gdscript
|
|
139
|
+
# Player.gd
|
|
140
|
+
signal health_changed(new_health: int, max_health: int)
|
|
141
|
+
signal died
|
|
142
|
+
|
|
143
|
+
func take_damage(amount: int) -> void:
|
|
144
|
+
health -= amount
|
|
145
|
+
health_changed.emit(health, max_health)
|
|
146
|
+
if health <= 0:
|
|
147
|
+
died.emit()
|
|
148
|
+
|
|
149
|
+
# HealthBar.gd (Connect in editor or code)
|
|
150
|
+
func _ready() -> void:
|
|
151
|
+
var player := get_tree().get_first_node_in_group("player") as Player
|
|
152
|
+
player.health_changed.connect(_on_health_changed)
|
|
153
|
+
|
|
154
|
+
func _on_health_changed(current: int, maximum: int) -> void:
|
|
155
|
+
value = float(current) / float(maximum)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### 3. Resource-Based Data
|
|
159
|
+
|
|
160
|
+
```gdscript
|
|
161
|
+
# weapon_data.gd
|
|
162
|
+
class_name WeaponData
|
|
163
|
+
extends Resource
|
|
164
|
+
|
|
165
|
+
@export var name: String
|
|
166
|
+
@export var damage: int
|
|
167
|
+
@export var fire_rate: float
|
|
168
|
+
@export var icon: Texture2D
|
|
169
|
+
@export var projectile_scene: PackedScene
|
|
170
|
+
|
|
171
|
+
# Usage in code
|
|
172
|
+
@export var weapon: WeaponData
|
|
173
|
+
|
|
174
|
+
func attack() -> void:
|
|
175
|
+
var projectile := weapon.projectile_scene.instantiate()
|
|
176
|
+
projectile.damage = weapon.damage
|
|
177
|
+
add_child(projectile)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 4. Component Pattern
|
|
181
|
+
|
|
182
|
+
```gdscript
|
|
183
|
+
# health_component.gd
|
|
184
|
+
class_name HealthComponent
|
|
185
|
+
extends Node
|
|
186
|
+
|
|
187
|
+
signal health_changed(current: int, maximum: int)
|
|
188
|
+
signal died
|
|
189
|
+
|
|
190
|
+
@export var max_health: int = 100
|
|
191
|
+
var current_health: int
|
|
192
|
+
|
|
193
|
+
func _ready() -> void:
|
|
194
|
+
current_health = max_health
|
|
195
|
+
|
|
196
|
+
func take_damage(amount: int) -> void:
|
|
197
|
+
current_health = maxi(0, current_health - amount)
|
|
198
|
+
health_changed.emit(current_health, max_health)
|
|
199
|
+
if current_health == 0:
|
|
200
|
+
died.emit()
|
|
201
|
+
|
|
202
|
+
func heal(amount: int) -> void:
|
|
203
|
+
current_health = mini(max_health, current_health + amount)
|
|
204
|
+
health_changed.emit(current_health, max_health)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## State Machine Implementation
|
|
210
|
+
|
|
211
|
+
```gdscript
|
|
212
|
+
# state_machine.gd
|
|
213
|
+
class_name StateMachine
|
|
214
|
+
extends Node
|
|
215
|
+
|
|
216
|
+
@export var initial_state: State
|
|
217
|
+
var current_state: State
|
|
218
|
+
|
|
219
|
+
func _ready() -> void:
|
|
220
|
+
for child in get_children():
|
|
221
|
+
if child is State:
|
|
222
|
+
child.state_machine = self
|
|
223
|
+
|
|
224
|
+
if initial_state:
|
|
225
|
+
initial_state.enter()
|
|
226
|
+
current_state = initial_state
|
|
227
|
+
|
|
228
|
+
func _process(delta: float) -> void:
|
|
229
|
+
if current_state:
|
|
230
|
+
current_state.update(delta)
|
|
231
|
+
|
|
232
|
+
func _physics_process(delta: float) -> void:
|
|
233
|
+
if current_state:
|
|
234
|
+
current_state.physics_update(delta)
|
|
235
|
+
|
|
236
|
+
func transition_to(state_name: String) -> void:
|
|
237
|
+
var new_state := get_node_or_null(state_name) as State
|
|
238
|
+
if new_state and new_state != current_state:
|
|
239
|
+
current_state.exit()
|
|
240
|
+
current_state = new_state
|
|
241
|
+
current_state.enter()
|
|
242
|
+
|
|
243
|
+
# state.gd
|
|
244
|
+
class_name State
|
|
245
|
+
extends Node
|
|
246
|
+
|
|
247
|
+
var state_machine: StateMachine
|
|
248
|
+
|
|
249
|
+
func enter() -> void:
|
|
250
|
+
pass
|
|
251
|
+
|
|
252
|
+
func exit() -> void:
|
|
253
|
+
pass
|
|
254
|
+
|
|
255
|
+
func update(_delta: float) -> void:
|
|
256
|
+
pass
|
|
257
|
+
|
|
258
|
+
func physics_update(_delta: float) -> void:
|
|
259
|
+
pass
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Godot Shaders
|
|
265
|
+
|
|
266
|
+
### Basic 2D Shader
|
|
267
|
+
|
|
268
|
+
```gdshader
|
|
269
|
+
shader_type canvas_item;
|
|
270
|
+
|
|
271
|
+
uniform vec4 flash_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
|
|
272
|
+
uniform float flash_amount : hint_range(0.0, 1.0) = 0.0;
|
|
273
|
+
|
|
274
|
+
void fragment() {
|
|
275
|
+
vec4 tex_color = texture(TEXTURE, UV);
|
|
276
|
+
COLOR = mix(tex_color, flash_color, flash_amount);
|
|
277
|
+
COLOR.a = tex_color.a;
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Outline Shader
|
|
282
|
+
|
|
283
|
+
```gdshader
|
|
284
|
+
shader_type canvas_item;
|
|
285
|
+
|
|
286
|
+
uniform float outline_width : hint_range(0.0, 10.0) = 1.0;
|
|
287
|
+
uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
|
|
288
|
+
|
|
289
|
+
void fragment() {
|
|
290
|
+
vec2 size = TEXTURE_PIXEL_SIZE * outline_width;
|
|
291
|
+
|
|
292
|
+
float alpha = texture(TEXTURE, UV).a;
|
|
293
|
+
alpha += texture(TEXTURE, UV + vec2(size.x, 0)).a;
|
|
294
|
+
alpha += texture(TEXTURE, UV + vec2(-size.x, 0)).a;
|
|
295
|
+
alpha += texture(TEXTURE, UV + vec2(0, size.y)).a;
|
|
296
|
+
alpha += texture(TEXTURE, UV + vec2(0, -size.y)).a;
|
|
297
|
+
|
|
298
|
+
vec4 final_color = texture(TEXTURE, UV);
|
|
299
|
+
if (final_color.a < 1.0 && alpha > 0.0) {
|
|
300
|
+
final_color = outline_color;
|
|
301
|
+
}
|
|
302
|
+
COLOR = final_color;
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Godot RL Agents Integration
|
|
309
|
+
|
|
310
|
+
### Setup
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# Install Python package
|
|
314
|
+
pip install godot-rl
|
|
315
|
+
|
|
316
|
+
# Clone sync wrapper
|
|
317
|
+
git clone https://github.com/edbeeching/godot_rl_agents_plugin
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Basic RL Environment
|
|
321
|
+
|
|
322
|
+
```gdscript
|
|
323
|
+
# ai_agent.gd
|
|
324
|
+
extends AIController2D
|
|
325
|
+
|
|
326
|
+
func get_observations() -> Dictionary:
|
|
327
|
+
return {
|
|
328
|
+
"position": [global_position.x, global_position.y],
|
|
329
|
+
"velocity": [velocity.x, velocity.y],
|
|
330
|
+
"target": [target.global_position.x, target.global_position.y]
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
func set_action(action: Dictionary) -> void:
|
|
334
|
+
var move_x: float = action["move"][0]
|
|
335
|
+
var move_y: float = action["move"][1]
|
|
336
|
+
velocity = Vector2(move_x, move_y) * speed
|
|
337
|
+
|
|
338
|
+
func get_reward() -> float:
|
|
339
|
+
var distance := global_position.distance_to(target.global_position)
|
|
340
|
+
return -distance * 0.001
|
|
341
|
+
|
|
342
|
+
func is_done() -> bool:
|
|
343
|
+
return global_position.distance_to(target.global_position) < 10.0
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Performance Optimization
|
|
349
|
+
|
|
350
|
+
### Profiler Checklist
|
|
351
|
+
|
|
352
|
+
| Metric | Target | Check |
|
|
353
|
+
|--------|--------|-------|
|
|
354
|
+
| Frame Time | < 16ms | Debugger > Profiler |
|
|
355
|
+
| Physics FPS | 60 stable | Monitor > Debugger |
|
|
356
|
+
| Draw Calls | < 500 2D, < 200 mobile | Frame > Debugger |
|
|
357
|
+
| Object Count | Monitor growth | Remote > Nodes |
|
|
358
|
+
|
|
359
|
+
### Quick Wins
|
|
360
|
+
|
|
361
|
+
```gdscript
|
|
362
|
+
# 1. Use object pooling
|
|
363
|
+
var bullet_pool: Array[Bullet] = []
|
|
364
|
+
|
|
365
|
+
func get_bullet() -> Bullet:
|
|
366
|
+
if bullet_pool.is_empty():
|
|
367
|
+
return bullet_scene.instantiate()
|
|
368
|
+
return bullet_pool.pop_back()
|
|
369
|
+
|
|
370
|
+
func return_bullet(bullet: Bullet) -> void:
|
|
371
|
+
bullet.visible = false
|
|
372
|
+
bullet_pool.append(bullet)
|
|
373
|
+
|
|
374
|
+
# 2. Use call_deferred for heavy operations
|
|
375
|
+
queue_free.call_deferred()
|
|
376
|
+
|
|
377
|
+
# 3. Disable processing when not needed
|
|
378
|
+
set_process(false)
|
|
379
|
+
set_physics_process(false)
|
|
380
|
+
|
|
381
|
+
# 4. Use groups for efficient queries
|
|
382
|
+
get_tree().get_nodes_in_group("enemies")
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## C# in Godot
|
|
388
|
+
|
|
389
|
+
### When to Use C#
|
|
390
|
+
|
|
391
|
+
| Use GDScript When | Use C# When |
|
|
392
|
+
|-------------------|-------------|
|
|
393
|
+
| Rapid prototyping | Complex systems |
|
|
394
|
+
| Simple games | Team knows C# |
|
|
395
|
+
| Learning Godot | Need .NET libraries |
|
|
396
|
+
| Hot reload needed | Performance-critical |
|
|
397
|
+
|
|
398
|
+
### C# Example
|
|
399
|
+
|
|
400
|
+
```csharp
|
|
401
|
+
using Godot;
|
|
402
|
+
|
|
403
|
+
public partial class Player : CharacterBody2D
|
|
404
|
+
{
|
|
405
|
+
[Export] public float Speed { get; set; } = 200.0f;
|
|
406
|
+
[Export] public float JumpForce { get; set; } = -400.0f;
|
|
407
|
+
|
|
408
|
+
private float _gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle();
|
|
409
|
+
|
|
410
|
+
public override void _PhysicsProcess(double delta)
|
|
411
|
+
{
|
|
412
|
+
Vector2 velocity = Velocity;
|
|
413
|
+
|
|
414
|
+
if (!IsOnFloor())
|
|
415
|
+
velocity.Y += _gravity * (float)delta;
|
|
416
|
+
|
|
417
|
+
if (Input.IsActionJustPressed("jump") && IsOnFloor())
|
|
418
|
+
velocity.Y = JumpForce;
|
|
419
|
+
|
|
420
|
+
float direction = Input.GetAxis("move_left", "move_right");
|
|
421
|
+
velocity.X = direction * Speed;
|
|
422
|
+
|
|
423
|
+
Velocity = velocity;
|
|
424
|
+
MoveAndSlide();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## Anti-Patterns
|
|
432
|
+
|
|
433
|
+
| ❌ Don't | ✅ Do |
|
|
434
|
+
|----------|-------|
|
|
435
|
+
| `get_node` with long paths | `@onready` + short paths |
|
|
436
|
+
| Process when not needed | `set_process(false)` |
|
|
437
|
+
| Create nodes in `_process` | Object pooling |
|
|
438
|
+
| Use strings for node paths | `@export NodePath` |
|
|
439
|
+
| Hardcode values | Resources or exports |
|
|
440
|
+
| Skip type hints | Always use type hints |
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Quick Reference Commands
|
|
445
|
+
|
|
446
|
+
```bash
|
|
447
|
+
# Export from command line
|
|
448
|
+
godot --headless --export-release "Windows Desktop" build/game.exe
|
|
449
|
+
|
|
450
|
+
# Run specific scene
|
|
451
|
+
godot scenes/main.tscn
|
|
452
|
+
|
|
453
|
+
# Run tests (GUT plugin)
|
|
454
|
+
godot --headless -s addons/gut/gut_cmdln.gd -gdir=res://test/
|
|
455
|
+
|
|
456
|
+
# Convert project format
|
|
457
|
+
godot --convert-project
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
> **Remember:** Godot's strength is simplicity. Don't fight the engine—embrace scene composition and signals.
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hybrid-game-spec
|
|
3
|
+
description: Templates và hướng dẫn tạo Macro Spec cho game phức tạp. Bao gồm SPEC-architecture và SCHEMA-data patterns.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Hybrid Game Spec Skill
|
|
7
|
+
|
|
8
|
+
> **Purpose**: Cung cấp templates và nguyên tắc để tạo "Macro Spec" cho game trước khi code.
|
|
9
|
+
|
|
10
|
+
## Khi Nào Sử Dụng
|
|
11
|
+
- Bắt đầu dự án game phức tạp (3+ systems)
|
|
12
|
+
- Khi cần định nghĩa architecture trước khi phát triển
|
|
13
|
+
- Khi muốn nhiều agents làm việc song song
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. SPEC-architecture.md Template
|
|
18
|
+
|
|
19
|
+
Template đầy đủ tại: [SPEC-architecture-template.md](./templates/SPEC-architecture-template.md)
|
|
20
|
+
|
|
21
|
+
### Nội dung bắt buộc:
|
|
22
|
+
|
|
23
|
+
| Section | Mô tả |
|
|
24
|
+
|---------|-------|
|
|
25
|
+
| **Event Bus** | Liệt kê TẤT CẢ game events (OnPlayerHurt, OnScoreChanged...) |
|
|
26
|
+
| **Manager Sequence** | Thứ tự khởi tạo Singletons |
|
|
27
|
+
| **Save System** | Contract cho save/load data |
|
|
28
|
+
| **Input Abstraction** | Interface cho touch/keyboard |
|
|
29
|
+
|
|
30
|
+
### Event Bus Pattern
|
|
31
|
+
|
|
32
|
+
```csharp
|
|
33
|
+
// GameEvents.cs - Static event bus
|
|
34
|
+
public static class GameEvents
|
|
35
|
+
{
|
|
36
|
+
// Core Events
|
|
37
|
+
public static event Action<int> OnScoreChanged;
|
|
38
|
+
public static event Action<int> OnHealthChanged;
|
|
39
|
+
public static event Action OnPlayerDied;
|
|
40
|
+
public static event Action<int> OnLevelComplete;
|
|
41
|
+
|
|
42
|
+
// UI Events
|
|
43
|
+
public static event Action OnPauseRequested;
|
|
44
|
+
public static event Action OnResumeRequested;
|
|
45
|
+
|
|
46
|
+
// Economy Events
|
|
47
|
+
public static event Action<int> OnCoinCollected;
|
|
48
|
+
public static event Action<string, int> OnItemPurchased;
|
|
49
|
+
|
|
50
|
+
// Invocation helpers
|
|
51
|
+
public static void ScoreChanged(int score) => OnScoreChanged?.Invoke(score);
|
|
52
|
+
public static void PlayerDied() => OnPlayerDied?.Invoke();
|
|
53
|
+
|
|
54
|
+
// Cleanup (call on scene unload)
|
|
55
|
+
public static void ClearAll()
|
|
56
|
+
{
|
|
57
|
+
OnScoreChanged = null;
|
|
58
|
+
OnHealthChanged = null;
|
|
59
|
+
OnPlayerDied = null;
|
|
60
|
+
// ... clear all
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 2. SCHEMA-data.md Template
|
|
68
|
+
|
|
69
|
+
Template đầy đủ tại: [SCHEMA-data-template.md](./templates/SCHEMA-data-template.md)
|
|
70
|
+
|
|
71
|
+
### Nguyên Tắc ScriptableObject
|
|
72
|
+
|
|
73
|
+
| Rule | Lý Do |
|
|
74
|
+
|------|-------|
|
|
75
|
+
| **Mọi số balance phải trong SO** | AI có thể sửa .asset mà không làm hỏng logic |
|
|
76
|
+
| **Nested structs cho complex data** | Tổ chức rõ ràng |
|
|
77
|
+
| **[CreateAssetMenu] attribute** | Dễ tạo asset trong Editor |
|
|
78
|
+
| **Default values có ý nghĩa** | Game chạy được ngay cả khi chưa tune |
|
|
79
|
+
|
|
80
|
+
### ScriptableObject Patterns
|
|
81
|
+
|
|
82
|
+
```csharp
|
|
83
|
+
// CharacterData.cs
|
|
84
|
+
[CreateAssetMenu(fileName = "CharacterData", menuName = "Game/Data/Character")]
|
|
85
|
+
public class CharacterData : ScriptableObject
|
|
86
|
+
{
|
|
87
|
+
[Header("Movement")]
|
|
88
|
+
public float MoveSpeed = 5f;
|
|
89
|
+
public float JumpForce = 10f;
|
|
90
|
+
public float Gravity = 2f;
|
|
91
|
+
|
|
92
|
+
[Header("Combat")]
|
|
93
|
+
public int MaxHealth = 100;
|
|
94
|
+
public int AttackDamage = 10;
|
|
95
|
+
public float AttackCooldown = 0.5f;
|
|
96
|
+
|
|
97
|
+
[Header("Progression")]
|
|
98
|
+
public AnimationCurve LevelUpCurve;
|
|
99
|
+
public int BaseXP = 100;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// EnemyData.cs
|
|
103
|
+
[CreateAssetMenu(fileName = "EnemyData", menuName = "Game/Data/Enemy")]
|
|
104
|
+
public class EnemyData : ScriptableObject
|
|
105
|
+
{
|
|
106
|
+
public string EnemyName;
|
|
107
|
+
public Sprite Icon;
|
|
108
|
+
|
|
109
|
+
[Header("Stats")]
|
|
110
|
+
public int Health = 50;
|
|
111
|
+
public int Damage = 10;
|
|
112
|
+
public float MoveSpeed = 3f;
|
|
113
|
+
|
|
114
|
+
[Header("Behavior")]
|
|
115
|
+
public float DetectionRange = 5f;
|
|
116
|
+
public float AttackRange = 1.5f;
|
|
117
|
+
public float PatrolSpeed = 2f;
|
|
118
|
+
|
|
119
|
+
[Header("Drops")]
|
|
120
|
+
public int MinCoinDrop = 5;
|
|
121
|
+
public int MaxCoinDrop = 15;
|
|
122
|
+
public float DropChance = 0.3f;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// LevelConfig.cs
|
|
126
|
+
[CreateAssetMenu(fileName = "Level_01", menuName = "Game/Data/Level")]
|
|
127
|
+
public class LevelConfig : ScriptableObject
|
|
128
|
+
{
|
|
129
|
+
public int LevelNumber;
|
|
130
|
+
public string LevelName;
|
|
131
|
+
public string SceneName;
|
|
132
|
+
|
|
133
|
+
[Header("Difficulty")]
|
|
134
|
+
public Difficulty Difficulty;
|
|
135
|
+
public int EnemyCount;
|
|
136
|
+
public float TimeLimit;
|
|
137
|
+
|
|
138
|
+
[Header("Rewards")]
|
|
139
|
+
public int StarThreshold1;
|
|
140
|
+
public int StarThreshold2;
|
|
141
|
+
public int StarThreshold3;
|
|
142
|
+
public int CompletionBonus;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public enum Difficulty { Easy, Normal, Hard, Nightmare }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 3. Decoupled System Pattern
|
|
151
|
+
|
|
152
|
+
### Why Decoupling?
|
|
153
|
+
|
|
154
|
+
| Coupled (❌) | Decoupled (✅) |
|
|
155
|
+
|--------------|---------------|
|
|
156
|
+
| Agent A sửa file → Agent B bị conflict | Agents làm song song |
|
|
157
|
+
| Change UI → phải sửa Combat code | Change 1 nơi, không ảnh hưởng nơi khác |
|
|
158
|
+
| Hard to test | Easy to unit test |
|
|
159
|
+
|
|
160
|
+
### Implementation
|
|
161
|
+
|
|
162
|
+
```csharp
|
|
163
|
+
// ✅ Combat KHÔNG biết về UI
|
|
164
|
+
public class CombatSystem : MonoBehaviour
|
|
165
|
+
{
|
|
166
|
+
[SerializeField] private CharacterData _data;
|
|
167
|
+
private int _currentHealth;
|
|
168
|
+
|
|
169
|
+
void Start() => _currentHealth = _data.MaxHealth;
|
|
170
|
+
|
|
171
|
+
public void TakeDamage(int damage)
|
|
172
|
+
{
|
|
173
|
+
_currentHealth -= damage;
|
|
174
|
+
|
|
175
|
+
// Fire event, KHÔNG gọi UI trực tiếp
|
|
176
|
+
GameEvents.HealthChanged(_currentHealth);
|
|
177
|
+
|
|
178
|
+
if (_currentHealth <= 0)
|
|
179
|
+
GameEvents.PlayerDied();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ✅ UI SUBSCRIBE to events
|
|
184
|
+
public class HealthUI : MonoBehaviour
|
|
185
|
+
{
|
|
186
|
+
[SerializeField] private Slider _healthBar;
|
|
187
|
+
[SerializeField] private CharacterData _data;
|
|
188
|
+
|
|
189
|
+
void OnEnable() => GameEvents.OnHealthChanged += UpdateHealth;
|
|
190
|
+
void OnDisable() => GameEvents.OnHealthChanged -= UpdateHealth;
|
|
191
|
+
|
|
192
|
+
void UpdateHealth(int current)
|
|
193
|
+
{
|
|
194
|
+
_healthBar.value = (float)current / _data.MaxHealth;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 4. Checklist Trước Khi Code
|
|
202
|
+
|
|
203
|
+
- [ ] Event Bus defined với TẤT CẢ events
|
|
204
|
+
- [ ] Manager bootstrap sequence documented
|
|
205
|
+
- [ ] Save system contract defined
|
|
206
|
+
- [ ] Character ScriptableObject template created
|
|
207
|
+
- [ ] Enemy ScriptableObject template created
|
|
208
|
+
- [ ] Level ScriptableObject template created
|
|
209
|
+
- [ ] Input abstraction layer designed
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Related Skills
|
|
214
|
+
- `game-development/unity-integration`
|
|
215
|
+
- `game-development/game-design`
|
|
216
|
+
- `clean-code`
|
|
217
|
+
|
|
218
|
+
## Related Workflows
|
|
219
|
+
- `/game-hybrid` - Sử dụng skill này cho Tầng 1
|
|
220
|
+
- `/game-from-idea` - Simplified workflow cho rapid prototyping
|