tweaks
This commit is contained in:
219
AGENTS.md
Normal file
219
AGENTS.md
Normal file
@@ -0,0 +1,219 @@
|
||||
# AGENTS.md - AI Agent Guidelines for ai-game-2
|
||||
|
||||
## Project Overview
|
||||
|
||||
This is a **Godot 4.6** game project (King's Quest IV remake). The project uses:
|
||||
- Godot's scene system (`.tscn` files)
|
||||
- GDScript (`.gd` files) for game logic
|
||||
- NavigationServer2D for pathfinding
|
||||
- Custom script builder pattern for game scripts
|
||||
|
||||
|
||||
## Build & Development Commands
|
||||
|
||||
### Running the Game
|
||||
```bash
|
||||
# Open in Godot editor (headless for CI)
|
||||
godot --headless --path .
|
||||
|
||||
# Or run the exported game (if built)
|
||||
./export/linux/ai-game
|
||||
```
|
||||
|
||||
### Single Test/Scene Testing
|
||||
Godot doesn't have a traditional test framework. To test a single scene:
|
||||
1. Open the project in Godot
|
||||
2. Set the scene as the main scene in project.godot
|
||||
3. Run with F5
|
||||
|
||||
### Code Quality
|
||||
```bash
|
||||
# Godot's built-in lint (via editor)
|
||||
# Tools > Analyze > Check Code
|
||||
|
||||
# For CI, you can run headless:
|
||||
godot --headless --script-check .
|
||||
```
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
*** CRITICAL ****
|
||||
When you need to create a new uid, run python make_uid.py, and it will return a unique uid. When creating scenes, at a <scene>.tscn.uid with the contents uid://<uid>
|
||||
|
||||
### File Organization
|
||||
- **Scenes**: `scenes/kq4_XXX_room_name/`
|
||||
- **Scripts**: `scenes/kq4_XXX_room_name/kq4_XXX_room_name.gd`
|
||||
- **Resources**: Visual assets copied to room folders
|
||||
- **Template**: Use `scenes/kq4_placeholder_template/` when creating new rooms
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
| Element | Convention | Example |
|
||||
|---------|------------|---------|
|
||||
| Scenes | `kq4_XXX_description` (snake_case) | `kq4_010_forest_path` |
|
||||
| Nodes | PascalCase | `kq4_004_ogres_cottage` |
|
||||
| Scripts | snake_case.gd | `kq4_010_forest_path.gd` |
|
||||
| Variables | snake_case | `appear_at_node` |
|
||||
| Constants | SCREAMING_SNAKE | `const MAX_SPEED = 100` |
|
||||
| Classes | PascalCase | `class_name Scene` |
|
||||
|
||||
### GDScript Patterns
|
||||
|
||||
#### Class Definition
|
||||
```gdscript
|
||||
extends Node2D
|
||||
class_name MyClass
|
||||
|
||||
# Use @export for editor-exposed variables
|
||||
@export var my_var: int = 0
|
||||
@export_file("*.tscn") var target_scene: String
|
||||
```
|
||||
|
||||
#### Type Hints (Required)
|
||||
```gdscript
|
||||
var player: Node2D
|
||||
var score: int = 0
|
||||
var name: String = ""
|
||||
|
||||
func move_to(position: Vector2) -> void:
|
||||
pass
|
||||
```
|
||||
|
||||
#### Signals
|
||||
```gdscript
|
||||
signal my_signal(value: int)
|
||||
|
||||
# Connecting
|
||||
some_node.my_signal.connect(_on_my_signal)
|
||||
|
||||
# Or in editor-created connections:
|
||||
[connection signal="interacted" from="transition_piece" to="." method="_on_interacted"]
|
||||
```
|
||||
|
||||
### Scene Structure (.tscn)
|
||||
|
||||
#### Header
|
||||
```gdscript
|
||||
[gd_scene format=3 uid="uid://xxxxx"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://xxxxx" path="res://path/to/script.gd" id="1_abc"]
|
||||
[ext_resource type="Texture2D" uid="uid://xxxxx" path="res://path/to/texture.png" id="2_abc"]
|
||||
[ext_resource type="PackedScene" uid="uid://xxxxx" path="res://TransitionPiece.tscn" id="3_abc"]
|
||||
```
|
||||
|
||||
#### Node Hierarchy
|
||||
- Use meaningful node names
|
||||
- Prefix private nodes with underscore when appropriate
|
||||
- Use `unique_id=` for editor-managed nodes
|
||||
|
||||
#### Transition Pieces
|
||||
When adding exits to rooms:
|
||||
```gdscript
|
||||
[node name="kq4_004_ogres_cottage" parent="." instance=ExtResource("4_abc")]
|
||||
position = Vector2(910, -213)
|
||||
polygon = PackedVector2Array(...)
|
||||
appear_at_node = "kq4_010_forest_path" # Node name in target scene
|
||||
target = "uid://xxxxxxxx" # Scene UID
|
||||
label = "Ogre's Cottage"
|
||||
|
||||
[node name="entrance" parent="kq4_004_ogres_cottage" index="0"]
|
||||
position = Vector2(163, 598)
|
||||
|
||||
[node name="exit" parent="kq4_004_ogres_cottage" index="1"]
|
||||
position = Vector2(159, 459)
|
||||
|
||||
[connection signal="interacted" from="kq4_004_ogres_cottage" to="." method="_on_ogres_cottage_interacted"]
|
||||
|
||||
[editable path="kq4_004_ogres_cottage"]
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
- Use `push_error()` for critical issues
|
||||
- Use `push_warning()` for non-critical issues
|
||||
- Always check `load()` returns with `if resource:` before using
|
||||
- Use `@onready` for node references (handles load order)
|
||||
|
||||
### Room Creation Process
|
||||
|
||||
1. **Copy template**: `cp -r scenes/kq4_placeholder_template scenes/kq4_XXX_name`
|
||||
2. **Rename files**: Update `.gd` and `.tscn` filenames
|
||||
3. **Copy visual**: Copy `pic_XXX_visual.png` from decompile
|
||||
4. **Update .tscn**:
|
||||
- Remove hardcoded UIDs (let Godot generate)
|
||||
- Add transition pieces for cardinal directions
|
||||
- Set labels to human-readable names
|
||||
5. **Update .gd**: Add signal handlers for connected rooms
|
||||
6. **Generate UIDs**: Let Godot import, then create `.uid` files
|
||||
7. **Wire transitions**: Update `target` fields with real UIDs
|
||||
|
||||
### Import Files
|
||||
|
||||
When creating new room textures, create `.import` files:
|
||||
```ini
|
||||
[remap]
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://xxxxxxxx"
|
||||
path="res://.godot/imported/image.png-xxx.ctex"
|
||||
|
||||
[deps]
|
||||
source_file="res://scenes/room_name/image.png"
|
||||
dest_files=[...]
|
||||
|
||||
[params]
|
||||
compress/mode=0
|
||||
# ... standard Godot texture params
|
||||
```
|
||||
|
||||
### What NOT to Do
|
||||
|
||||
- **Don't** commit secrets/keys (use `.gitignore`)
|
||||
- **Don't** use `print()` for debugging in production (use `push_warning()`)
|
||||
- **Don't** hardcode paths - use `res://` relative paths
|
||||
- **Don't** modify `project.godot` unless necessary
|
||||
- **Don't** delete the `meadow-2` scene (unrelated to KQ4 rooms)
|
||||
|
||||
### File Extensions to Know
|
||||
|
||||
| Extension | Purpose |
|
||||
|-----------|---------|
|
||||
| `.gd` | GDScript source |
|
||||
| `.tscn` | Godot scene |
|
||||
| `.tres` | Godot resource |
|
||||
| `.import` | Import configuration |
|
||||
| `.uid` | Resource UID cache |
|
||||
| `.md` | Room documentation (in kq4-sierra-decompile) |
|
||||
|
||||
### Room Specs Reference
|
||||
|
||||
Room specifications are in `kq4-sierra-decompile/rooms/kq4-XXX-name/`.
|
||||
Each room has:
|
||||
- `kq4-XXX-name.md` - Technical documentation
|
||||
- `pic_XXX_visual.png` - Background image
|
||||
- `pic_XXX_control.png` - Control/hitbox areas
|
||||
- `pic_XXX_priority.png` - Priority/z-ordering
|
||||
|
||||
### Key Classes
|
||||
|
||||
- `Scene` (Scene.gd) - Base room class with navigation
|
||||
- `TransitionPiece` (TransitionPiece.gd) - Exit/entry points
|
||||
- `GameScript` (GameScript.gd) - Script builder for cutscenes
|
||||
- `Ego` (Ego.gd) - Player character
|
||||
|
||||
### Common Patterns
|
||||
|
||||
#### Navigation
|
||||
```gdscript
|
||||
var path = NavigationServer2D.map_get_path(map, start, end, true)
|
||||
```
|
||||
|
||||
#### Pathfinding Movement
|
||||
```gdscript
|
||||
scene.start_main_script(scene.ScriptBuilder.init(scene.ScriptBuilder.walk_path(ego, path)).build())
|
||||
```
|
||||
|
||||
#### Scene Transitions
|
||||
```gdscript
|
||||
func _on_exit_interacted() -> void:
|
||||
$target_scene.default_script(self)
|
||||
```
|
||||
Reference in New Issue
Block a user