Compare commits
27 Commits
078caadd0c
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| cc051a1e15 | |||
| 80957641bd | |||
| 0b560b94ca | |||
| c24709d02d | |||
| 8929c4fc09 | |||
| b2c243a819 | |||
| 971e830c6a | |||
| 2479e4c784 | |||
| 868b25299a | |||
| 7a7d9e78db | |||
| 9b5a7040c2 | |||
| ec4fc8e756 | |||
| 784867833d | |||
| aa79040dcb | |||
| b8b3c79e99 | |||
| 639060fa7f | |||
| dee6216873 | |||
| a0afc9bd1f | |||
| 1465104b98 | |||
| 5ae9ff1f17 | |||
| 0ec2f52172 | |||
| 18bfeb9bcc | |||
| 5f144fb5d7 | |||
| 5e9fb9251e | |||
| e8982ba4ef | |||
| 5613ae1d8c | |||
| c0db909092 |
51
.beads/.gitignore
vendored
51
.beads/.gitignore
vendored
@@ -1,51 +0,0 @@
|
|||||||
# Dolt database (managed by Dolt, not git)
|
|
||||||
dolt/
|
|
||||||
dolt-access.lock
|
|
||||||
|
|
||||||
# Runtime files
|
|
||||||
bd.sock
|
|
||||||
bd.sock.startlock
|
|
||||||
sync-state.json
|
|
||||||
last-touched
|
|
||||||
|
|
||||||
# Local version tracking (prevents upgrade notification spam after git ops)
|
|
||||||
.local_version
|
|
||||||
|
|
||||||
# Worktree redirect file (contains relative path to main repo's .beads/)
|
|
||||||
# Must not be committed as paths would be wrong in other clones
|
|
||||||
redirect
|
|
||||||
|
|
||||||
# Sync state (local-only, per-machine)
|
|
||||||
# These files are machine-specific and should not be shared across clones
|
|
||||||
.sync.lock
|
|
||||||
export-state/
|
|
||||||
|
|
||||||
# Ephemeral store (SQLite - wisps/molecules, intentionally not versioned)
|
|
||||||
ephemeral.sqlite3
|
|
||||||
ephemeral.sqlite3-journal
|
|
||||||
ephemeral.sqlite3-wal
|
|
||||||
ephemeral.sqlite3-shm
|
|
||||||
|
|
||||||
# Dolt server management (auto-started by bd)
|
|
||||||
dolt-server.pid
|
|
||||||
dolt-server.log
|
|
||||||
dolt-server.lock
|
|
||||||
dolt-server.port
|
|
||||||
dolt-server.activity
|
|
||||||
dolt-monitor.pid
|
|
||||||
|
|
||||||
# Backup data (auto-exported JSONL, local-only)
|
|
||||||
backup/
|
|
||||||
|
|
||||||
# Legacy files (from pre-Dolt versions)
|
|
||||||
*.db
|
|
||||||
*.db?*
|
|
||||||
*.db-journal
|
|
||||||
*.db-wal
|
|
||||||
*.db-shm
|
|
||||||
db.sqlite
|
|
||||||
bd.db
|
|
||||||
# NOTE: Do NOT add negation patterns here.
|
|
||||||
# They would override fork protection in .git/info/exclude.
|
|
||||||
# Config files (metadata.json, config.yaml) are tracked by git by default
|
|
||||||
# since no pattern above ignores them.
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
# Beads - AI-Native Issue Tracking
|
|
||||||
|
|
||||||
Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code.
|
|
||||||
|
|
||||||
## What is Beads?
|
|
||||||
|
|
||||||
Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git.
|
|
||||||
|
|
||||||
**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads)
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
### Essential Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create new issues
|
|
||||||
bd create "Add user authentication"
|
|
||||||
|
|
||||||
# View all issues
|
|
||||||
bd list
|
|
||||||
|
|
||||||
# View issue details
|
|
||||||
bd show <issue-id>
|
|
||||||
|
|
||||||
# Update issue status
|
|
||||||
bd update <issue-id> --claim
|
|
||||||
bd update <issue-id> --status done
|
|
||||||
|
|
||||||
# Sync with Dolt remote
|
|
||||||
bd dolt push
|
|
||||||
```
|
|
||||||
|
|
||||||
### Working with Issues
|
|
||||||
|
|
||||||
Issues in Beads are:
|
|
||||||
- **Git-native**: Stored in Dolt database with version control and branching
|
|
||||||
- **AI-friendly**: CLI-first design works perfectly with AI coding agents
|
|
||||||
- **Branch-aware**: Issues can follow your branch workflow
|
|
||||||
- **Always in sync**: Auto-syncs with your commits
|
|
||||||
|
|
||||||
## Why Beads?
|
|
||||||
|
|
||||||
✨ **AI-Native Design**
|
|
||||||
- Built specifically for AI-assisted development workflows
|
|
||||||
- CLI-first interface works seamlessly with AI coding agents
|
|
||||||
- No context switching to web UIs
|
|
||||||
|
|
||||||
🚀 **Developer Focused**
|
|
||||||
- Issues live in your repo, right next to your code
|
|
||||||
- Works offline, syncs when you push
|
|
||||||
- Fast, lightweight, and stays out of your way
|
|
||||||
|
|
||||||
🔧 **Git Integration**
|
|
||||||
- Automatic sync with git commits
|
|
||||||
- Branch-aware issue tracking
|
|
||||||
- Dolt-native three-way merge resolution
|
|
||||||
|
|
||||||
## Get Started with Beads
|
|
||||||
|
|
||||||
Try Beads in your own projects:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install Beads
|
|
||||||
curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
|
|
||||||
|
|
||||||
# Initialize in your repo
|
|
||||||
bd init
|
|
||||||
|
|
||||||
# Create your first issue
|
|
||||||
bd create "Try out Beads"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Learn More
|
|
||||||
|
|
||||||
- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs)
|
|
||||||
- **Quick Start Guide**: Run `bd quickstart`
|
|
||||||
- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*Beads: Issue tracking that moves at the speed of thought* ⚡
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
# Beads Configuration File
|
|
||||||
# This file configures default behavior for all bd commands in this repository
|
|
||||||
# All settings can also be set via environment variables (BD_* prefix)
|
|
||||||
# or overridden with command-line flags
|
|
||||||
|
|
||||||
# Issue prefix for this repository (used by bd init)
|
|
||||||
# If not set, bd init will auto-detect from directory name
|
|
||||||
# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc.
|
|
||||||
# issue-prefix: ""
|
|
||||||
|
|
||||||
# Use no-db mode: JSONL-only, no Dolt database
|
|
||||||
# When true, bd will use .beads/issues.jsonl as the source of truth
|
|
||||||
# no-db: false
|
|
||||||
|
|
||||||
# Enable JSON output by default
|
|
||||||
# json: false
|
|
||||||
|
|
||||||
# Feedback title formatting for mutating commands (create/update/close/dep/edit)
|
|
||||||
# 0 = hide titles, N > 0 = truncate to N characters
|
|
||||||
# output:
|
|
||||||
# title-length: 255
|
|
||||||
|
|
||||||
# Default actor for audit trails (overridden by BD_ACTOR or --actor)
|
|
||||||
# actor: ""
|
|
||||||
|
|
||||||
# Export events (audit trail) to .beads/events.jsonl on each flush/sync
|
|
||||||
# When enabled, new events are appended incrementally using a high-water mark.
|
|
||||||
# Use 'bd export --events' to trigger manually regardless of this setting.
|
|
||||||
# events-export: false
|
|
||||||
|
|
||||||
# Multi-repo configuration (experimental - bd-307)
|
|
||||||
# Allows hydrating from multiple repositories and routing writes to the correct database
|
|
||||||
# repos:
|
|
||||||
# primary: "." # Primary repo (where this database lives)
|
|
||||||
# additional: # Additional repos to hydrate from (read-only)
|
|
||||||
# - ~/beads-planning # Personal planning repo
|
|
||||||
# - ~/work-planning # Work planning repo
|
|
||||||
|
|
||||||
# JSONL backup (periodic export for off-machine recovery)
|
|
||||||
# Auto-enabled when a git remote exists. Override explicitly:
|
|
||||||
# backup:
|
|
||||||
# enabled: false # Disable auto-backup entirely
|
|
||||||
# interval: 15m # Minimum time between auto-exports
|
|
||||||
# git-push: false # Disable git push (export locally only)
|
|
||||||
# git-repo: "" # Separate git repo for backups (default: project repo)
|
|
||||||
|
|
||||||
# Integration settings (access with 'bd config get/set')
|
|
||||||
# These are stored in the database, not in this file:
|
|
||||||
# - jira.url
|
|
||||||
# - jira.project
|
|
||||||
# - linear.url
|
|
||||||
# - linear.api-key
|
|
||||||
# - github.org
|
|
||||||
# - github.repo
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
# --- BEGIN BEADS INTEGRATION v0.59.0 ---
|
|
||||||
# This section is managed by beads. Do not remove these markers.
|
|
||||||
if command -v bd >/dev/null 2>&1; then
|
|
||||||
export BD_GIT_HOOK=1
|
|
||||||
bd hooks run post-checkout "$@"
|
|
||||||
_bd_exit=$?; if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
|
|
||||||
fi
|
|
||||||
# --- END BEADS INTEGRATION v0.59.0 ---
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
# --- BEGIN BEADS INTEGRATION v0.59.0 ---
|
|
||||||
# This section is managed by beads. Do not remove these markers.
|
|
||||||
if command -v bd >/dev/null 2>&1; then
|
|
||||||
export BD_GIT_HOOK=1
|
|
||||||
bd hooks run post-merge "$@"
|
|
||||||
_bd_exit=$?; if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
|
|
||||||
fi
|
|
||||||
# --- END BEADS INTEGRATION v0.59.0 ---
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
# --- BEGIN BEADS INTEGRATION v0.59.0 ---
|
|
||||||
# This section is managed by beads. Do not remove these markers.
|
|
||||||
if command -v bd >/dev/null 2>&1; then
|
|
||||||
export BD_GIT_HOOK=1
|
|
||||||
bd hooks run pre-commit "$@"
|
|
||||||
_bd_exit=$?; if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
|
|
||||||
fi
|
|
||||||
# --- END BEADS INTEGRATION v0.59.0 ---
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
# --- BEGIN BEADS INTEGRATION v0.59.0 ---
|
|
||||||
# This section is managed by beads. Do not remove these markers.
|
|
||||||
if command -v bd >/dev/null 2>&1; then
|
|
||||||
export BD_GIT_HOOK=1
|
|
||||||
bd hooks run pre-push "$@"
|
|
||||||
_bd_exit=$?; if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
|
|
||||||
fi
|
|
||||||
# --- END BEADS INTEGRATION v0.59.0 ---
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
# --- BEGIN BEADS INTEGRATION v0.59.0 ---
|
|
||||||
# This section is managed by beads. Do not remove these markers.
|
|
||||||
if command -v bd >/dev/null 2>&1; then
|
|
||||||
export BD_GIT_HOOK=1
|
|
||||||
bd hooks run prepare-commit-msg "$@"
|
|
||||||
_bd_exit=$?; if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
|
|
||||||
fi
|
|
||||||
# --- END BEADS INTEGRATION v0.59.0 ---
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"database": "dolt",
|
|
||||||
"backend": "dolt",
|
|
||||||
"dolt_mode": "server",
|
|
||||||
"dolt_database": "ai_game_2",
|
|
||||||
"project_id": "16f0248d-5833-44e9-91cc-42afea26fd77"
|
|
||||||
}
|
|
||||||
7
.gitattributes
vendored
7
.gitattributes
vendored
@@ -1,3 +1,10 @@
|
|||||||
|
# Line ending normalization - prevents Windows/Linux conflicts
|
||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
# Windows-only files should use CRLF
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.cmd text eol=crlf
|
||||||
|
|
||||||
Assets/**/*.png filter=lfs diff=lfs merge=lfs -text
|
Assets/**/*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
**/*.png filter=lfs diff=lfs merge=lfs -text
|
**/*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
scenes/entrance/entrance-wall.png filter=lfs diff=lfs merge=lfs -text
|
scenes/entrance/entrance-wall.png filter=lfs diff=lfs merge=lfs -text
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,3 +14,4 @@ tmp/**
|
|||||||
tools/ora_editor/node_modules/*
|
tools/ora_editor/node_modules/*
|
||||||
node_modules/*
|
node_modules/*
|
||||||
**/*.log
|
**/*.log
|
||||||
|
kq4-sierra-decompile/**
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
|||||||
[submodule "kq4-sierra-decompile"]
|
[submodule "kq4-sierra-decompile"]
|
||||||
path = kq4-sierra-decompile
|
path = kq4-sierra-decompile
|
||||||
url = ssh://raspberrypi/~/git/sierra-decompile
|
url = ssh://raspberrypi/~/git/sierra-decompile
|
||||||
|
[submodule "godot-mcp"]
|
||||||
|
path = godot-mcp
|
||||||
|
url = https://github.com/tugcantopaloglu/godot-mcp
|
||||||
|
|||||||
281
.opencode/package-lock.json
generated
281
.opencode/package-lock.json
generated
@@ -5,21 +5,100 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/plugin": "1.3.14"
|
"@opencode-ai/plugin": "1.14.29"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/@opencode-ai/plugin": {
|
"node_modules/@opencode-ai/plugin": {
|
||||||
"version": "1.3.14",
|
"version": "1.14.29",
|
||||||
"resolved": "https://registry.npmjs.org/@opencode-ai/plugin/-/plugin-1.3.14.tgz",
|
"resolved": "https://registry.npmjs.org/@opencode-ai/plugin/-/plugin-1.14.29.tgz",
|
||||||
"integrity": "sha512-dIEko9B4KytL1pABotkSw2Rm3/BKXb+5Z4g4c/aXjVd2cu86UIsFz8orgMB4zsQOa0bECzESaQzHOKTn3gMEMw==",
|
"integrity": "sha512-GwmBg7dajawma/6tzpoK/JMbcRcUTg27XHlnxZOFWG85WDz4M67hxFYnvE+BnJj9k7tTLXTfSR+pgfcdqbUDAg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/sdk": "1.3.14",
|
"@opencode-ai/sdk": "1.14.29",
|
||||||
|
"effect": "4.0.0-beta.57",
|
||||||
"zod": "4.1.8"
|
"zod": "4.1.8"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@opentui/core": ">=0.1.96",
|
"@opentui/core": ">=0.1.105",
|
||||||
"@opentui/solid": ">=0.1.96"
|
"@opentui/solid": ">=0.1.105"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"@opentui/core": {
|
"@opentui/core": {
|
||||||
@@ -31,14 +110,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@opencode-ai/sdk": {
|
"node_modules/@opencode-ai/sdk": {
|
||||||
"version": "1.3.14",
|
"version": "1.14.29",
|
||||||
"resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.3.14.tgz",
|
"resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.14.29.tgz",
|
||||||
"integrity": "sha512-8sNOFYB86d3b2KiIiL6wtio4V9U0mKEiJAlehzuaigZWiZMsI11Gq1Fdq+tIf9RWNQNsZSMYFuofLabPWQs7qA==",
|
"integrity": "sha512-y6wNTlHhgfwLdp01EwdnMFVxUS1FLgz7MZh7H3+jROG2v02GqGDy/gPH3ME0kI+sqQ4qSlk/9AJ+YbKAruPaZw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cross-spawn": "7.0.6"
|
"cross-spawn": "7.0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@standard-schema/spec": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
@@ -53,12 +138,135 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/detect-libc": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/effect": {
|
||||||
|
"version": "4.0.0-beta.57",
|
||||||
|
"resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-beta.57.tgz",
|
||||||
|
"integrity": "sha512-rg32VgXnLKaPRs9tbRDaZ5jxmzNY7ojXt85gSHGUTwdlbWH5Ik+OCUY2q14TXliygPGoHwCAvNWS4bQJOqf00g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@standard-schema/spec": "^1.1.0",
|
||||||
|
"fast-check": "^4.6.0",
|
||||||
|
"find-my-way-ts": "^0.1.6",
|
||||||
|
"ini": "^6.0.0",
|
||||||
|
"kubernetes-types": "^1.30.0",
|
||||||
|
"msgpackr": "^1.11.9",
|
||||||
|
"multipasta": "^0.2.7",
|
||||||
|
"toml": "^4.1.1",
|
||||||
|
"uuid": "^13.0.0",
|
||||||
|
"yaml": "^2.8.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fast-check": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-NsZRtqvSSoCP0HbNjUD+r1JH8zqZalyp6gLY9e7OYs7NK9b6AHOs2baBFeBG7bVNsuoukh89x2Yg3rPsul8ziQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/dubzzz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/fast-check"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"pure-rand": "^8.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.17.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/find-my-way-ts": {
|
||||||
|
"version": "0.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/find-my-way-ts/-/find-my-way-ts-0.1.6.tgz",
|
||||||
|
"integrity": "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/ini": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.17.0 || >=22.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/isexe": {
|
"node_modules/isexe": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/kubernetes-types": {
|
||||||
|
"version": "1.30.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/kubernetes-types/-/kubernetes-types-1.30.0.tgz",
|
||||||
|
"integrity": "sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
|
"node_modules/msgpackr": {
|
||||||
|
"version": "1.11.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.10.tgz",
|
||||||
|
"integrity": "sha512-iCZNq+HszvF+fC3anCm4nBmWEnbeIAfpDs6IStAEKhQ2YSgkjzVG2FF9XJqwwQh5bH3N9OUTUt4QwVN6MLMLtA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optionalDependencies": {
|
||||||
|
"msgpackr-extract": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/msgpackr-extract": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"node-gyp-build-optional-packages": "5.2.2"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"download-msgpackr-prebuilds": "bin/download-prebuilds.js"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3",
|
||||||
|
"@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3",
|
||||||
|
"@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3",
|
||||||
|
"@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3",
|
||||||
|
"@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3",
|
||||||
|
"@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/multipasta": {
|
||||||
|
"version": "0.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/multipasta/-/multipasta-0.2.7.tgz",
|
||||||
|
"integrity": "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/node-gyp-build-optional-packages": {
|
||||||
|
"version": "5.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz",
|
||||||
|
"integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"detect-libc": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"node-gyp-build-optional-packages": "bin.js",
|
||||||
|
"node-gyp-build-optional-packages-optional": "optional.js",
|
||||||
|
"node-gyp-build-optional-packages-test": "build-test.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-key": {
|
"node_modules/path-key": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
@@ -68,6 +276,22 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pure-rand": {
|
||||||
|
"version": "8.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.0.tgz",
|
||||||
|
"integrity": "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/dubzzz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/fast-check"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@@ -89,6 +313,28 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/toml": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/toml/-/toml-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "13.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
|
||||||
|
"integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist-node/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
@@ -104,6 +350,21 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/yaml": {
|
||||||
|
"version": "2.8.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz",
|
||||||
|
"integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"yaml": "bin.mjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/eemeli"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/zod": {
|
"node_modules/zod": {
|
||||||
"version": "4.1.8",
|
"version": "4.1.8",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
202
.opencode/plans/kq4-room-navigator.md
Normal file
202
.opencode/plans/kq4-room-navigator.md
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
---
|
||||||
|
model: "auto"
|
||||||
|
kill: ["alpha-mask-creator"]
|
||||||
|
date_introduced: 2026-04-28
|
||||||
|
---
|
||||||
|
|
||||||
|
# Plan: kq4-room-navigator Skill (AI Agent Room Pathfinding via Godot MCP)
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The game has ~96 rooms connected by TransitionPiece nodes. Each room's `.tscn` file defines its exits: node name (destination room), target UID, appear_at_node, label, and polygon coordinates. Room scripts connect the `interacted` signal to handlers that call `default_script()` on the transition piece, triggering a 3-step animated sequence (walk to exit → fade/swap scenes → walk to entrance in new room).
|
||||||
|
|
||||||
|
The custom MCP server (`scripts/mcp_interaction_server.gd`) runs as an autoload at TCP port 9090 with ~80 commands including `eval` (arbitrary GDScript execution), `click`, `screenshot`, `get_scene_tree`, `get_property`, and `wait`. No Python client exists yet.
|
||||||
|
|
||||||
|
**Key constraint**: Full runtime discovery via `eval` is fragile — instantiating .tscn files for graph discovery triggers script execution (`_ready()`) which references autoload singletons (ActionState, GameScript), causing errors when rooms aren't fully set up. **Solution**: Use targeted `find_nodes_by_class` MCP command for the currently-loaded room, and file parsing for global graph construction (leveraging existing `scripts/check_transitions.py`).
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
Build a Python tool (`tools/kq4_room_navigator.py`) that:
|
||||||
|
1. Parses `.tscn` files to build complete room adjacency graph (reuse logic from `check_transitions.py`)
|
||||||
|
2. Runs BFS pathfinding between start and destination rooms
|
||||||
|
3. Connects to the MCP server on port 9090 for live navigation
|
||||||
|
4. Uses `eval` to compute click coordinates within TransitionPiece polygons in the running game
|
||||||
|
5. Executes step-by-step clicks with screenshot verification after each transition
|
||||||
|
|
||||||
|
The SKILL.md guides an AI agent through: starting Godot, invoking the tool, and optionally verifying steps manually with MCP commands.
|
||||||
|
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
### 1. Extend room graph parser (`scripts/build_room_graph.py`)
|
||||||
|
|
||||||
|
**Purpose**: Parse all `.tscn` files to produce a queryable room adjacency graph with BFS pathfinding. Extends/extracts logic from existing `scripts/check_transitions.py`.
|
||||||
|
|
||||||
|
**What it does**:
|
||||||
|
1. Scan `scenes/kq4_*/kq4_*.tscn` (exclude placeholder_template)
|
||||||
|
2. Parse each file to extract:
|
||||||
|
- Scene UID (from header `[gd_scene format=3 uid="uid://XXX"]`)
|
||||||
|
- Room name/directory stem (e.g., `kq4_004_ogres_cottage`)
|
||||||
|
- All TransitionPiece nodes → build adjacency list
|
||||||
|
3. Build bidirectional graph: `{room_name: [(exit_node_name, target_uid, appear_at_node, label, polygon), ...]}`
|
||||||
|
|
||||||
|
**Output**: Returns a structure that supports BFS queries between any two rooms.
|
||||||
|
|
||||||
|
**Interface** (callable from Python or CLI):
|
||||||
|
```python
|
||||||
|
def build_graph(scenes_dir: Path) -> dict[str, list[TransitionInfo]]:
|
||||||
|
"""Parse all room .tscn files and return adjacency graph."""
|
||||||
|
|
||||||
|
def find_path(graph: dict, start_room: str, end_room: str) -> list[NavigationStep]:
|
||||||
|
"""BFS from start to end. Returns ordered list of steps or None."""
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class NavigationStep:
|
||||||
|
from_room: str # Current room name (e.g., "kq4_004_ogres_cottage")
|
||||||
|
exit_node_name: str # TransitionPiece node name (e.g., "kq4_010_forest_path")
|
||||||
|
to_room: str # Destination room name
|
||||||
|
label: str # Human-readable label (e.g., "Forest Path")
|
||||||
|
polygon: list[tuple] # Polygon vertices for click coordinate computation
|
||||||
|
```
|
||||||
|
|
||||||
|
**File**: `scripts/build_room_graph.py`
|
||||||
|
|
||||||
|
### 3. Create the main navigator tool (`tools/kq4_room_navigator.py`)
|
||||||
|
|
||||||
|
**Purpose**: End-to-end CLI tool that connects to MCP, builds graph, finds path, and navigates.
|
||||||
|
|
||||||
|
**Workflow**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python tools/kq4_room_navigator.py --from kq4_004_ogres_cottage --to kq4_092_lolottes_throne_room
|
||||||
|
```
|
||||||
|
|
||||||
|
**Implementation flow**:
|
||||||
|
|
||||||
|
1. **Build graph** (offline): Calls `build_graph()` to parse all rooms
|
||||||
|
2. **BFS pathfinding**: Finds shortest path from start → destination
|
||||||
|
3. **No path found**: Reports unreachable, lists connected components
|
||||||
|
4. **Path found**: Prints the step-by-step plan with click coordinates
|
||||||
|
|
||||||
|
5. **Connect to MCP** (runtime): Opens TCP connection to port 9090
|
||||||
|
6. **For each navigation step**:
|
||||||
|
a. Verify starting room: `eval("return get_node('/root/Node2D').get_current_room_name()")` returns the current room's node name (e.g., `"kq4_003_fountain_pool"`). This convenience function on MainGame simplifies verification compared to traversing the scene tree.
|
||||||
|
b. `find_nodes_by_class(class_name="TransitionPiece")` — discover all transition pieces in current scene
|
||||||
|
c. Match the exit node name from our path → get runtime position + polygon
|
||||||
|
d. Compute click coordinate: centroid of the TransitionPiece's `polygon`, transformed to viewport coordinates
|
||||||
|
e. `click(x, y)` — trigger the transition
|
||||||
|
f. Wait for transition animation (2-3s via `wait` command or poll-loop)
|
||||||
|
g. **Verify arrival**: `eval("return get_node('/root/Node2D').get_current_room_name()")` to confirm we've entered the expected room. Compare against the `to_room` from our BFS path. Returns empty string if no scene loaded.
|
||||||
|
h. If verification fails, retry up to 2 times with adjusted coordinates
|
||||||
|
h. Optionally take a screenshot via `screenshot()` for visual confirmation
|
||||||
|
|
||||||
|
7. **Complete**: Print summary of navigation path taken
|
||||||
|
|
||||||
|
**GDScript eval code used at runtime**:
|
||||||
|
|
||||||
|
Find clickable position within TransitionPiece polygon:
|
||||||
|
```gdscript
|
||||||
|
# Returns {node_name, centroid_x, centroid_y} for matching transition piece
|
||||||
|
var bg = get_tree().root.get_node_or_null("Node2D/SceneViewport/background")
|
||||||
|
if not bg: return null
|
||||||
|
for child in bg.get_children():
|
||||||
|
if child.has_method("is_class") and child.is_class("TransitionPiece"):
|
||||||
|
var p = child.position + child.polygon.reduce(func(p, a): return p + a, Vector2(0,0)) / child.polygon.size()
|
||||||
|
return {"node": child.name, "x": p.x, "y": p.y, "polygon_size": child.polygon.size()}
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify current room:
|
||||||
|
```gdscript
|
||||||
|
var bg = get_tree().root.get_node_or_null("Node2D/SceneViewport/background")
|
||||||
|
return bg ? bg.name : null
|
||||||
|
```
|
||||||
|
|
||||||
|
**File**: `tools/kq4_room_navigator.py`
|
||||||
|
|
||||||
|
### 4. Write SKILL.md (`.opencode/skills/kq4-room-navigator/SKILL.md`)
|
||||||
|
|
||||||
|
The skill guide documents:
|
||||||
|
|
||||||
|
- **When to use**: Planning navigation between rooms, verifying room connectivity, debugging transitions
|
||||||
|
- **Pre-requisites**: Godot game running with MCP server active on port 9090
|
||||||
|
- **Quick start**: `python tools/kq4_room_navigator.py --from kq4_XXX --to kq4_YYY`
|
||||||
|
- **Room verification helper** (`MainGame.get_current_room_name()`):
|
||||||
|
|
||||||
|
The root node (`/root/Node2D`, script: `MainGame.gd`) provides a convenience function for testing:
|
||||||
|
|
||||||
|
```gdscript
|
||||||
|
# Via MCP eval — returns node name like "kq4_003_fountain_pool", or "" if no scene loaded
|
||||||
|
return get_node("/root/Node2D").get_current_room_name()
|
||||||
|
```
|
||||||
|
|
||||||
|
Use this after each transition click to verify you arrived at the expected room. Compare against the `to_room` field from your BFS path.
|
||||||
|
|
||||||
|
- **Manual MCP workflow** (for step-by-step agent control):
|
||||||
|
- Start Godot: `godot --path .` or run exported binary
|
||||||
|
- Check current room: `{"command": "eval", "params": {"code": "return get_node('/root/Node2D').get_current_room_name()"}}` → returns `"kq4_003_fountain_pool"` style string
|
||||||
|
- Verify connectivity: `{"command": "get_scene_tree"}` returns the current scene tree
|
||||||
|
- Discover exits in current room: `{"command": "find_nodes_by_class", "params": {"class_name": "TransitionPiece"}}`
|
||||||
|
- Click a transition: compute centroid from polygon data, then `{"command": "click", "params": {"x": px, "y": py}}`
|
||||||
|
- Verify current room: `{"command": "eval", "params": {"code": "return get_node('/root/Node2D').get_current_room_name()"}}` (returns node name like `"kq4_010_forest_path"`). Alternatively use screenshot for visual confirmation.
|
||||||
|
- **Coordinate computation math**: How to convert TransitionPiece polygon (local-space) to viewport click coordinates: `viewport_x = transition_node.position.x + polygon_centroid.x`, accounting for any node scale transforms
|
||||||
|
- **Troubleshooting**: Common failures (server busy, node not found mid-transition, wrong room), escape hatches
|
||||||
|
|
||||||
|
**File**: `.opencode/skills/kq4-room-navigator/SKILL.md`
|
||||||
|
|
||||||
|
## Task Dependency Graph
|
||||||
|
|
||||||
|
```
|
||||||
|
[1. build_room_graph.py] ────────┐
|
||||||
|
├── [2. kq4_room_navigator.py] ─── [3. SKILL.md]
|
||||||
|
|
||||||
|
### Using MainGame.get_current_room_name() for Room Verification
|
||||||
|
|
||||||
|
The `MainGame.gd` script (attached to `/root/Node2D`) provides a convenience function:
|
||||||
|
|
||||||
|
```gdscript
|
||||||
|
# Returns the node name of the current scene, e.g., "kq4_003_fountain_pool"
|
||||||
|
func get_current_room_name() -> String:
|
||||||
|
var scene = get_scene()
|
||||||
|
if scene:
|
||||||
|
return scene.name
|
||||||
|
return ""
|
||||||
|
```
|
||||||
|
|
||||||
|
**Via MCP eval for runtime verification**:
|
||||||
|
```bash
|
||||||
|
curl http://localhost:9090 -d '{"command": "eval", "params": {"code": "return get_node(\"/root/Node2D\").get_current_room_name()"}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the room node name string (e.g., `"kq4_003_fountain_pool"`), or empty string if no scene is loaded. This is more reliable than traversing the scene tree manually since it uses the same `$SceneViewport/background` reference that MainGame's own logic uses.
|
||||||
|
|
||||||
|
**When to use**:
|
||||||
|
- After clicking a transition, call to confirm arrival at expected room in `to_room`
|
||||||
|
- Before navigation starts, verify you're actually in the intended `from_room`
|
||||||
|
- Compare against BFS path nodes during automated step-by-step execution
|
||||||
|
```
|
||||||
|
|
||||||
|
Tasks run sequentially. Task 3 documents the completed system.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
- Run `python scripts/build_room_graph.py` → should produce a graph with all rooms and their exits
|
||||||
|
- Test BFS: path from kq4_001_beach to an adjacent room should be 1 step; path to a far room tests multi-hop correctly
|
||||||
|
- Connect to running Godot instance via `tools/kq4_room_navigator.py` → verify it can navigate at least one transition end-to-end (from current room to an adjacent room)
|
||||||
|
- Verify failure handling: requesting a path between disconnected rooms returns "no path found"
|
||||||
|
- Test `_busy` retry logic by sending rapid commands
|
||||||
|
|
||||||
|
## Risks & Mitigations
|
||||||
|
|
||||||
|
| Risk | Impact | Mitigation |
|
||||||
|
|------|--------|------------|
|
||||||
|
| Room not fully set up — `TransitionPiece._ready()` crashes on eval-instantiation | Can't discover transitions from unloaded rooms via MCP | File parsing for graph discovery is the primary approach; MCP runtime only queries currently-loaded scene |
|
||||||
|
| Transition animation timing varies | Click at wrong time → missed transition | Poll current room name via eval every 0.5s until it changes, with 10s timeout |
|
||||||
|
| Polygon coordinates are local to node — need transform to viewport | Click lands outside polygon | Account for node `position` AND `scale` when computing centroid; use `get_node_info` runtime to get actual global polygon positions |
|
||||||
|
| MCP server `_busy` state blocks commands | Navigation stalls | Retry with exponential backoff (0.1s, 0.2s, 0.4s, ...) and 3-second max wait |
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Path optimization beyond BFS shortest path
|
||||||
|
- Inventory/item-based transitions (e.g., needing a key to enter a room)
|
||||||
|
- Cutscene-triggered room changes (non-interaction transitions)
|
||||||
|
- Multiplayer considerations
|
||||||
|
- Auto-starting Godot from the tool (user starts game manually)
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
---
|
||||||
|
## Goal
|
||||||
|
- Implement inventory and backpack system in Godot 4.6 point-and-click adventure game per plan at `docs/plans/2026-04-26-001-feat-inventory-backpack-system-plan.md`
|
||||||
|
|
||||||
|
## Constraints & Preferences
|
||||||
|
- Interaction handlers are signals emitted by items, not embedded dictionary data
|
||||||
|
- No multi-step transition queues — FSM transitions interrupt in-flight animations immediately
|
||||||
|
- No sound required
|
||||||
|
- Item cursor as 5th `ActionState` slot (`ITEM`, value 4); right-click cycles WALK→LOOK→TOUCH→TALK→ITEM→WALK
|
||||||
|
- Use colored `ColorRect` boxes as placeholders for all item/backpack visuals
|
||||||
|
- Follow PRD §13 recommended Godot architecture approaches
|
||||||
|
- PRD is engine-agnostic but implementation targets Godot 4.6
|
||||||
|
|
||||||
|
## Progress
|
||||||
|
### Done
|
||||||
|
- Read and analyzed `inventory-prd.md` (791 lines)
|
||||||
|
- Researched existing codebase patterns
|
||||||
|
- Wrote complete plan to `docs/plans/2026-04-26-001-feat-inventory-backpack-system-plan.md` with 6 implementation units
|
||||||
|
- Applied 5 user edits to plan: signal-based interactions, no transition queues, no sound, ActionState ITEM slot, colored boxes
|
||||||
|
- Created directory structure: `inventory/inventory_backpack/`, `inventory/inventory_overlay/`
|
||||||
|
- Generated 12 UIDs for new files
|
||||||
|
- U1 complete: `inventory/ItemDefinition.gd` written (Resource with id, name, combination_category)
|
||||||
|
- U2 complete: `inventory/InventoryManager.gd` written (AutoLoad singleton with signals, queries, mutations, combination emission, selection)
|
||||||
|
- U3 complete: `inventory/inventory_backpack/InventoryBackpack.gd` + `.tscn` (FSM with IDLE/OPEN/SELECTED/ACQUIRE/REMOVE, Tween animations, guard checks)
|
||||||
|
- U4 complete: `inventory/inventory_overlay/InventoryOverlay.gd` + `.tscn` + `InventorySlot.gd` + `.tscn` (full-screen overlay, grid, drag-and-drop, hover, combination)
|
||||||
|
- U5 complete: Modified `ActionState.gd` (ITEM=4), `MainGame.gd` (5-action cycling), `Scene.gd` (overlay guard, ITEM input), `GameScript.gd` (GiveItem step)
|
||||||
|
- U6 complete: Modified `Scene.gd` (give_item/remove_item/strip_items helpers), `SetPiece_.gd` (ITEM action handling)
|
||||||
|
- InventoryManager registered as AutoLoad in `project.godot`
|
||||||
|
- All commits pushed to remote
|
||||||
|
|
||||||
|
### In Progress
|
||||||
|
- (none)
|
||||||
|
|
||||||
|
### Blocked
|
||||||
|
- (none)
|
||||||
|
|
||||||
|
## Key Decisions
|
||||||
|
- **Signal-based interactions**: Items emit signals; `InventoryManager.attempt_combine` emits `combination_attempted`; scene scripts handle results
|
||||||
|
- **No transition queues**: FSM transitions kill in-flight tweens and start fresh; `is_busy` flag prevents concurrency but does not queue
|
||||||
|
- **ActionState ITEM slot**: `ITEM = 4` added to enum; right-click cycles all 5 states; selected item stored in `InventoryManager.selected_item`
|
||||||
|
- **Colored boxes**: `ColorRect` placeholders replace all `Sprite2D` references
|
||||||
|
- **Hand-rolled FSM (PRD Option A)** over AnimationTree: conditional branching maps better to code
|
||||||
|
- **AutoLoad singleton** for InventoryManager following ActionState pattern
|
||||||
|
- **Raw `_gui_input()`** for overlay drag-and-drop instead of Godot's built-in system
|
||||||
|
- **Combined input priority defense**: `MOUSE_FILTER_STOP` background + `_unhandled_input()` gate + explicit `overlay_active` guard flag
|
||||||
|
- **ItemDefinition as Resource** for serializable `.tres` item data
|
||||||
|
- **GridContainer** for static item grid layout
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
- Test all units in Godot editor
|
||||||
|
- Register sample item definitions (`.tres` files)
|
||||||
|
- Wire up signal connections in `Game.tscn` (backpack ↔ overlay ↔ manager)
|
||||||
|
- Create example room script demonstrating `give_item()` usage
|
||||||
|
- Replace colored box placeholders with actual item sprites
|
||||||
|
|
||||||
|
## Critical Context
|
||||||
|
- Godot 4.6 project, 1920x1080 viewport
|
||||||
|
- Branch: `sugary-panda` (worktree), default branch: `master`
|
||||||
|
- Existing autoloads: `ActionState`, `CameraTransition`, `InventoryManager` (new)
|
||||||
|
- Root scene `Game.tscn` uses `SubViewport` for game world, `CanvasLayer` for overlays
|
||||||
|
- `ActionState.gd` enum: `WALK=0, LOOK=1, TOUCH=2, TALK=3, ITEM=4`
|
||||||
|
- `MainGame.gd` has `cursors` array with 4 cursor textures — 5th slot needed for ITEM (currently skips if no item selected)
|
||||||
|
- All code committed and pushed to `origin/sugary-panda`
|
||||||
|
|
||||||
|
## Relevant Files
|
||||||
|
- `inventory-prd.md`: Origin requirements document (791 lines, 14 acceptance criteria)
|
||||||
|
- `docs/plans/2026-04-26-001-feat-inventory-backpack-system-plan.md`: Implementation plan (6 units, edited with 5 user changes)
|
||||||
|
- `inventory/ItemDefinition.gd`: Custom Resource class (DONE)
|
||||||
|
- `inventory/ItemDefinition.gd.uid`: UID file for ItemDefinition (DONE)
|
||||||
|
- `inventory/InventoryManager.gd`: AutoLoad singleton with signals, queries, mutations (DONE)
|
||||||
|
- `inventory/InventoryManager.gd.uid`: UID file for InventoryManager (DONE)
|
||||||
|
- `inventory/inventory_backpack/InventoryBackpack.gd`: FSM script (DONE)
|
||||||
|
- `inventory/inventory_backpack/InventoryBackpack.gd.uid`: UID file (DONE)
|
||||||
|
- `inventory/inventory_backpack/InventoryBackpack.tscn`: HUD backpack scene (DONE)
|
||||||
|
- `inventory/inventory_backpack/InventoryBackpack.tscn.uid`: UID file (DONE)
|
||||||
|
- `inventory/inventory_overlay/InventoryOverlay.gd`: Overlay interaction script (DONE)
|
||||||
|
- `inventory/inventory_overlay/InventoryOverlay.gd.uid`: UID file (DONE)
|
||||||
|
- `inventory/inventory_overlay/InventoryOverlay.tscn`: Full-screen overlay scene (DONE)
|
||||||
|
- `inventory/inventory_overlay/InventoryOverlay.tscn.uid`: UID file (DONE)
|
||||||
|
- `inventory/inventory_overlay/InventorySlot.gd`: Slot behavior script (DONE)
|
||||||
|
- `inventory/inventory_overlay/InventorySlot.gd.uid`: UID file (DONE)
|
||||||
|
- `inventory/inventory_overlay/InventorySlot.tscn`: Single item slot scene (DONE)
|
||||||
|
- `inventory/inventory_overlay/InventorySlot.tscn.uid`: UID file (DONE)
|
||||||
|
- `MainGame.gd`: Modified for 5-action cursor cycling with ITEM
|
||||||
|
- `Scene.gd`: Modified for overlay guard, ITEM action, helper methods
|
||||||
|
- `ActionState.gd`: Modified to add ITEM action
|
||||||
|
- `GameScript.gd`: Modified to add GiveItem/GiveItemDeferred steps
|
||||||
|
- `SetPiece_.gd`: Modified to handle ITEM action
|
||||||
|
- `project.godot`: InventoryManager AutoLoad registered
|
||||||
127
.opencode/skills/gitea-tea/SKILL.md
Normal file
127
.opencode/skills/gitea-tea/SKILL.md
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
---
|
||||||
|
name: gitea-tea
|
||||||
|
description: Use tea CLI to create, manage, and checkout Gitea pull requests. Use this when opening a PR, managing PRs, or checking out PRs on the gitea remote (gitea.story-basking.ts.net).
|
||||||
|
---
|
||||||
|
|
||||||
|
# Gitea Tea CLI Skill
|
||||||
|
|
||||||
|
This skill covers using `tea` (Gitea's official CLI) for pull request workflows in this project.
|
||||||
|
|
||||||
|
## When to Use This Skill
|
||||||
|
|
||||||
|
Use this skill when you need to:
|
||||||
|
- Create a PR from a working branch to master on the gitea remote
|
||||||
|
- Open, list, or view PRs
|
||||||
|
- Checkout a PR locally for review or iteration
|
||||||
|
- Manage PR state (close, reopen, merge)
|
||||||
|
|
||||||
|
## Project Setup
|
||||||
|
|
||||||
|
The gitea remote is `gitea.story-basking.ts.net` with repo slug `notid/integreat`. The default push remote is **gitea**, NOT origin and NOT deploy.
|
||||||
|
|
||||||
|
In this project's environment:
|
||||||
|
- Gitea login is pre-configured for `gitea.story-basking.ts.net`
|
||||||
|
- Repo slug: `notid/integreat`
|
||||||
|
- Target branch for PRs: `master`
|
||||||
|
- The git remote named `gitea` points to this instance
|
||||||
|
|
||||||
|
## Creating a PR
|
||||||
|
|
||||||
|
Use `tea pulls create` to open a PR from the current branch to master. Always specify `-r notid/integreat -b master`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea pulls create -r notid/integreat -b master --title "Title" --description "Body"
|
||||||
|
```
|
||||||
|
|
||||||
|
Common flags:
|
||||||
|
- `-t, --title` - PR title
|
||||||
|
- `-d, --description` - PR body/description (use heredoc or file for long descriptions)
|
||||||
|
- `-a, --assignees` - Comma-separated usernames to assign
|
||||||
|
- `-L, --labels` - Comma-separated labels to apply
|
||||||
|
- `-m, --milestone` - Milestone to assign
|
||||||
|
|
||||||
|
**Writing a multiline description:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea pulls create -r notid/integreat -b master \
|
||||||
|
-t "feat: add feature" \
|
||||||
|
-d "$(cat <<'EOF'
|
||||||
|
## Summary
|
||||||
|
- Bullet point one
|
||||||
|
- Bullet point two
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
```
|
||||||
|
|
||||||
|
Or write the body to a temp file first and reference it.
|
||||||
|
|
||||||
|
## Listing PRs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea pulls list -r notid/integreat # List open PRs
|
||||||
|
tea pulls list -r notid/integreat --state all # All PRs
|
||||||
|
tea pulls list -r notid/integreat --limit 10 -o simple # Limit output, simple format
|
||||||
|
```
|
||||||
|
|
||||||
|
## Opening a PR in Browser
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea open pr <number> -r notid/integreat
|
||||||
|
tea open pr create -r notid/integreat # Open web UI to create a PR
|
||||||
|
```
|
||||||
|
|
||||||
|
## Checking Out a PR Locally
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea pulls checkout <number> -r notid/integreat
|
||||||
|
```
|
||||||
|
|
||||||
|
This fetches and checks out the PR branch locally.
|
||||||
|
|
||||||
|
## Managing PR State
|
||||||
|
|
||||||
|
**Close a PR:**
|
||||||
|
```bash
|
||||||
|
tea pulls close <number> -r notid/integreat --confirm
|
||||||
|
```
|
||||||
|
|
||||||
|
**Reopen a closed PR:**
|
||||||
|
```bash
|
||||||
|
tea pulls reopen <number> -r notid/integreat --confirm
|
||||||
|
```
|
||||||
|
|
||||||
|
**Merge a PR:**
|
||||||
|
```bash
|
||||||
|
tea pulls merge <number> -r notid/integreat --confirm
|
||||||
|
```
|
||||||
|
|
||||||
|
**Edit a PR (title, description, etc.):**
|
||||||
|
```bash
|
||||||
|
tea pulls edit <number> -r notid/integreat --title "New title" --description "New body"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Full PR Creation Workflow
|
||||||
|
|
||||||
|
1. Ensure the branch is pushed to gitea:
|
||||||
|
```bash
|
||||||
|
git push gitea <branch-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Create the PR with tea:
|
||||||
|
```bash
|
||||||
|
tea pulls create -r notid/integreat -b master \
|
||||||
|
--title "feat: description of change" \
|
||||||
|
--description "Detailed PR body here"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Open the PR in browser to verify:
|
||||||
|
```bash
|
||||||
|
tea open pr <number> -r notid/integreat
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- Always use `-r notid/integreat` to specify the repo explicitly
|
||||||
|
- Use `-b master` to set the target branch (default may differ)
|
||||||
|
- The `--confirm` flag is required for destructive actions (close, merge)
|
||||||
|
- Use `-o simple`, `-o json`, `-o table`, etc. to control output format
|
||||||
194
.opencode/skills/kq4-room-navigator/SKILL.md
Normal file
194
.opencode/skills/kq4-room-navigator/SKILL.md
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
---
|
||||||
|
name: kq4-room-navigator
|
||||||
|
description: Navigate between KQ4 rooms using the Godot MCP server. BFS pathfinds through room transition graph, then the agent navigates McpInteractionServer (port 9090). Use when planning navigation between any two rooms or simulating player movement through the game world at runtime. Trigger phrases: "navigate from", "go to room", "path from X to Y", "walk to", "how do I get to room", "room navigation".
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
# KQ4 Room Navigator
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This skill finds shortest paths between rooms and can execute them through the running game using Godot's MCP server. It combines offline `.tscn` file parsing for graph construction with runtime interaction via McpInteractionServer (TCP port 9090).
|
||||||
|
|
||||||
|
The room transition system uses TransitionPiece nodes: each has an `exit_node_name` (destination), a polygon, and connects rooms typically bidirectionally. Clicking a TransitionPiece triggers a 3-step animation (walk → fade/swap scenes → walk to entrance in new room).
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- Planning multi-room navigation paths
|
||||||
|
- Verifying room connectivity
|
||||||
|
- Debugging why a path can't be traversed
|
||||||
|
- Automating room transitions during testing
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
```
|
||||||
|
.scenes/*.tscn files → adjacency graph (96 rooms, 233 exits) → BFS pathfinding → use MCP for execution
|
||||||
|
```
|
||||||
|
|
||||||
|
Room identification at runtime:
|
||||||
|
|
||||||
|
- Game node tree: `/root/Node2D/SceneViewport/background` (always named "background")
|
||||||
|
- Room identity comes from `background.get_script().resource_path` (e.g., `res://scenes/kq4_010_forest_path/kq4_010_forest_path.gd`)
|
||||||
|
- TransitionPiece children have `.target` UIDs and `.label` strings for cross-referencing
|
||||||
|
|
||||||
|
### Getting the current room name at runtime
|
||||||
|
|
||||||
|
The canonical way is via `MainGame.get_current_room_name()`:
|
||||||
|
|
||||||
|
Use `godot_game_call_method` to call it directly on the node path:
|
||||||
|
```json
|
||||||
|
Call method get_current_room_name on /root/Node2D
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns a string like `"kq4_010_forest_path"`. The implementation extracts the filename from the scene script's resource path (`script_path.trim_suffix(".gd").get_file()`), NOT the node name (which is always `"background"`).
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Step 1 — Make a plan:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python tools/kq4_room_navigator.py --from kq4_003_fountain_pool --to kq4_011_enchanted_grove
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
Path: kq4_003_fountain_pool → kq4_011_enchanted_grove (3 steps)
|
||||||
|
1. Click 'kq4_004_ogres_cottage' in kq4_003_fountain_pool → kq4_004_ogres_cottage [Ogre's Cottage] (click at: 1874, 714)
|
||||||
|
2. Click 'kq4_010_forest_path' in kq4_004_ogres_cottage → kq4_010_forest_path [Forest Path] (click at: 1042, 1078)
|
||||||
|
3. Click 'kq4_011_enchanted_grove' in kq4_010_forest_path → kq4_011_enchanted_grove [Enchanted Grove] (click at: 1898, 610)
|
||||||
|
```
|
||||||
|
|
||||||
|
The click coordinates are not used — the `exit_node_name` is what matters.
|
||||||
|
|
||||||
|
### Step 2 — Launch and navigate
|
||||||
|
|
||||||
|
1. Use the Godot MCP to start the game (`godot_run_project`)
|
||||||
|
2. Poll room name to verify starting room:
|
||||||
|
```
|
||||||
|
get_tree().root.get_node('Node2D').get_current_room_name()
|
||||||
|
```
|
||||||
|
3. For each step, call **`mock_interact(0)`** on the TransitionPiece node (see exact method name below)
|
||||||
|
4. Wait and poll until `get_current_room_name()` returns the expected destination
|
||||||
|
5. Repeat for next step
|
||||||
|
|
||||||
|
## Detailed Navigation Protocol
|
||||||
|
|
||||||
|
### Identify current room
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"command": "eval", "params": {"code": "get_tree().root.get_node('Node2D').get_current_room_name()"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns `"kq4_0xx_room_name"`, confirming both MCP connectivity and which room you're in.
|
||||||
|
|
||||||
|
### Discover available exits from current room
|
||||||
|
|
||||||
|
Use the `set-piece` group to find all interactive polygons (TransitionPieces are automatically added):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"command": "get_nodes_in_group", "params": {"group": "set-piece"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Filter results for node names starting with `kq4_0` — these are transition exits.
|
||||||
|
|
||||||
|
### Trigger a room transition
|
||||||
|
|
||||||
|
**Critical: The method name is `mock_interact`, NOT `mock_interaction`.**
|
||||||
|
|
||||||
|
Use `godot_game_call_method` to call it directly on the node path:
|
||||||
|
|
||||||
|
```
|
||||||
|
Call method mock_interact(0) on /root/Node2D/SceneViewport/background/<exit_node_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
Argument `0` = ActionState.Action.WALK (1=LOOK, 2=TOUCH, 3=TALK).
|
||||||
|
|
||||||
|
### Waiting — MCP busy protocol
|
||||||
|
|
||||||
|
**IMPORTANT**: Walk animations block the McpInteractionServer for ~30 seconds. During this time:
|
||||||
|
- `eval`, `wait`, `call_method` all fail with "timed out after 30s"
|
||||||
|
- The server has a built-in `_busy` flag auto-reset after ~30s ("_busy flag stuck for 30.Xs, force-resetting")
|
||||||
|
|
||||||
|
**Robust polling pattern**:
|
||||||
|
1. Call `mock_interact(0)` on the target node (returns immediately, animation starts)
|
||||||
|
2. Try `wait(frames=30)` then poll room name
|
||||||
|
3. If both timeout (~30s elapsed), retry the room name poll once more
|
||||||
|
4. The server will auto-reset and the next poll will succeed
|
||||||
|
|
||||||
|
Expected timing per transition: **~45-75 seconds total** (walk ~15s, MCP block ~30s, fade-in ~5s, confirm ~2s)
|
||||||
|
|
||||||
|
### Finding transitions by script handler
|
||||||
|
|
||||||
|
In room `.gd` files, handlers like `_on_ogres_cottage_interacted()` reference the TransitionPiece node (`$kq4_004_ogres_cottage.default_script(self)`). The handler's parameter name matches the node name you need to call `mock_interact(0)` on.
|
||||||
|
|
||||||
|
## Room Graph Structure
|
||||||
|
|
||||||
|
The graph currently has:
|
||||||
|
|
||||||
|
- **96 rooms** across 23 connected components
|
||||||
|
- Largest component: 36 rooms (starting from room 3 Fountain Pool)
|
||||||
|
- Second largest: 17 rooms (room 1 Beach area)
|
||||||
|
- Two additional 36-room components that are disconnected due to UID mismatches
|
||||||
|
|
||||||
|
Use `python scripts/build_room_graph.py --from A --to B` to find a path. If "no path" is returned but rooms feel like they should connect, the cause is likely a stale UID (see Common Issues).
|
||||||
|
|
||||||
|
### UID mismatch example
|
||||||
|
|
||||||
|
Room `kq4_018_cemetery` has UID `uid://b3fjmiaribbrl`, but nearby rooms point to it with stale UIDs (`uid://35amqvpjgpf2x`). Runtime navigation works fine (Transitions use file paths), but the graph can't find the connection.
|
||||||
|
|
||||||
|
## Common Issues
|
||||||
|
|
||||||
|
| Problem | Diagnosis | Fix |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `mock_interaction` method not found | Wrong method name | Use **`mock_interact(0)`** — no trailing "tion" |
|
||||||
|
| MCP commands time out during transition | Walk animation blocks server (~30s) | Wait and retry; server auto-resets after ~30s |
|
||||||
|
| "No path" between adjacent rooms at graph level | Target UID in source `.tscn` doesn't match destination room's `.uid` file | Runtime still works. Fix the target uid in the source tscn or update the destination room's .uid |
|
||||||
|
| `get_current_room_name()` returns `"background"` | Old implementation used `scene.name` | Updated to use `script_path.trim_suffix(".gd").get_file()` |
|
||||||
|
|
||||||
|
## Verified Navigation Example
|
||||||
|
|
||||||
|
Successfully tested navigating from kq4_003_fountain_pool to kq4_018_cemetery via 5 transitions:
|
||||||
|
|
||||||
|
```
|
||||||
|
kq4_003_fountain_pool → mock_interact(kq4_004_ogres_cottage) → kq4_004_ogres_cottage ✓
|
||||||
|
kq4_004_ogres_cottage → mock_interact(kq4_010_forest_path) → kq4_010_forest_path ✓
|
||||||
|
kq4_010_forest_path → mock_interact(kq4_011_enchanted_grove) → kq4_011_enchanted_grove ✓
|
||||||
|
kq4_011_enchanted_grove → mock_interact(kq4_017_spooky_house_exterior) → kq4_017_spooky_house_exterior ✓
|
||||||
|
kq4_017_spooky_house_exterior → mock_interact(kq4_018_cemetery) → kq4_018_cemetery ✓
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### build_room_graph.py module
|
||||||
|
|
||||||
|
```python
|
||||||
|
from pathlib import Path
|
||||||
|
from scripts.build_room_graph import build_graph, find_path, NavigationStep
|
||||||
|
|
||||||
|
graph = build_graph(Path('scenes')) # RoomInfo dict keyed by room name
|
||||||
|
steps = find_path(graph, "kq4_003_fountain_pool", "kq4_018_cemetery") # List[NavigationStep] or None
|
||||||
|
step.from_room # Source room name
|
||||||
|
step.exit_node_name # TransitionPiece node to call mock_interact(0) on
|
||||||
|
step.to_room # Destination room name
|
||||||
|
step.label # Human-readable label (e.g., "Ogre's Cottage")
|
||||||
|
```
|
||||||
|
|
||||||
|
### kq4_room_navigator.py CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python tools/kq4_room_navigator.py --from ROOM --to ROOM
|
||||||
|
# For graph summary:
|
||||||
|
python tools/kq4_room_navigator.py summary
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Files
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
| --- | --- |
|
||||||
|
| `MainGame.gd` | Root game node; `get_current_room_name()` returns room from script path |
|
||||||
|
| `tools/kq4_room_navigator.py` | CLI combining graph + BFS + MCP navigation |
|
||||||
|
| `scripts/build_room_graph.py` | Room adjacency graph builder + BFS pathfinding |
|
||||||
|
| `TransitionPiece.gd` | Exit nodes; `mock_interact(action)` triggers default_script() |
|
||||||
|
| `SetPiece_.gd` | Base interactive polygon class (class_name SetPiece) |
|
||||||
|
| `.opencode/skills/kq4-room-creator/SKILL.md` | Related: creating new rooms with transitions |
|
||||||
7
.superset/config.json
Normal file
7
.superset/config.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"setup": [
|
||||||
|
"git submodule update\ncd godot-mcp\nnpm install\nnpm run build\ncd .."
|
||||||
|
],
|
||||||
|
"teardown": [],
|
||||||
|
"run": []
|
||||||
|
}
|
||||||
108
AGENTS.md
108
AGENTS.md
@@ -299,116 +299,10 @@ func _on_exit_interacted() -> void:
|
|||||||
|
|
||||||
Do all work in a branch. Squash the branch before merging into master.
|
Do all work in a branch. Squash the branch before merging into master.
|
||||||
|
|
||||||
|
|
||||||
<!-- BEGIN BEADS INTEGRATION -->
|
|
||||||
## Issue Tracking with bd (beads)
|
|
||||||
|
|
||||||
**IMPORTANT**: This project uses **bd (beads)** for ALL issue tracking. Do NOT use markdown TODOs, task lists, or other tracking methods.
|
|
||||||
|
|
||||||
### Why bd?
|
|
||||||
|
|
||||||
- Dependency-aware: Track blockers and relationships between issues
|
|
||||||
- Git-friendly: Dolt-powered version control with native sync
|
|
||||||
- Agent-optimized: JSON output, ready work detection, discovered-from links
|
|
||||||
- Prevents duplicate tracking systems and confusion
|
|
||||||
|
|
||||||
### Quick Start
|
|
||||||
|
|
||||||
**Check for ready work:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bd ready --json
|
|
||||||
```
|
|
||||||
|
|
||||||
**Create new issues:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bd create "Issue title" --description="Detailed context" -t bug|feature|task -p 0-4 --json
|
|
||||||
bd create "Issue title" --description="What this issue is about" -p 1 --deps discovered-from:bd-123 --json
|
|
||||||
```
|
|
||||||
|
|
||||||
**Claim and update:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bd update <id> --claim --json
|
|
||||||
bd update bd-42 --priority 1 --json
|
|
||||||
```
|
|
||||||
|
|
||||||
**Complete work:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bd close bd-42 --reason "Completed" --json
|
|
||||||
```
|
|
||||||
|
|
||||||
### Issue Types
|
|
||||||
|
|
||||||
- `bug` - Something broken
|
|
||||||
- `feature` - New functionality
|
|
||||||
- `task` - Work item (tests, docs, refactoring)
|
|
||||||
- `epic` - Large feature with subtasks
|
|
||||||
- `chore` - Maintenance (dependencies, tooling)
|
|
||||||
|
|
||||||
### Priorities
|
|
||||||
|
|
||||||
- `0` - Critical (security, data loss, broken builds)
|
|
||||||
- `1` - High (major features, important bugs)
|
|
||||||
- `2` - Medium (default, nice-to-have)
|
|
||||||
- `3` - Low (polish, optimization)
|
|
||||||
- `4` - Backlog (future ideas)
|
|
||||||
|
|
||||||
### Workflow for AI Agents
|
|
||||||
|
|
||||||
1. **Check ready work**: `bd ready` shows unblocked issues
|
|
||||||
2. **Claim your task atomically**: `bd update <id> --claim`
|
|
||||||
3. **Work on it**: Implement, test, document
|
|
||||||
4. **Discover new work?** Create linked issue:
|
|
||||||
- `bd create "Found bug" --description="Details about what was found" -p 1 --deps discovered-from:<parent-id>`
|
|
||||||
5. **Complete**: `bd close <id> --reason "Done"`
|
|
||||||
|
|
||||||
### Auto-Sync
|
|
||||||
|
|
||||||
bd automatically syncs via Dolt:
|
|
||||||
|
|
||||||
- Each write auto-commits to Dolt history
|
|
||||||
- Use `bd dolt push`/`bd dolt pull` for remote sync
|
|
||||||
- No manual export/import needed!
|
|
||||||
|
|
||||||
### Important Rules
|
|
||||||
|
|
||||||
- ✅ Use bd for ALL task tracking
|
|
||||||
- ✅ Always use `--json` flag for programmatic use
|
|
||||||
- ✅ Link discovered work with `discovered-from` dependencies
|
|
||||||
- ✅ Check `bd ready` before asking "what should I work on?"
|
|
||||||
- ❌ Do NOT create markdown TODO lists
|
|
||||||
- ❌ Do NOT use external issue trackers
|
|
||||||
- ❌ Do NOT duplicate tracking systems
|
|
||||||
|
|
||||||
For more details, see README.md and docs/QUICKSTART.md.
|
|
||||||
|
|
||||||
## Landing the Plane (Session Completion)
|
|
||||||
|
|
||||||
**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.
|
|
||||||
|
|
||||||
**MANDATORY WORKFLOW:**
|
|
||||||
|
|
||||||
1. **File issues for remaining work** - Create issues for anything that needs follow-up
|
|
||||||
2. **Run quality gates** (if code changed) - Tests, linters, builds
|
|
||||||
3. **Update issue status** - Close finished work, update in-progress items
|
|
||||||
4. **PUSH TO REMOTE** - This is MANDATORY:
|
|
||||||
```bash
|
|
||||||
git pull --rebase
|
|
||||||
bd sync
|
|
||||||
git push
|
|
||||||
git status # MUST show "up to date with origin"
|
|
||||||
```
|
|
||||||
5. **Clean up** - Clear stashes, prune remote branches
|
|
||||||
6. **Verify** - All changes committed AND pushed
|
|
||||||
7. **Hand off** - Provide context for next session
|
|
||||||
|
|
||||||
**CRITICAL RULES:**
|
**CRITICAL RULES:**
|
||||||
- Work is NOT complete until `git push` succeeds
|
- Work is NOT complete until `git push` succeeds
|
||||||
- NEVER stop before pushing - that leaves work stranded locally
|
- NEVER stop before pushing - that leaves work stranded locally
|
||||||
- NEVER say "ready to push when you are" - YOU must push
|
- NEVER say "ready to push when you are" - YOU must push
|
||||||
- If push fails, resolve and retry until it succeeds
|
- If push fails, resolve and retry until it succeeds
|
||||||
|
|
||||||
<!-- END BEADS INTEGRATION -->
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
enum Action { WALK = 0, LOOK = 1, TOUCH = 2, TALK = 3 }
|
enum Action { WALK = 0, LOOK = 1, TOUCH = 2, TALK = 3, ITEM = 4 }
|
||||||
|
|
||||||
var current_action: int = Action.WALK:
|
var current_action: int = Action.WALK:
|
||||||
set(value):
|
set(value):
|
||||||
@@ -22,6 +22,7 @@ func get_action_name() -> String:
|
|||||||
Action.LOOK: return "look"
|
Action.LOOK: return "look"
|
||||||
Action.TOUCH: return "touch"
|
Action.TOUCH: return "touch"
|
||||||
Action.TALK: return "talk"
|
Action.TALK: return "talk"
|
||||||
|
Action.ITEM: return "item"
|
||||||
return "walk"
|
return "walk"
|
||||||
|
|
||||||
func get_action_enum() -> int:
|
func get_action_enum() -> int:
|
||||||
@@ -39,10 +40,15 @@ func _process(_delta: float) -> void:
|
|||||||
if not current_scene:
|
if not current_scene:
|
||||||
return
|
return
|
||||||
|
|
||||||
var global_mouse_pos = get_viewport().get_mouse_position()
|
# Use the scene's viewport (SubViewport), not the root viewport,
|
||||||
var camera = get_viewport().get_camera_2d()
|
# so we get the correct Camera2D and properly account for zoom/position.
|
||||||
|
var scene_viewport = current_scene.get_viewport()
|
||||||
|
var camera = scene_viewport.get_camera_2d()
|
||||||
|
var global_mouse_pos: Vector2
|
||||||
if camera:
|
if camera:
|
||||||
global_mouse_pos = camera.get_global_mouse_position()
|
global_mouse_pos = camera.get_global_mouse_position()
|
||||||
|
else:
|
||||||
|
global_mouse_pos = scene_viewport.get_mouse_position()
|
||||||
|
|
||||||
# Find all SetPieces in current scene
|
# Find all SetPieces in current scene
|
||||||
var new_hovered: Array[SetPiece] = []
|
var new_hovered: Array[SetPiece] = []
|
||||||
@@ -53,7 +59,7 @@ func _process(_delta: float) -> void:
|
|||||||
new_hovered.append(piece)
|
new_hovered.append(piece)
|
||||||
|
|
||||||
# Sort by priority (highest first)
|
# Sort by priority (highest first)
|
||||||
new_hovered.sort_custom(func(a, b): return b.priority > a.priority)
|
new_hovered.sort_custom(func(a, b): return b.priority < a.priority)
|
||||||
|
|
||||||
# Check if top piece changed
|
# Check if top piece changed
|
||||||
var new_top = new_hovered[0] if new_hovered.size() > 0 else null
|
var new_top = new_hovered[0] if new_hovered.size() > 0 else null
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/ComfyUI_09976_.png-90d1260948678f4c6d87ad664d
|
|||||||
compress/mode=0
|
compress/mode=0
|
||||||
compress/high_quality=false
|
compress/high_quality=false
|
||||||
compress/lossy_quality=0.7
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
@@ -25,6 +27,10 @@ mipmaps/generate=false
|
|||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
process/fix_alpha_border=true
|
process/fix_alpha_border=true
|
||||||
process/premult_alpha=false
|
process/premult_alpha=false
|
||||||
process/normal_map_invert_y=false
|
process/normal_map_invert_y=false
|
||||||
|
|||||||
516
Ego.tscn
516
Ego.tscn
@@ -8,124 +8,139 @@
|
|||||||
[ext_resource type="Texture2D" uid="uid://b4inlny6ixmf0" path="res://ego/masks/3.png" id="7_jhjmn"]
|
[ext_resource type="Texture2D" uid="uid://b4inlny6ixmf0" path="res://ego/masks/3.png" id="7_jhjmn"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bnnap4pr1mr5h" path="res://ego/animations/rosella/img_00103_.png" id="9_pyi2f"]
|
[ext_resource type="Texture2D" uid="uid://bnnap4pr1mr5h" path="res://ego/animations/rosella/img_00103_.png" id="9_pyi2f"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dck67hsxi3rnv" path="res://ego/animations/rosella/img_00069_.png" id="10_l4ay1"]
|
[ext_resource type="Texture2D" uid="uid://dck67hsxi3rnv" path="res://ego/animations/rosella/img_00069_.png" id="10_l4ay1"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bvrsr0b55pbou" path="res://ego/animations/walk6/e/image/frame_0000.png" id="12_4nppn"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bma63tibheds3" path="res://ego/animations/rosella/img_00001_.png" id="12_84jj5"]
|
[ext_resource type="Texture2D" uid="uid://bma63tibheds3" path="res://ego/animations/rosella/img_00001_.png" id="12_84jj5"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bewoslpmmowgr" path="res://ego/animations/walk6/e/image/frame_0001.png" id="13_72g70"]
|
||||||
[ext_resource type="Texture2D" uid="uid://notpa4ibijco" path="res://ego/animations/rosella/img_00031_.png" id="13_ttpag"]
|
[ext_resource type="Texture2D" uid="uid://notpa4ibijco" path="res://ego/animations/rosella/img_00031_.png" id="13_ttpag"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bio44t1xei64v" path="res://ego/animations/rosella/img_00056_.png" id="14_2ts53"]
|
[ext_resource type="Texture2D" uid="uid://bio44t1xei64v" path="res://ego/animations/rosella/img_00056_.png" id="14_2ts53"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cg5sqbqaj1mmv" path="res://ego/animations/rosella/img_00076_.png" id="35_gphxb"]
|
[ext_resource type="Texture2D" uid="uid://b105ixtjlaemw" path="res://ego/animations/walk6/e/image/frame_0002.png" id="14_jgc4u"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dwbrh1gl8ig4y" path="res://ego/animations/rosella/img_00077_.png" id="36_gpkly"]
|
[ext_resource type="Texture2D" uid="uid://dj5qqu1i60t8b" path="res://ego/animations/walk6/e/image/frame_0003.png" id="15_k08d4"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bgw06nmfunwda" path="res://ego/animations/rosella/img_00078_.png" id="37_0nogo"]
|
[ext_resource type="Texture2D" uid="uid://bv6a6vt0q5luo" path="res://ego/animations/walk6/e/image/frame_0004.png" id="16_kxwb1"]
|
||||||
[ext_resource type="Texture2D" uid="uid://0vli2hym4ie" path="res://ego/animations/rosella/img_00079_.png" id="38_atjfg"]
|
[ext_resource type="Texture2D" uid="uid://clrk60e8f6cto" path="res://ego/animations/walk6/e/image/frame_0005.png" id="17_m5pot"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cb0phxkfcvulo" path="res://ego/animations/rosella/img_00080_.png" id="39_vq1x5"]
|
[ext_resource type="Texture2D" uid="uid://hgah784brj1u" path="res://ego/animations/walk6/e/image/frame_0006.png" id="18_uejjd"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bqeqgqd6fd76d" path="res://ego/animations/rosella/img_00081_.png" id="40_k80hd"]
|
[ext_resource type="Texture2D" uid="uid://dvct6l2bs4xfo" path="res://ego/animations/walk6/e/image/frame_0007.png" id="19_elvj4"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b553win6ylbtv" path="res://ego/animations/rosella/img_00082_.png" id="41_fcwhd"]
|
[ext_resource type="Texture2D" uid="uid://73p11ya60fhx" path="res://ego/animations/walk6/e/image/frame_0008.png" id="20_gsu4v"]
|
||||||
[ext_resource type="Texture2D" uid="uid://d0de8nrdgr1wk" path="res://ego/animations/rosella/img_00083_.png" id="42_p3kcj"]
|
[ext_resource type="Texture2D" uid="uid://b25stwboh3o6a" path="res://ego/animations/walk6/e/image/frame_0009.png" id="21_s0vn5"]
|
||||||
[ext_resource type="Texture2D" uid="uid://crwhr71lshdva" path="res://ego/animations/rosella/img_00084_.png" id="43_lt2am"]
|
[ext_resource type="Texture2D" uid="uid://elkyn3cmg0c2" path="res://ego/animations/walk6/e/image/frame_0010.png" id="22_opx4c"]
|
||||||
[ext_resource type="Texture2D" uid="uid://d0l40is1juh67" path="res://ego/animations/rosella/img_00085_.png" id="44_a03gu"]
|
[ext_resource type="Texture2D" uid="uid://djgn51fdby287" path="res://ego/animations/walk6/e/image/frame_0011.png" id="23_aoxuo"]
|
||||||
[ext_resource type="Texture2D" uid="uid://db848rfj88m05" path="res://ego/animations/rosella/img_00086_.png" id="45_8k8du"]
|
[ext_resource type="Texture2D" uid="uid://dlbpbe6s4l1tx" path="res://ego/animations/walk6/e/image/frame_0012.png" id="24_yyx1q"]
|
||||||
[ext_resource type="Texture2D" uid="uid://mr8owblcx4hd" path="res://ego/animations/rosella/img_00087_.png" id="46_d4tyc"]
|
[ext_resource type="Texture2D" uid="uid://wrn8804ysm1r" path="res://ego/animations/walk6/e/image/frame_0013.png" id="25_gw6rl"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dlug3lmdktatv" path="res://ego/animations/rosella/img_00088_.png" id="47_gjkxo"]
|
[ext_resource type="Texture2D" uid="uid://dfknsguku55ft" path="res://ego/animations/walk6/e/image/frame_0014.png" id="26_qf3gd"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cph5yxxllk651" path="res://ego/animations/rosella/img_00089_.png" id="48_1s2in"]
|
[ext_resource type="Texture2D" uid="uid://o55311qur6ux" path="res://ego/animations/walk6/e/image/frame_0015.png" id="27_mk8du"]
|
||||||
[ext_resource type="Texture2D" uid="uid://m7igon4nf2cr" path="res://ego/animations/rosella/img_00090_.png" id="49_xusjq"]
|
[ext_resource type="Texture2D" uid="uid://btp8767fm0iq7" path="res://ego/animations/walk6/n/image/frame_0016.png" id="28_gw6rl"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b32tvyeo2qlyu" path="res://ego/animations/rosella/img_00091_.png" id="50_laj3v"]
|
[ext_resource type="Texture2D" uid="uid://cq6envo4lp6ro" path="res://ego/animations/walk6/n/image/frame_0017.png" id="29_qf3gd"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bm8rmjef65tgj" path="res://ego/animations/rosella/img_00092_.png" id="51_w12ac"]
|
[ext_resource type="Texture2D" uid="uid://doelb4yxmyms4" path="res://ego/animations/walk6/n/image/frame_0018.png" id="30_mk8du"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cbx760fqragtk" path="res://ego/animations/rosella/img_00093_.png" id="52_ww1el"]
|
[ext_resource type="Texture2D" uid="uid://bu0kutuqi7eq" path="res://ego/animations/walk6/n/image/frame_0019.png" id="31_x73qc"]
|
||||||
[ext_resource type="Texture2D" uid="uid://puk2xmou5bse" path="res://ego/animations/rosella/img_00094_.png" id="53_5r8ch"]
|
[ext_resource type="Texture2D" uid="uid://b2gqntbxjjjqh" path="res://ego/animations/walk6/n/image/frame_0020.png" id="32_qrgip"]
|
||||||
[ext_resource type="Texture2D" uid="uid://51ebjq5e220v" path="res://ego/animations/rosella/img_00095_.png" id="54_twso8"]
|
[ext_resource type="Texture2D" uid="uid://ctxixw4wclmqk" path="res://ego/animations/walk6/n/image/frame_0021.png" id="33_2ah26"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b8xxc3utklfbg" path="res://ego/animations/rosella/img_00096_.png" id="55_qwddt"]
|
[ext_resource type="Texture2D" uid="uid://cekttv2sd1lp4" path="res://ego/animations/walk6/n/image/frame_0022.png" id="34_2kb50"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dgm08dti21wf" path="res://ego/animations/rosella/img_00097_.png" id="56_665sf"]
|
[ext_resource type="Texture2D" uid="uid://hr3hg4yx4jgj" path="res://ego/animations/walk6/n/image/frame_0023.png" id="35_tl3rq"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cg32svq3ubjl0" path="res://ego/animations/rosella/img_00098_.png" id="57_5qxwo"]
|
[ext_resource type="Texture2D" uid="uid://f35wf4l1k8vx" path="res://ego/animations/walk6/n/image/frame_0024.png" id="36_p38v6"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b2p68seocumxc" path="res://ego/animations/rosella/img_00099_.png" id="58_cv6on"]
|
[ext_resource type="Texture2D" uid="uid://ohs0yvbig878" path="res://ego/animations/walk6/n/image/frame_0025.png" id="37_0v1yx"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ddysiuqg3md00" path="res://ego/animations/rosella/img_00100_.png" id="59_1ubhi"]
|
[ext_resource type="Texture2D" uid="uid://djnwrqr3cyfyh" path="res://ego/animations/walk6/n/image/frame_0026.png" id="38_37u3v"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bqaskor0ehfuq" path="res://ego/animations/rosella/img_00101_.png" id="60_dqjs6"]
|
[ext_resource type="Texture2D" uid="uid://ceo6nje8u1h4x" path="res://ego/animations/walk6/n/image/frame_0027.png" id="39_fkaqq"]
|
||||||
[ext_resource type="Texture2D" uid="uid://jidrqhgsqmec" path="res://ego/animations/rosella/img_00102_.png" id="61_fj0td"]
|
[ext_resource type="Texture2D" uid="uid://di8blm0onobj" path="res://ego/animations/walk6/n/image/frame_0028.png" id="40_okkqf"]
|
||||||
[ext_resource type="Texture2D" uid="uid://lbjiluk8ntk8" path="res://ego/animations/rosella/img_00104_.png" id="62_1oix2"]
|
[ext_resource type="Texture2D" uid="uid://dnyd4ce7xwewg" path="res://ego/animations/walk6/n/image/frame_0029.png" id="41_c5tbi"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bd5q4c6e0xye4" path="res://ego/animations/rosella/img_00105_.png" id="63_hkmm4"]
|
[ext_resource type="Texture2D" uid="uid://cwxduxrkh52x0" path="res://ego/animations/walk6/n/image/frame_0030.png" id="42_q66kk"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cf72vjyp24ppk" path="res://ego/animations/rosella/img_00061_.png" id="64_f3le7"]
|
[ext_resource type="Texture2D" uid="uid://dmvy0ss2ettds" path="res://ego/animations/walk6/n/image/frame_0031.png" id="43_vvmec"]
|
||||||
[ext_resource type="Texture2D" uid="uid://f284av04l3qc" path="res://ego/animations/rosella/img_00062_.png" id="65_c1022"]
|
[ext_resource type="Texture2D" uid="uid://dgodwo787wase" path="res://ego/animations/walk6/ne/image/frame_0000.png" id="44_xff26"]
|
||||||
[ext_resource type="Texture2D" uid="uid://c43wvjoob67ga" path="res://ego/animations/rosella/img_00063_.png" id="66_1r88r"]
|
[ext_resource type="Texture2D" uid="uid://bqjfph16yhjwa" path="res://ego/animations/walk6/ne/image/frame_0001.png" id="45_7hvw5"]
|
||||||
[ext_resource type="Texture2D" uid="uid://deg2xa6euweai" path="res://ego/animations/rosella/img_00064_.png" id="67_fo0ow"]
|
[ext_resource type="Texture2D" uid="uid://n5b27nerh745" path="res://ego/animations/walk6/ne/image/frame_0002.png" id="46_ib7pv"]
|
||||||
[ext_resource type="Texture2D" uid="uid://d0pwlq1h6m281" path="res://ego/animations/rosella/img_00065_.png" id="68_m0ljg"]
|
[ext_resource type="Texture2D" uid="uid://cbwxgca7b7d3p" path="res://ego/animations/walk6/ne/image/frame_0003.png" id="47_1ypi2"]
|
||||||
[ext_resource type="Texture2D" uid="uid://d1uudexxfkoxv" path="res://ego/animations/rosella/img_00066_.png" id="69_4wwa5"]
|
[ext_resource type="Texture2D" uid="uid://ck5cg76kjt2tj" path="res://ego/animations/walk6/ne/image/frame_0004.png" id="48_bb5nw"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dbgb7pkwobys3" path="res://ego/animations/rosella/img_00067_.png" id="70_ouq1l"]
|
[ext_resource type="Texture2D" uid="uid://bol547r5xbbyo" path="res://ego/animations/walk6/ne/image/frame_0005.png" id="49_4hl61"]
|
||||||
[ext_resource type="Texture2D" uid="uid://e52vgy56v2bk" path="res://ego/animations/rosella/img_00068_.png" id="71_gygjm"]
|
[ext_resource type="Texture2D" uid="uid://b06wbkkgu47iu" path="res://ego/animations/walk6/ne/image/frame_0006.png" id="50_df5q1"]
|
||||||
[ext_resource type="Texture2D" uid="uid://5viwlyfh5fj4" path="res://ego/animations/rosella/img_00070_.png" id="72_0kaxt"]
|
[ext_resource type="Texture2D" uid="uid://c8cuugb52glen" path="res://ego/animations/walk6/ne/image/frame_0007.png" id="51_dnhwr"]
|
||||||
[ext_resource type="Texture2D" uid="uid://btva2sp0ktooh" path="res://ego/animations/rosella/img_00071_.png" id="73_db5ja"]
|
[ext_resource type="Texture2D" uid="uid://vjdars4cuymm" path="res://ego/animations/walk6/ne/image/frame_0008.png" id="52_0rhxg"]
|
||||||
[ext_resource type="Texture2D" uid="uid://7fksrocnnefd" path="res://ego/animations/rosella/img_00072_.png" id="74_1jmh4"]
|
[ext_resource type="Texture2D" uid="uid://bc14roj0xc7so" path="res://ego/animations/walk6/ne/image/frame_0009.png" id="53_lh1ea"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cy4ynarwk2lwt" path="res://ego/animations/rosella/img_00073_.png" id="75_i71gw"]
|
[ext_resource type="Texture2D" uid="uid://cee5xi1s057bx" path="res://ego/animations/walk6/ne/image/frame_0010.png" id="54_i0lgs"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cxbsa3s17s4wy" path="res://ego/animations/rosella/img_00074_.png" id="76_t4gew"]
|
[ext_resource type="Texture2D" uid="uid://dkmin76r8o88w" path="res://ego/animations/walk6/ne/image/frame_0011.png" id="55_av2vk"]
|
||||||
[ext_resource type="Texture2D" uid="uid://d0jhqqpkylfpk" path="res://ego/animations/rosella/img_00075_.png" id="77_bn0fg"]
|
[ext_resource type="Texture2D" uid="uid://cayosnox1s802" path="res://ego/animations/walk6/ne/image/frame_0012.png" id="56_xba83"]
|
||||||
[ext_resource type="Texture2D" uid="uid://d12fabpeuio5j" path="res://ego/animations/rosella/img_00002_.png" id="92_ie3g4"]
|
[ext_resource type="Texture2D" uid="uid://dw6b0np8svoyj" path="res://ego/animations/walk6/ne/image/frame_0013.png" id="57_v6qvo"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cy7q04eg5hjvx" path="res://ego/animations/rosella/img_00003_.png" id="93_nm270"]
|
[ext_resource type="Texture2D" uid="uid://1arv1eg1imfe" path="res://ego/animations/walk6/ne/image/frame_0014.png" id="58_kmnvl"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bpqarq0yirtuh" path="res://ego/animations/rosella/img_00004_.png" id="94_vawqf"]
|
[ext_resource type="Texture2D" uid="uid://dtll4c1enlifl" path="res://ego/animations/walk6/ne/image/frame_0015.png" id="59_fuy8j"]
|
||||||
[ext_resource type="Texture2D" uid="uid://m5wgl7mifwqk" path="res://ego/animations/rosella/img_00005_.png" id="95_m3ymp"]
|
[ext_resource type="Texture2D" uid="uid://8hrjled324vu" path="res://ego/animations/walk6/nw/image/frame_0016.png" id="60_uysyb"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cbufiq5fjmq03" path="res://ego/animations/rosella/img_00006_.png" id="96_xowhf"]
|
[ext_resource type="Texture2D" uid="uid://bk5b6jqj58euy" path="res://ego/animations/walk6/nw/image/frame_0017.png" id="61_0yvyt"]
|
||||||
[ext_resource type="Texture2D" uid="uid://gubrfsm2pk0x" path="res://ego/animations/rosella/img_00007_.png" id="97_3asjl"]
|
[ext_resource type="Texture2D" uid="uid://by8hvy766aqo8" path="res://ego/animations/walk6/nw/image/frame_0018.png" id="62_6i2ne"]
|
||||||
[ext_resource type="Texture2D" uid="uid://binxa18kwl3d4" path="res://ego/animations/rosella/img_00008_.png" id="98_bl8n8"]
|
[ext_resource type="Texture2D" uid="uid://q8ydpu1jq1m4" path="res://ego/animations/walk6/nw/image/frame_0019.png" id="63_cdocw"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cfbwoverts640" path="res://ego/animations/rosella/img_00009_.png" id="99_ski6f"]
|
[ext_resource type="Texture2D" uid="uid://13btqib4d01m" path="res://ego/animations/walk6/nw/image/frame_0020.png" id="64_emfac"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bjk0a5x3tb84w" path="res://ego/animations/rosella/img_00010_.png" id="100_mf0u4"]
|
[ext_resource type="Texture2D" uid="uid://co406e0caf7rs" path="res://ego/animations/walk6/nw/image/frame_0021.png" id="65_24r7p"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b6lqqhr124lh" path="res://ego/animations/rosella/img_00011_.png" id="101_stlf2"]
|
[ext_resource type="Texture2D" uid="uid://cq67a0pi8534b" path="res://ego/animations/walk6/nw/image/frame_0022.png" id="66_p6u0u"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bv2b02uqonxe1" path="res://ego/animations/rosella/img_00012_.png" id="102_3uaju"]
|
[ext_resource type="Texture2D" uid="uid://ccuqsnvb45wid" path="res://ego/animations/walk6/nw/image/frame_0023.png" id="67_n8x0v"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b0icq1fqlcgup" path="res://ego/animations/rosella/img_00013_.png" id="103_k4pwn"]
|
[ext_resource type="Texture2D" uid="uid://nyt7luhf2exy" path="res://ego/animations/walk6/nw/image/frame_0024.png" id="68_amoxi"]
|
||||||
[ext_resource type="Texture2D" uid="uid://t4ws1dxrk74k" path="res://ego/animations/rosella/img_00014_.png" id="104_yudkd"]
|
[ext_resource type="Texture2D" uid="uid://21pwhg2e8j5e" path="res://ego/animations/walk6/nw/image/frame_0025.png" id="69_5csai"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b0hr3ftsvypi3" path="res://ego/animations/rosella/img_00015_.png" id="105_gyxix"]
|
[ext_resource type="Texture2D" uid="uid://1kw0wwwhcd2g" path="res://ego/animations/walk6/nw/image/frame_0026.png" id="70_b3d6q"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cujcg5fs2d4s1" path="res://ego/animations/rosella/img_00032_.png" id="106_tj1k5"]
|
[ext_resource type="Texture2D" uid="uid://ct752psctn0av" path="res://ego/animations/walk6/nw/image/frame_0027.png" id="71_m405h"]
|
||||||
[ext_resource type="Texture2D" uid="uid://0a1estsf13nm" path="res://ego/animations/rosella/img_00033_.png" id="107_gmbms"]
|
[ext_resource type="Texture2D" uid="uid://do3855gst2lv4" path="res://ego/animations/walk6/nw/image/frame_0028.png" id="72_p25cj"]
|
||||||
[ext_resource type="Texture2D" uid="uid://c46xhdf224a2m" path="res://ego/animations/rosella/img_00034_.png" id="108_o7aaa"]
|
[ext_resource type="Texture2D" uid="uid://bb5mp21ssu06q" path="res://ego/animations/walk6/nw/image/frame_0029.png" id="73_8hyjb"]
|
||||||
[ext_resource type="Texture2D" uid="uid://rln2p7r6a5" path="res://ego/animations/rosella/img_00035_.png" id="109_7sodb"]
|
[ext_resource type="Texture2D" uid="uid://xxh03tdjncbt" path="res://ego/animations/walk6/nw/image/frame_0030.png" id="74_8q4hi"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b1xifkxpy1hb6" path="res://ego/animations/rosella/img_00036_.png" id="110_5od0t"]
|
[ext_resource type="Texture2D" uid="uid://vutdndo0qgnk" path="res://ego/animations/walk6/nw/image/frame_0031.png" id="75_uff0b"]
|
||||||
[ext_resource type="Texture2D" uid="uid://gog3qgvko874" path="res://ego/animations/rosella/img_00037_.png" id="111_mgwvh"]
|
[ext_resource type="Texture2D" uid="uid://ibpf2uuxc27e" path="res://ego/animations/walk6/s/image/frame_0016.png" id="76_dsexq"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b7qp3mt0ysveg" path="res://ego/animations/rosella/img_00038_.png" id="112_0r2r0"]
|
[ext_resource type="Texture2D" uid="uid://sh50dk0u21gv" path="res://ego/animations/walk6/s/image/frame_0017.png" id="77_hwnuj"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ccpx5q1dhhtda" path="res://ego/animations/rosella/img_00039_.png" id="113_vlgai"]
|
[ext_resource type="Texture2D" uid="uid://cn0ec21d4e51i" path="res://ego/animations/walk6/s/image/frame_0018.png" id="78_ivvdo"]
|
||||||
[ext_resource type="Texture2D" uid="uid://77s8kv2rrgms" path="res://ego/animations/rosella/img_00040_.png" id="114_2fgrx"]
|
[ext_resource type="Texture2D" uid="uid://lipn36kkmdg2" path="res://ego/animations/walk6/s/image/frame_0019.png" id="79_786ir"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cxeket55l1uox" path="res://ego/animations/rosella/img_00041_.png" id="115_gtwhg"]
|
[ext_resource type="Texture2D" uid="uid://ckfndx0hhkfu3" path="res://ego/animations/walk6/s/image/frame_0020.png" id="80_5p581"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bahwbfx8wlw8a" path="res://ego/animations/rosella/img_00042_.png" id="116_clvmm"]
|
[ext_resource type="Texture2D" uid="uid://s8r8v5tjo03l" path="res://ego/animations/walk6/s/image/frame_0021.png" id="81_5yp8t"]
|
||||||
[ext_resource type="Texture2D" uid="uid://x37xim021bcr" path="res://ego/animations/rosella/img_00043_.png" id="117_wons0"]
|
[ext_resource type="Texture2D" uid="uid://bo52oqe8hpeke" path="res://ego/animations/walk6/s/image/frame_0022.png" id="82_8umh2"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cfwcuk0rjmmf5" path="res://ego/animations/rosella/img_00044_.png" id="118_im20t"]
|
[ext_resource type="Texture2D" uid="uid://ckqjojy8c2m5e" path="res://ego/animations/walk6/s/image/frame_0023.png" id="83_dn78y"]
|
||||||
[ext_resource type="Texture2D" uid="uid://coyxuaeylsx1i" path="res://ego/animations/rosella/img_00045_.png" id="119_31gcv"]
|
[ext_resource type="Texture2D" uid="uid://p837mhdkkifr" path="res://ego/animations/walk6/s/image/frame_0024.png" id="84_vjaoi"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://exf2i4ggwjak" path="res://ego/animations/walk6/s/image/frame_0025.png" id="85_1bupr"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://b6q01rev3b4yc" path="res://ego/animations/walk6/s/image/frame_0026.png" id="86_def6r"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dp2oh6igsocar" path="res://ego/animations/walk6/s/image/frame_0027.png" id="87_se17v"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://c7appdm0bky1i" path="res://ego/animations/walk6/s/image/frame_0028.png" id="88_atafq"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://drx07btj8l6al" path="res://ego/animations/walk6/s/image/frame_0029.png" id="89_60r7o"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cxxs1ywu72p6p" path="res://ego/animations/walk6/s/image/frame_0030.png" id="90_ub7dx"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://daelr7qf0yuhw" path="res://ego/animations/walk6/s/image/frame_0031.png" id="91_e7eqt"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://hdtep2u1rmer" path="res://ego/animations/walk6/se/image/frame_0000.png" id="92_3vrr3"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bhvhwej1nrhx4" path="res://ego/animations/walk6/se/image/frame_0001.png" id="93_6epyu"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dp2dw867l7ifl" path="res://ego/animations/walk6/se/image/frame_0002.png" id="94_pjif5"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://ctarli3djfk5d" path="res://ego/animations/walk6/se/image/frame_0003.png" id="95_1h26f"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://q8qlsog836fc" path="res://ego/animations/walk6/se/image/frame_0004.png" id="96_klrxs"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dn8svxp7b2es7" path="res://ego/animations/walk6/se/image/frame_0005.png" id="97_nwnj3"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dcbnlm0bbdtrr" path="res://ego/animations/walk6/se/image/frame_0006.png" id="98_bbx6e"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://b2pprdtdj31a2" path="res://ego/animations/walk6/se/image/frame_0007.png" id="99_bru01"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cc5dn4iff37mi" path="res://ego/animations/walk6/se/image/frame_0008.png" id="100_cp2xd"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cr5nma70ectjf" path="res://ego/animations/walk6/se/image/frame_0009.png" id="101_jbccs"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://j71c27rvol84" path="res://ego/animations/walk6/se/image/frame_0010.png" id="102_bu1yf"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cragg3ffp8fkx" path="res://ego/animations/walk6/se/image/frame_0011.png" id="103_1484e"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bhn47ko6cps5m" path="res://ego/animations/walk6/se/image/frame_0012.png" id="104_scw7s"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://qcggsl5xl2m7" path="res://ego/animations/walk6/se/image/frame_0013.png" id="105_timr7"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://c1ckt15isyv6a" path="res://ego/animations/walk6/se/image/frame_0014.png" id="106_nlo5j"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://wq201khar1r4" path="res://ego/animations/walk6/se/image/frame_0015.png" id="107_yna12"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://b3ulpsu03i0wp" path="res://ego/animations/walk6/sw/image/frame_0000.png" id="108_tbxo8"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cdw2yjedrlvr7" path="res://ego/animations/walk6/sw/image/frame_0001.png" id="109_cwboe"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://xa7qkvs1xkp7" path="res://ego/animations/walk6/sw/image/frame_0002.png" id="110_fci48"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://d2lxnxeduchey" path="res://ego/animations/walk6/sw/image/frame_0003.png" id="111_oo60o"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://blxmeqor2delv" path="res://ego/animations/walk6/sw/image/frame_0004.png" id="112_jk871"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bvkg4cb878msd" path="res://ego/animations/walk6/sw/image/frame_0005.png" id="113_fqwbh"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dj7c4sjonys1l" path="res://ego/animations/walk6/sw/image/frame_0006.png" id="114_boqln"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://s1wbs8usun0m" path="res://ego/animations/walk6/sw/image/frame_0007.png" id="115_gjc4p"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://ds3t17hgm1a37" path="res://ego/animations/walk6/sw/image/frame_0008.png" id="116_338xc"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cdakhhgglyq3a" path="res://ego/animations/walk6/sw/image/frame_0009.png" id="117_v50lk"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://8tuqjah64of1" path="res://ego/animations/walk6/sw/image/frame_0010.png" id="118_ssq1t"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://d3lfrum86awn2" path="res://ego/animations/walk6/sw/image/frame_0011.png" id="119_huqp0"]
|
||||||
[ext_resource type="Texture2D" uid="uid://j6v4fyxanf3q" path="res://ego/animations/rosella/img_00106_.png" id="119_q6yh0"]
|
[ext_resource type="Texture2D" uid="uid://j6v4fyxanf3q" path="res://ego/animations/rosella/img_00106_.png" id="119_q6yh0"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bhulcb0tcph6y" path="res://ego/animations/rosella/img_00107_.png" id="120_pagte"]
|
[ext_resource type="Texture2D" uid="uid://do2g2v7qq8kcs" path="res://ego/animations/walk6/sw/image/frame_0012.png" id="120_274ja"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dju8ct8uh4x4a" path="res://ego/animations/rosella/img_00046_.png" id="120_qeejn"]
|
[ext_resource type="Texture2D" uid="uid://gsrymkte3dwy" path="res://ego/animations/walk6/sw/image/frame_0013.png" id="121_u8w2y"]
|
||||||
[ext_resource type="Texture2D" uid="uid://btntcfpy7sxq3" path="res://ego/animations/rosella/img_00047_.png" id="121_h6nhi"]
|
[ext_resource type="Texture2D" uid="uid://quow7u232wxa" path="res://ego/animations/walk6/sw/image/frame_0014.png" id="122_1pwk6"]
|
||||||
[ext_resource type="Texture2D" uid="uid://xmqtqshjh5ad" path="res://ego/animations/rosella/img_00108_.png" id="121_hg8r5"]
|
[ext_resource type="Texture2D" uid="uid://c3bt0sjoptdwx" path="res://ego/animations/walk6/sw/image/frame_0015.png" id="123_248hs"]
|
||||||
[ext_resource type="Texture2D" uid="uid://c8bjdgjwj41ay" path="res://ego/animations/rosella/img_00109_.png" id="122_5oaqq"]
|
[ext_resource type="Texture2D" uid="uid://jhfveypdrxx6" path="res://ego/animations/walk6/w/image/frame_0000.png" id="124_uy2xp"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dnl5qg8pdg7js" path="res://ego/animations/rosella/img_00048_.png" id="122_grugb"]
|
[ext_resource type="Texture2D" uid="uid://jfl3v3tru3ok" path="res://ego/animations/walk6/w/image/frame_0001.png" id="125_o8wjp"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dywo3e1aq3sdi" path="res://ego/animations/rosella/img_00110_.png" id="123_kn1mn"]
|
[ext_resource type="Texture2D" uid="uid://bfgyj7g1s0tyu" path="res://ego/animations/walk6/w/image/frame_0002.png" id="126_y4i6c"]
|
||||||
[ext_resource type="Texture2D" uid="uid://5okhhcxsivoq" path="res://ego/animations/rosella/img_00049_.png" id="123_yoybg"]
|
[ext_resource type="Texture2D" uid="uid://b8dx5i3spo20" path="res://ego/animations/walk6/w/image/frame_0003.png" id="127_qpxhg"]
|
||||||
[ext_resource type="Texture2D" uid="uid://csnpmnd8mhela" path="res://ego/animations/rosella/img_00050_.png" id="124_8jd8x"]
|
[ext_resource type="Texture2D" uid="uid://bv8t2mtx6str3" path="res://ego/animations/walk6/w/image/frame_0004.png" id="128_fua1r"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bsyvm2c0x50np" path="res://ego/animations/rosella/img_00111_.png" id="124_opp18"]
|
[ext_resource type="Texture2D" uid="uid://dv5r6vggsvi1e" path="res://ego/animations/walk6/w/image/frame_0005.png" id="129_i3cnu"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ct2p00u6hqpfm" path="res://ego/animations/rosella/img_00112_.png" id="125_4nwac"]
|
[ext_resource type="Texture2D" uid="uid://dwsw5mulqwaov" path="res://ego/animations/walk6/w/image/frame_0006.png" id="130_bt6sr"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ngodxvv1jgiy" path="res://ego/animations/rosella/img_00051_.png" id="125_nm7rs"]
|
[ext_resource type="Texture2D" uid="uid://c1j245fawfb6r" path="res://ego/animations/walk6/w/image/frame_0007.png" id="131_u0i8g"]
|
||||||
[ext_resource type="Texture2D" uid="uid://wgat1ygky6vb" path="res://ego/animations/rosella/img_00052_.png" id="126_cviwa"]
|
[ext_resource type="Texture2D" uid="uid://dejanvimdcw73" path="res://ego/animations/walk6/w/image/frame_0008.png" id="132_wvpsm"]
|
||||||
[ext_resource type="Texture2D" uid="uid://brf3b2o7wehcm" path="res://ego/animations/rosella/img_00113_.png" id="126_ido3p"]
|
[ext_resource type="Texture2D" uid="uid://dpgmhaf00uwrv" path="res://ego/animations/walk6/w/image/frame_0009.png" id="133_dxmcl"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cwv0rfu6mixdo" path="res://ego/animations/rosella/img_00053_.png" id="127_bpypy"]
|
[ext_resource type="Texture2D" uid="uid://c1w600krkghsr" path="res://ego/animations/walk6/w/image/frame_0010.png" id="134_u084s"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dsykfaqdjbnnf" path="res://ego/animations/rosella/img_00114_.png" id="127_iwaxh"]
|
[ext_resource type="Texture2D" uid="uid://bitfme7l2hhmt" path="res://ego/animations/walk6/w/image/frame_0011.png" id="135_lflbb"]
|
||||||
[ext_resource type="Texture2D" uid="uid://pnvg6du2qq6d" path="res://ego/animations/rosella/img_00115_.png" id="128_ar1ys"]
|
[ext_resource type="Texture2D" uid="uid://c8wnouu2p482i" path="res://ego/animations/walk6/w/image/frame_0012.png" id="136_08xgv"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dv1vf7vu27ug7" path="res://ego/animations/rosella/img_00054_.png" id="128_qenlf"]
|
[ext_resource type="Texture2D" uid="uid://dt0asn0fywk3l" path="res://ego/animations/walk6/w/image/frame_0013.png" id="137_j38cn"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bb855tpyoaitj" path="res://ego/animations/rosella/img_00055_.png" id="129_7b1px"]
|
[ext_resource type="Texture2D" uid="uid://dbnjhs46g3tox" path="res://ego/animations/walk6/w/image/frame_0014.png" id="138_wfkq6"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dsg2pjb1wvt1q" path="res://ego/animations/rosella/img_00116_.png" id="129_gxp5c"]
|
[ext_resource type="Texture2D" uid="uid://cnuokkal5qj8a" path="res://ego/animations/walk6/w/image/frame_0015.png" id="139_aqsva"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dkbggvmvgf31a" path="res://ego/animations/rosella/img_00117_.png" id="130_0ooo7"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://l8c28scv1mb5" path="res://ego/animations/rosella/img_00057_.png" id="130_w3x52"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://tk736wuremvo" path="res://ego/animations/rosella/img_00058_.png" id="131_nfjxv"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://b7ndpr0lputtn" path="res://ego/animations/rosella/img_00118_.png" id="131_okk5g"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://d2rv38oy5neff" path="res://ego/animations/rosella/img_00119_.png" id="132_0g30d"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://bs3waxmju8q2x" path="res://ego/animations/rosella/img_00059_.png" id="132_v1scd"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://xh1mxrknsfle" path="res://ego/animations/rosella/img_00060_.png" id="133_kxwux"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://bdk2vrjstiodj" path="res://ego/animations/rosella/img_00120_.png" id="133_w8q6v"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://cbiapiccssu0k" path="res://ego/animations/rosella/img_00016_.png" id="159_6fkdd"]
|
[ext_resource type="Texture2D" uid="uid://cbiapiccssu0k" path="res://ego/animations/rosella/img_00016_.png" id="159_6fkdd"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dtjlq5rm3gj3c" path="res://ego/animations/rosella/img_00017_.png" id="160_llhmj"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://dij6cjatpop24" path="res://ego/animations/rosella/img_00018_.png" id="161_uupqn"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://8ylna7crhmiq" path="res://ego/animations/rosella/img_00019_.png" id="162_vqsv2"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://rkrkgom3cm3v" path="res://ego/animations/rosella/img_00020_.png" id="163_nrmid"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://fg5643mb7a3q" path="res://ego/animations/rosella/img_00021_.png" id="164_orhiv"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://b4hg51a11paw1" path="res://ego/animations/rosella/img_00022_.png" id="165_qik70"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://n2hgry6npirj" path="res://ego/animations/rosella/img_00023_.png" id="166_414b7"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://0bi20hsxamun" path="res://ego/animations/rosella/img_00024_.png" id="167_gugxh"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://dkbnilfkftdo8" path="res://ego/animations/rosella/img_00025_.png" id="168_525u8"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://dywe87t2qm0im" path="res://ego/animations/rosella/img_00026_.png" id="169_wbmcb"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://r6hhulvl5wtn" path="res://ego/animations/rosella/img_00027_.png" id="170_t83h1"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://w47creb8ae45" path="res://ego/animations/rosella/img_00028_.png" id="171_ifskr"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://370l1illwxuv" path="res://ego/animations/rosella/img_00029_.png" id="172_rfe2v"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://c04v143dispfa" path="res://ego/animations/rosella/img_00030_.png" id="173_q1b42"]
|
|
||||||
[ext_resource type="Theme" uid="uid://dkli02kmdncbc" path="res://UITheme.tres" id="194"]
|
[ext_resource type="Theme" uid="uid://dkli02kmdncbc" path="res://UITheme.tres" id="194"]
|
||||||
[ext_resource type="Script" uid="uid://b6gqw3bcaoye5" path="res://ego/Ego.gd" id="195"]
|
[ext_resource type="Script" uid="uid://b6gqw3bcaoye5" path="res://ego/Ego.gd" id="195"]
|
||||||
|
|
||||||
@@ -309,49 +324,52 @@ animations = [{
|
|||||||
}, {
|
}, {
|
||||||
"frames": [{
|
"frames": [{
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("119_q6yh0")
|
"texture": ExtResource("12_4nppn")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("120_pagte")
|
"texture": ExtResource("13_72g70")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("121_hg8r5")
|
"texture": ExtResource("14_jgc4u")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("122_5oaqq")
|
"texture": ExtResource("15_k08d4")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("123_kn1mn")
|
"texture": ExtResource("16_kxwb1")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("124_opp18")
|
"texture": ExtResource("17_m5pot")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("125_4nwac")
|
"texture": ExtResource("18_uejjd")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("126_ido3p")
|
"texture": ExtResource("19_elvj4")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("127_iwaxh")
|
"texture": ExtResource("20_gsu4v")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("128_ar1ys")
|
"texture": ExtResource("21_s0vn5")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("129_gxp5c")
|
"texture": ExtResource("22_opx4c")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("130_0ooo7")
|
"texture": ExtResource("23_aoxuo")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("131_okk5g")
|
"texture": ExtResource("24_yyx1q")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("132_0g30d")
|
"texture": ExtResource("25_gw6rl")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("133_w8q6v")
|
"texture": ExtResource("26_qf3gd")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": ExtResource("27_mk8du")
|
||||||
}],
|
}],
|
||||||
"loop": true,
|
"loop": true,
|
||||||
"name": &"walk_E",
|
"name": &"walk_E",
|
||||||
@@ -359,49 +377,52 @@ animations = [{
|
|||||||
}, {
|
}, {
|
||||||
"frames": [{
|
"frames": [{
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("35_gphxb")
|
"texture": ExtResource("28_gw6rl")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("36_gpkly")
|
"texture": ExtResource("29_qf3gd")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("37_0nogo")
|
"texture": ExtResource("30_mk8du")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("38_atjfg")
|
"texture": ExtResource("31_x73qc")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("39_vq1x5")
|
"texture": ExtResource("32_qrgip")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("40_k80hd")
|
"texture": ExtResource("33_2ah26")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("41_fcwhd")
|
"texture": ExtResource("34_2kb50")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("42_p3kcj")
|
"texture": ExtResource("35_tl3rq")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("43_lt2am")
|
"texture": ExtResource("36_p38v6")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("44_a03gu")
|
"texture": ExtResource("37_0v1yx")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("45_8k8du")
|
"texture": ExtResource("38_37u3v")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("46_d4tyc")
|
"texture": ExtResource("39_fkaqq")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("47_gjkxo")
|
"texture": ExtResource("40_okkqf")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("48_1s2in")
|
"texture": ExtResource("41_c5tbi")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("49_xusjq")
|
"texture": ExtResource("42_q66kk")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": ExtResource("43_vvmec")
|
||||||
}],
|
}],
|
||||||
"loop": true,
|
"loop": true,
|
||||||
"name": &"walk_N",
|
"name": &"walk_N",
|
||||||
@@ -409,49 +430,52 @@ animations = [{
|
|||||||
}, {
|
}, {
|
||||||
"frames": [{
|
"frames": [{
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("50_laj3v")
|
"texture": ExtResource("44_xff26")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("51_w12ac")
|
"texture": ExtResource("45_7hvw5")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("52_ww1el")
|
"texture": ExtResource("46_ib7pv")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("53_5r8ch")
|
"texture": ExtResource("47_1ypi2")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("54_twso8")
|
"texture": ExtResource("48_bb5nw")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("55_qwddt")
|
"texture": ExtResource("49_4hl61")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("56_665sf")
|
"texture": ExtResource("50_df5q1")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("57_5qxwo")
|
"texture": ExtResource("51_dnhwr")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("58_cv6on")
|
"texture": ExtResource("52_0rhxg")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("59_1ubhi")
|
"texture": ExtResource("53_lh1ea")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("60_dqjs6")
|
"texture": ExtResource("54_i0lgs")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("61_fj0td")
|
"texture": ExtResource("55_av2vk")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("9_pyi2f")
|
"texture": ExtResource("56_xba83")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("62_1oix2")
|
"texture": ExtResource("57_v6qvo")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("63_hkmm4")
|
"texture": ExtResource("58_kmnvl")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": ExtResource("59_fuy8j")
|
||||||
}],
|
}],
|
||||||
"loop": true,
|
"loop": true,
|
||||||
"name": &"walk_NE",
|
"name": &"walk_NE",
|
||||||
@@ -459,49 +483,52 @@ animations = [{
|
|||||||
}, {
|
}, {
|
||||||
"frames": [{
|
"frames": [{
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("64_f3le7")
|
"texture": ExtResource("60_uysyb")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("65_c1022")
|
"texture": ExtResource("61_0yvyt")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("66_1r88r")
|
"texture": ExtResource("62_6i2ne")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("67_fo0ow")
|
"texture": ExtResource("63_cdocw")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("68_m0ljg")
|
"texture": ExtResource("64_emfac")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("69_4wwa5")
|
"texture": ExtResource("65_24r7p")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("70_ouq1l")
|
"texture": ExtResource("66_p6u0u")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("71_gygjm")
|
"texture": ExtResource("67_n8x0v")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("10_l4ay1")
|
"texture": ExtResource("68_amoxi")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("72_0kaxt")
|
"texture": ExtResource("69_5csai")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("73_db5ja")
|
"texture": ExtResource("70_b3d6q")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("74_1jmh4")
|
"texture": ExtResource("71_m405h")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("75_i71gw")
|
"texture": ExtResource("72_p25cj")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("76_t4gew")
|
"texture": ExtResource("73_8hyjb")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("77_bn0fg")
|
"texture": ExtResource("74_8q4hi")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": ExtResource("75_uff0b")
|
||||||
}],
|
}],
|
||||||
"loop": true,
|
"loop": true,
|
||||||
"name": &"walk_NW",
|
"name": &"walk_NW",
|
||||||
@@ -509,49 +536,52 @@ animations = [{
|
|||||||
}, {
|
}, {
|
||||||
"frames": [{
|
"frames": [{
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("159_6fkdd")
|
"texture": ExtResource("76_dsexq")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("160_llhmj")
|
"texture": ExtResource("77_hwnuj")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("161_uupqn")
|
"texture": ExtResource("78_ivvdo")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("162_vqsv2")
|
"texture": ExtResource("79_786ir")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("163_nrmid")
|
"texture": ExtResource("80_5p581")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("164_orhiv")
|
"texture": ExtResource("81_5yp8t")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("165_qik70")
|
"texture": ExtResource("82_8umh2")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("166_414b7")
|
"texture": ExtResource("83_dn78y")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("167_gugxh")
|
"texture": ExtResource("84_vjaoi")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("168_525u8")
|
"texture": ExtResource("85_1bupr")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("169_wbmcb")
|
"texture": ExtResource("86_def6r")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("170_t83h1")
|
"texture": ExtResource("87_se17v")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("171_ifskr")
|
"texture": ExtResource("88_atafq")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("172_rfe2v")
|
"texture": ExtResource("89_60r7o")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("173_q1b42")
|
"texture": ExtResource("90_ub7dx")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": ExtResource("91_e7eqt")
|
||||||
}],
|
}],
|
||||||
"loop": true,
|
"loop": true,
|
||||||
"name": &"walk_S",
|
"name": &"walk_S",
|
||||||
@@ -559,49 +589,52 @@ animations = [{
|
|||||||
}, {
|
}, {
|
||||||
"frames": [{
|
"frames": [{
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("12_84jj5")
|
"texture": ExtResource("92_3vrr3")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("92_ie3g4")
|
"texture": ExtResource("93_6epyu")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("93_nm270")
|
"texture": ExtResource("94_pjif5")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("94_vawqf")
|
"texture": ExtResource("95_1h26f")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("95_m3ymp")
|
"texture": ExtResource("96_klrxs")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("96_xowhf")
|
"texture": ExtResource("97_nwnj3")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("97_3asjl")
|
"texture": ExtResource("98_bbx6e")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("98_bl8n8")
|
"texture": ExtResource("99_bru01")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("99_ski6f")
|
"texture": ExtResource("100_cp2xd")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("100_mf0u4")
|
"texture": ExtResource("101_jbccs")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("101_stlf2")
|
"texture": ExtResource("102_bu1yf")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("102_3uaju")
|
"texture": ExtResource("103_1484e")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("103_k4pwn")
|
"texture": ExtResource("104_scw7s")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("104_yudkd")
|
"texture": ExtResource("105_timr7")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("105_gyxix")
|
"texture": ExtResource("106_nlo5j")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": ExtResource("107_yna12")
|
||||||
}],
|
}],
|
||||||
"loop": true,
|
"loop": true,
|
||||||
"name": &"walk_SE",
|
"name": &"walk_SE",
|
||||||
@@ -609,49 +642,52 @@ animations = [{
|
|||||||
}, {
|
}, {
|
||||||
"frames": [{
|
"frames": [{
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("13_ttpag")
|
"texture": ExtResource("108_tbxo8")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("106_tj1k5")
|
"texture": ExtResource("109_cwboe")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("107_gmbms")
|
"texture": ExtResource("110_fci48")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("108_o7aaa")
|
"texture": ExtResource("111_oo60o")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("109_7sodb")
|
"texture": ExtResource("112_jk871")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("110_5od0t")
|
"texture": ExtResource("113_fqwbh")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("111_mgwvh")
|
"texture": ExtResource("114_boqln")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("112_0r2r0")
|
"texture": ExtResource("115_gjc4p")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("113_vlgai")
|
"texture": ExtResource("116_338xc")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("114_2fgrx")
|
"texture": ExtResource("117_v50lk")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("115_gtwhg")
|
"texture": ExtResource("118_ssq1t")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("116_clvmm")
|
"texture": ExtResource("119_huqp0")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("117_wons0")
|
"texture": ExtResource("120_274ja")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("118_im20t")
|
"texture": ExtResource("121_u8w2y")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("119_31gcv")
|
"texture": ExtResource("122_1pwk6")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": ExtResource("123_248hs")
|
||||||
}],
|
}],
|
||||||
"loop": true,
|
"loop": true,
|
||||||
"name": &"walk_SW",
|
"name": &"walk_SW",
|
||||||
@@ -659,49 +695,52 @@ animations = [{
|
|||||||
}, {
|
}, {
|
||||||
"frames": [{
|
"frames": [{
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("120_qeejn")
|
"texture": ExtResource("124_uy2xp")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("121_h6nhi")
|
"texture": ExtResource("125_o8wjp")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("122_grugb")
|
"texture": ExtResource("126_y4i6c")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("123_yoybg")
|
"texture": ExtResource("127_qpxhg")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("124_8jd8x")
|
"texture": ExtResource("128_fua1r")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("125_nm7rs")
|
"texture": ExtResource("129_i3cnu")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("126_cviwa")
|
"texture": ExtResource("130_bt6sr")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("127_bpypy")
|
"texture": ExtResource("131_u0i8g")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("128_qenlf")
|
"texture": ExtResource("132_wvpsm")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("129_7b1px")
|
"texture": ExtResource("133_dxmcl")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("14_2ts53")
|
"texture": ExtResource("134_u084s")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("130_w3x52")
|
"texture": ExtResource("135_lflbb")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("131_nfjxv")
|
"texture": ExtResource("136_08xgv")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("132_v1scd")
|
"texture": ExtResource("137_j38cn")
|
||||||
}, {
|
}, {
|
||||||
"duration": 1.0,
|
"duration": 1.0,
|
||||||
"texture": ExtResource("133_kxwux")
|
"texture": ExtResource("138_wfkq6")
|
||||||
|
}, {
|
||||||
|
"duration": 1.0,
|
||||||
|
"texture": ExtResource("139_aqsva")
|
||||||
}],
|
}],
|
||||||
"loop": true,
|
"loop": true,
|
||||||
"name": &"walk_W",
|
"name": &"walk_W",
|
||||||
@@ -770,14 +809,13 @@ unique_name_in_owner = true
|
|||||||
z_as_relative = false
|
z_as_relative = false
|
||||||
texture_filter = 2
|
texture_filter = 2
|
||||||
material = SubResource("ShaderMaterial_sle7q")
|
material = SubResource("ShaderMaterial_sle7q")
|
||||||
position = Vector2(-14, -13)
|
position = Vector2(-14.000001, -23)
|
||||||
scale = Vector2(1.5, 1.5)
|
scale = Vector2(0.59, 0.59)
|
||||||
sprite_frames = SubResource("1")
|
sprite_frames = SubResource("1")
|
||||||
animation = &"walk_SE"
|
animation = &"walk_W"
|
||||||
frame = 10
|
frame_progress = 0.08623318
|
||||||
frame_progress = 0.19484821
|
|
||||||
speed_scale = 2.0
|
speed_scale = 2.0
|
||||||
offset = Vector2(1.33333, -413.333)
|
offset = Vector2(1.333, -800)
|
||||||
|
|
||||||
[node name="ClipMask" type="AnimatedSprite2D" parent="." unique_id=61198776]
|
[node name="ClipMask" type="AnimatedSprite2D" parent="." unique_id=61198776]
|
||||||
visible = false
|
visible = false
|
||||||
|
|||||||
22
Game.tscn
22
Game.tscn
@@ -10,6 +10,8 @@
|
|||||||
[ext_resource type="PackedScene" uid="uid://c0mp4a2u3jkd" path="res://portrait.tscn" id="7_fj12q"]
|
[ext_resource type="PackedScene" uid="uid://c0mp4a2u3jkd" path="res://portrait.tscn" id="7_fj12q"]
|
||||||
[ext_resource type="Script" uid="uid://bsvab128vy1ip" path="res://OffsetCameraBasedOnMovement.gd" id="8_cvftx"]
|
[ext_resource type="Script" uid="uid://bsvab128vy1ip" path="res://OffsetCameraBasedOnMovement.gd" id="8_cvftx"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dyk4rcqsk3aed" path="res://scenes/kq4_003_fountain_pool/kq4_003_fountain_pool.tscn" id="8_yx171"]
|
[ext_resource type="PackedScene" uid="uid://dyk4rcqsk3aed" path="res://scenes/kq4_003_fountain_pool/kq4_003_fountain_pool.tscn" id="8_yx171"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dxkyfas46q7ef" path="res://inventory/inventory_backpack/InventoryBackpack.tscn" id="9_backpack"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://djoycn4xfa8p3" path="res://inventory/inventory_overlay/InventoryOverlay.tscn" id="a_overlay"]
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_44mjr"]
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_44mjr"]
|
||||||
shader = ExtResource("2_jr51a")
|
shader = ExtResource("2_jr51a")
|
||||||
@@ -183,3 +185,23 @@ label_settings = SubResource("LabelSettings_narrator")
|
|||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
autowrap_mode = 3
|
autowrap_mode = 3
|
||||||
|
|
||||||
|
[node name="HUD" type="CanvasLayer" parent="." unique_id=-294967295]
|
||||||
|
layer = 5
|
||||||
|
|
||||||
|
[node name="InventoryBackpack" parent="HUD" unique_id=-294967294 instance=ExtResource("9_backpack")]
|
||||||
|
anchors_preset = 0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
offset_top = 0.0
|
||||||
|
offset_bottom = 70.0
|
||||||
|
grow_vertical = 1
|
||||||
|
|
||||||
|
[node name="InventoryOverlayLayer" type="CanvasLayer" parent="." unique_id=-294967293]
|
||||||
|
layer = 10
|
||||||
|
|
||||||
|
[node name="InventoryOverlay" parent="InventoryOverlayLayer" unique_id=-294967292 instance=ExtResource("a_overlay")]
|
||||||
|
|
||||||
|
[connection signal="overlay_hide_requested" from="HUD/InventoryBackpack" to="." method="_on_backpack_hide_overlay"]
|
||||||
|
[connection signal="overlay_show_requested" from="HUD/InventoryBackpack" to="." method="_on_backpack_show_overlay"]
|
||||||
|
[connection signal="item_confirmed" from="InventoryOverlayLayer/InventoryOverlay" to="." method="_on_overlay_item_confirmed"]
|
||||||
|
|||||||
@@ -477,4 +477,53 @@ func reset_camera():
|
|||||||
var thing = ResetCamera.new()
|
var thing = ResetCamera.new()
|
||||||
return thing
|
return thing
|
||||||
|
|
||||||
|
class GiveItem:
|
||||||
|
extends ScriptNode
|
||||||
|
var item_id: String = ""
|
||||||
|
var text: String = ""
|
||||||
|
var subject: Node2D = null
|
||||||
|
var done = false
|
||||||
|
var started = false
|
||||||
|
|
||||||
|
func step_type():
|
||||||
|
return "GiveItem " + item_id
|
||||||
|
|
||||||
|
func init(scene):
|
||||||
|
super(scene)
|
||||||
|
|
||||||
|
func do(delta):
|
||||||
|
if not started:
|
||||||
|
started = true
|
||||||
|
if text:
|
||||||
|
await scene.find_child("dialogue").say(text)
|
||||||
|
InventoryManager.acquire_item(item_id)
|
||||||
|
done = true
|
||||||
|
|
||||||
|
func is_done():
|
||||||
|
return done
|
||||||
|
|
||||||
|
func interrupt():
|
||||||
|
done = true
|
||||||
|
|
||||||
|
class GiveItemDeferred:
|
||||||
|
extends GiveItem
|
||||||
|
var subject_name: String = ""
|
||||||
|
|
||||||
|
func init(scene):
|
||||||
|
super(scene)
|
||||||
|
subject = scene.get_node(subject_name)
|
||||||
|
|
||||||
|
func give_item(item_id: String, text: String = ""):
|
||||||
|
var step = GiveItem.new()
|
||||||
|
step.item_id = item_id
|
||||||
|
step.text = text
|
||||||
|
return step
|
||||||
|
|
||||||
|
func give_item_deferred(item_id: String, subject_name: String, text: String = ""):
|
||||||
|
var step = GiveItemDeferred.new()
|
||||||
|
step.item_id = item_id
|
||||||
|
step.subject_name = subject_name
|
||||||
|
step.text = text
|
||||||
|
return step
|
||||||
|
|
||||||
var current_script : ScriptGraph = null
|
var current_script : ScriptGraph = null
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ msdf_pixel_range=8
|
|||||||
msdf_size=48
|
msdf_size=48
|
||||||
allow_system_fallback=true
|
allow_system_fallback=true
|
||||||
force_autohinter=false
|
force_autohinter=false
|
||||||
|
modulate_color_glyphs=false
|
||||||
hinting=1
|
hinting=1
|
||||||
subpixel_positioning=1
|
subpixel_positioning=1
|
||||||
keep_rounding_remainders=true
|
keep_rounding_remainders=true
|
||||||
|
|||||||
45
MainGame.gd
45
MainGame.gd
@@ -3,12 +3,21 @@ extends Node2D
|
|||||||
|
|
||||||
var cursors = [load("res://boot_icon.png"), load("res://eye_icon.png"), load("res://hand_icon.png"), load("res://speech_icon.png")]
|
var cursors = [load("res://boot_icon.png"), load("res://eye_icon.png"), load("res://hand_icon.png"), load("res://speech_icon.png")]
|
||||||
var hourglass_cursor = load("res://hourglass_icon.png")
|
var hourglass_cursor = load("res://hourglass_icon.png")
|
||||||
|
var item_cursor: Texture2D = null
|
||||||
var previous_cursor_index: int = 0
|
var previous_cursor_index: int = 0
|
||||||
var is_script_running: bool = false
|
var is_script_running: bool = false
|
||||||
var is_cursor_locked: bool = false # When true, hourglass is shown and cursor can't be changed
|
var is_cursor_locked: bool = false # When true, hourglass is shown and cursor can't be changed
|
||||||
func get_scene() -> Scene:
|
func get_scene() -> Scene:
|
||||||
return $SceneViewport/background
|
return $SceneViewport/background
|
||||||
|
|
||||||
|
func get_current_room_name() -> String:
|
||||||
|
var scene = get_scene()
|
||||||
|
if scene and scene.get_script():
|
||||||
|
var script_path = scene.get_script().resource_path
|
||||||
|
if script_path.begins_with("res://scenes/"):
|
||||||
|
return script_path.trim_suffix(".gd").get_file()
|
||||||
|
return ""
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
# Called when the node enters the scene tree for the first time.
|
||||||
func _ready():
|
func _ready():
|
||||||
# get_scene().connect("transitioned", Callable($SceneViewport/label, "_on_transitioned"))
|
# get_scene().connect("transitioned", Callable($SceneViewport/label, "_on_transitioned"))
|
||||||
@@ -69,14 +78,46 @@ func set_script_cursor() -> void:
|
|||||||
func restore_cursor() -> void:
|
func restore_cursor() -> void:
|
||||||
is_script_running = false
|
is_script_running = false
|
||||||
is_cursor_locked = false # Unlock cursor
|
is_cursor_locked = false # Unlock cursor
|
||||||
|
if previous_cursor_index == ActionState.Action.ITEM:
|
||||||
|
if item_cursor:
|
||||||
|
Input.set_custom_mouse_cursor(item_cursor)
|
||||||
|
else:
|
||||||
|
Input.set_custom_mouse_cursor(cursors[ActionState.Action.WALK])
|
||||||
|
else:
|
||||||
Input.set_custom_mouse_cursor(cursors[previous_cursor_index])
|
Input.set_custom_mouse_cursor(cursors[previous_cursor_index])
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
func _unhandled_input(event: InputEvent) -> void:
|
||||||
$SceneViewport.push_input(event)
|
$SceneViewport.push_input(event)
|
||||||
|
|
||||||
|
func _on_backpack_show_overlay() -> void:
|
||||||
|
$InventoryOverlayLayer/InventoryOverlay.show_overlay()
|
||||||
|
|
||||||
|
func _on_backpack_hide_overlay() -> void:
|
||||||
|
$InventoryOverlayLayer/InventoryOverlay.hide_overlay()
|
||||||
|
|
||||||
|
func _on_overlay_item_confirmed(item_id: String) -> void:
|
||||||
|
InventoryManager.select_item(item_id)
|
||||||
|
var def = InventoryManager.get_item_definition(item_id)
|
||||||
|
if def and def.icon:
|
||||||
|
item_cursor = def.icon
|
||||||
|
Input.set_custom_mouse_cursor(item_cursor)
|
||||||
|
ActionState.current_action = ActionState.Action.ITEM
|
||||||
|
else:
|
||||||
|
Input.set_custom_mouse_cursor(cursors[ActionState.Action.WALK])
|
||||||
|
|
||||||
func _input(event):
|
func _input(event):
|
||||||
if event.is_action_released("quit"):
|
if event.is_action_released("quit"):
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
if event.is_action_released("right_click") and not is_cursor_locked:
|
if event.is_action_released("right_click") and not is_cursor_locked:
|
||||||
ActionState.current_action = (ActionState.current_action + 1) % 4
|
var prev_action = ActionState.current_action
|
||||||
Input.set_custom_mouse_cursor(cursors[ActionState.current_action], Input.CursorShape.CURSOR_ARROW, Vector2(64,64))
|
ActionState.current_action = (ActionState.current_action + 1) % 5
|
||||||
|
if ActionState.current_action == ActionState.Action.ITEM:
|
||||||
|
if InventoryManager.selected_item and item_cursor:
|
||||||
|
Input.set_custom_mouse_cursor(item_cursor, Input.CursorShape.CURSOR_ARROW, Vector2(0,0))
|
||||||
|
else:
|
||||||
|
ActionState.current_action = (ActionState.current_action + 1) % 5
|
||||||
|
Input.set_custom_mouse_cursor(cursors[ActionState.current_action], Input.CursorShape.CURSOR_ARROW, Vector2(0,0))
|
||||||
|
else:
|
||||||
|
if prev_action == ActionState.Action.ITEM:
|
||||||
|
InventoryManager.clear_selection()
|
||||||
|
Input.set_custom_mouse_cursor(cursors[ActionState.current_action], Input.CursorShape.CURSOR_ARROW, Vector2(0,0))
|
||||||
|
|||||||
44
Scene.gd
44
Scene.gd
@@ -129,6 +129,11 @@ func _unhandled_input(event):
|
|||||||
if ScriptBuilder.current_script.handle_input(event):
|
if ScriptBuilder.current_script.handle_input(event):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Block input when inventory overlay is active
|
||||||
|
var overlay = get_node_or_null("/root/Node2D/InventoryOverlay")
|
||||||
|
if overlay and overlay is InventoryOverlay and overlay.is_active():
|
||||||
|
return
|
||||||
|
|
||||||
var root = get_node("/root/Node2D")
|
var root = get_node("/root/Node2D")
|
||||||
# If look cursor is active and we got here, no SetPiece handled the input
|
# If look cursor is active and we got here, no SetPiece handled the input
|
||||||
# so this is a room-wide look
|
# so this is a room-wide look
|
||||||
@@ -138,7 +143,46 @@ func _unhandled_input(event):
|
|||||||
if ActionState.current_action == ActionState.Action.WALK:
|
if ActionState.current_action == ActionState.Action.WALK:
|
||||||
var path = NavigationServer2D.map_get_path(map, ego.position, pathfind.to_local(get_global_mouse_position()), true)
|
var path = NavigationServer2D.map_get_path(map, ego.position, pathfind.to_local(get_global_mouse_position()), true)
|
||||||
start_main_script(ScriptBuilder.init(ScriptBuilder.walk_path(ego, path)).can_interrupt().build(self, "_on_script_complete"))
|
start_main_script(ScriptBuilder.init(ScriptBuilder.walk_path(ego, path)).can_interrupt().build(self, "_on_script_complete"))
|
||||||
|
if ActionState.current_action == ActionState.Action.ITEM:
|
||||||
|
_on_item_use_in_world()
|
||||||
|
|
||||||
func _on_room_looked() -> void:
|
func _on_room_looked() -> void:
|
||||||
# Default room look description - override in room scripts
|
# Default room look description - override in room scripts
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
func _on_item_use_in_world() -> void:
|
||||||
|
if not InventoryManager.selected_item:
|
||||||
|
return
|
||||||
|
var item_id = InventoryManager.selected_item
|
||||||
|
var top_piece = ActionState.get_top_hovered_setpiece()
|
||||||
|
if top_piece:
|
||||||
|
_use_item_on_setpiece(item_id, top_piece)
|
||||||
|
else:
|
||||||
|
_on_item_used_empty_space(item_id)
|
||||||
|
|
||||||
|
func _use_item_on_setpiece(item_id: String, piece: SetPiece) -> void:
|
||||||
|
if piece.has_method("_on_item_used"):
|
||||||
|
piece._on_item_used(item_id)
|
||||||
|
else:
|
||||||
|
var def = InventoryManager.get_item_definition(item_id)
|
||||||
|
var item_name = item_id
|
||||||
|
if def:
|
||||||
|
item_name = def.name
|
||||||
|
var piece_name = piece.label if piece.label else piece.name
|
||||||
|
start_main_script(ScriptBuilder.init(ScriptBuilder.say(ego, "I can't use the %s on the %s." % [item_name, piece_name])).build(self, "_on_script_complete"))
|
||||||
|
|
||||||
|
func _on_item_used_empty_space(item_id: String) -> void:
|
||||||
|
var def = InventoryManager.get_item_definition(item_id)
|
||||||
|
var item_name = item_id
|
||||||
|
if def:
|
||||||
|
item_name = def.name
|
||||||
|
start_main_script(ScriptBuilder.init(ScriptBuilder.say(ego, "There's nothing to use the %s on here." % [item_name])).build(self, "_on_script_complete"))
|
||||||
|
|
||||||
|
func give_item(item_id: String) -> void:
|
||||||
|
InventoryManager.acquire_item(item_id)
|
||||||
|
|
||||||
|
func remove_item(item_id: String, quiet: bool = false) -> void:
|
||||||
|
InventoryManager.remove_item(item_id, quiet)
|
||||||
|
|
||||||
|
func strip_items(event_items: Array[String], exempt_items: Array[String] = []) -> void:
|
||||||
|
InventoryManager.bulk_strip_items(event_items, exempt_items)
|
||||||
|
|||||||
47
SetPiece_.gd
47
SetPiece_.gd
@@ -17,7 +17,8 @@ func _ready():
|
|||||||
notify_property_list_changed()
|
notify_property_list_changed()
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
hide()
|
pass
|
||||||
|
# hide()
|
||||||
pass # Replace with function body
|
pass # Replace with function body
|
||||||
|
|
||||||
|
|
||||||
@@ -40,6 +41,44 @@ signal exited(lab)
|
|||||||
points_resource = value
|
points_resource = value
|
||||||
_update_polygon_from_resource()
|
_update_polygon_from_resource()
|
||||||
|
|
||||||
|
func sample_polygon_point() -> Vector2:
|
||||||
|
if polygon.is_empty():
|
||||||
|
return position
|
||||||
|
var sum_x = 0.0
|
||||||
|
var sum_y = 0.0
|
||||||
|
for p in polygon:
|
||||||
|
sum_x += p.x
|
||||||
|
sum_y += p.y
|
||||||
|
return to_global(Vector2(sum_x / polygon.size(), sum_y / polygon.size()))
|
||||||
|
|
||||||
|
func get_screen_click_point() -> Vector2i:
|
||||||
|
var world_pt = sample_polygon_point()
|
||||||
|
var vp = get_viewport()
|
||||||
|
var screen_pt = vp.get_canvas_transform() * world_pt
|
||||||
|
return Vector2i(int(screen_pt.x), int(screen_pt.y))
|
||||||
|
|
||||||
|
func mock_interact(action = 0) -> void:
|
||||||
|
action = int(action)
|
||||||
|
var script_builder = get_node_or_null("/root/Node2D/GameScript")
|
||||||
|
if script_builder and script_builder.current_script and not script_builder.current_script.can_interrupt:
|
||||||
|
return
|
||||||
|
if interacted.get_connections().size() > 0:
|
||||||
|
emit_signal("interacted")
|
||||||
|
return
|
||||||
|
match action:
|
||||||
|
ActionState.Action.WALK:
|
||||||
|
if walked.get_connections().size() > 0:
|
||||||
|
emit_signal("walked")
|
||||||
|
ActionState.Action.LOOK:
|
||||||
|
if looked.get_connections().size() > 0:
|
||||||
|
emit_signal("looked")
|
||||||
|
ActionState.Action.TOUCH:
|
||||||
|
if touched.get_connections().size() > 0:
|
||||||
|
emit_signal("touched")
|
||||||
|
ActionState.Action.TALK:
|
||||||
|
if talked.get_connections().size() > 0:
|
||||||
|
emit_signal("talked")
|
||||||
|
|
||||||
func _input(event):
|
func _input(event):
|
||||||
if not Engine.is_editor_hint():
|
if not Engine.is_editor_hint():
|
||||||
if event is InputEventMouseButton and Input.is_action_just_released("interact"):
|
if event is InputEventMouseButton and Input.is_action_just_released("interact"):
|
||||||
@@ -74,3 +113,9 @@ func _input(event):
|
|||||||
ActionState.Action.TALK:
|
ActionState.Action.TALK:
|
||||||
if talked.get_connections().size() > 0:
|
if talked.get_connections().size() > 0:
|
||||||
emit_signal("talked")
|
emit_signal("talked")
|
||||||
|
ActionState.Action.ITEM:
|
||||||
|
if InventoryManager.selected_item:
|
||||||
|
var item_id = InventoryManager.selected_item
|
||||||
|
var scene = get_node_or_null("/root/Node2D/SceneViewport/background")
|
||||||
|
if scene and scene is Scene:
|
||||||
|
scene._use_item_on_setpiece(item_id, self)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ msdf_pixel_range=8
|
|||||||
msdf_size=48
|
msdf_size=48
|
||||||
allow_system_fallback=true
|
allow_system_fallback=true
|
||||||
force_autohinter=false
|
force_autohinter=false
|
||||||
|
modulate_color_glyphs=false
|
||||||
hinting=1
|
hinting=1
|
||||||
subpixel_positioning=1
|
subpixel_positioning=1
|
||||||
keep_rounding_remainders=true
|
keep_rounding_remainders=true
|
||||||
|
|||||||
Binary file not shown.
BIN
boot_icon.png
LFS
BIN
boot_icon.png
LFS
Binary file not shown.
@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/boot_icon.png-2296416b096145c4821e2741d23d2ff
|
|||||||
compress/mode=0
|
compress/mode=0
|
||||||
compress/high_quality=false
|
compress/high_quality=false
|
||||||
compress/lossy_quality=0.7
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
@@ -25,6 +27,10 @@ mipmaps/generate=false
|
|||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
process/fix_alpha_border=true
|
process/fix_alpha_border=true
|
||||||
process/premult_alpha=false
|
process/premult_alpha=false
|
||||||
process/normal_map_invert_y=false
|
process/normal_map_invert_y=false
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/boot_icon_big.png-68985c79f5e6cd0bab8b15bee07
|
|||||||
compress/mode=0
|
compress/mode=0
|
||||||
compress/high_quality=false
|
compress/high_quality=false
|
||||||
compress/lossy_quality=0.7
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
@@ -25,6 +27,10 @@ mipmaps/generate=false
|
|||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
process/fix_alpha_border=true
|
process/fix_alpha_border=true
|
||||||
process/premult_alpha=false
|
process/premult_alpha=false
|
||||||
process/normal_map_invert_y=false
|
process/normal_map_invert_y=false
|
||||||
|
|||||||
135
docs/code-review-pr3.md
Normal file
135
docs/code-review-pr3.md
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
## Code Review: PR 3 - "Stealth Cymbal"
|
||||||
|
|
||||||
|
### Scope
|
||||||
|
- **Branch:** stealth-cymbal
|
||||||
|
- **Base:** master
|
||||||
|
- **Files Changed:** 86 files (~1576 insertions, ~230 deletions)
|
||||||
|
- **Key Changes:** KQ4 Room Navigator skill, UID repair tools, MCP interaction server, room scene updates
|
||||||
|
|
||||||
|
### Review Team
|
||||||
|
- ✅ **ce-correctness-reviewer** - Logic errors, edge cases, state bugs
|
||||||
|
- ✅ **ce-testing-reviewer** - Coverage gaps, weak assertions, brittle tests
|
||||||
|
- ✅ **ce-maintainability-reviewer** - Coupling, complexity, naming, dead code
|
||||||
|
- ✅ **ce-project-standards-reviewer** - CLAUDE.md and AGENTS.md compliance
|
||||||
|
- ✅ **ce-agent-native-reviewer** - Agent-accessible design patterns
|
||||||
|
- ✅ **ce-learnings-researcher** - Past issues in docs/solutions/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### P1 -- High
|
||||||
|
|
||||||
|
| # | File | Issue | Reviewer | Confidence | Route |
|
||||||
|
|---|------|------|----------|------------|-------|
|
||||||
|
| 1 | `scenes/kq4_004_ogres_cottage/kq4_004_ogres_cottage.tscn:46` | UID mismatch - target UID for kq4_028_mine_entrance points to non-existent room | correctness | 75% | manual → downstream-resolver |
|
||||||
|
| 2 | `scripts/mcp_interaction_server.gd` | No runtime tests for 80+ TCP command handlers (171KB script) | testing | 50% | manual → downstream-resolver |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### P2 -- Moderate
|
||||||
|
|
||||||
|
| # | File | Issue | Reviewer | Confidence | Route |
|
||||||
|
|---|------|------|----------|------------|-------|
|
||||||
|
| 3 | `scenes/kq4_098_transitional_room/kq4_098_transitional_room.tscn` | Missing .uid companion file | correctness | 75% | manual → review-fixer |
|
||||||
|
| 4 | `scripts/build_room_graph.py:184` | `_resolve_target_room` returns None without explicit handling in callers | correctness | 75% | safe_auto → review-fixer |
|
||||||
|
| 5 | `tools/repair_uids.py:322` | Code duplication in fix_stale_target with inconsistent error handling | correctness | 75% | safe_auto → review-fixer |
|
||||||
|
| 6 | `tools/repair_uids.py` | No tests for file mutation operations (UID sync, target replacement) | testing | 75% | manual → downstream-resolver |
|
||||||
|
| 7 | `scripts/build_room_graph.py` | No tests for BFS edge cases (disconnected components, malformed UIDs) | testing | 75% | manual → downstream-resolver |
|
||||||
|
| 8 | `MainGame.gd`, `SetPiece_.gd` | No tests for signal emission logic and cursor action routing | testing | 50% | manual → downstream-resolver |
|
||||||
|
| 9 | `SetPiece_.gd:mock_interact()` | Unnecessary indirection - duplicates `_input()` logic | maintainability | 75% | gated_auto → downstream-resolver |
|
||||||
|
| 10 | `SetPiece_.gd` | Unused `entered/exited` signals with unclear `lab` param | maintainability | 75% | gated_auto → downstream-resolver |
|
||||||
|
| 11 | `tools/kq4_room_navigator.py` | sys.path manipulation creates coupling | maintainability | 50% | gated_auto → downstream-resolver |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### P3 -- Low
|
||||||
|
|
||||||
|
| # | File | Issue | Reviewer | Confidence | Route |
|
||||||
|
|---|------|------|----------|------------|-------|
|
||||||
|
| 12 | `MainGame.gd:13` | `get_current_room_name()` returns empty string on failure - silent failure mode | correctness | 50% | advisory → downstream-resolver |
|
||||||
|
| 13 | `scripts/mcp_interaction_server.gd:42` | Fixed 30-second timeout could mask real hangs | correctness | 50% | advisory → downstream-resolver |
|
||||||
|
| 14 | `SetPiece_.gd:60` | `mock_interact()` doesn't validate target room exists | correctness | 50% | advisory → downstream-resolver |
|
||||||
|
| 15 | `tools/kq4_room_navigator.py` | No tests for CLI tool | testing | 75% | advisory → human |
|
||||||
|
| 16 | `MainGame.gd` | Placeholder comment in `_ready()` - dead code | maintainability | 100% | advisory → human |
|
||||||
|
| 17 | `MainGame.gd` | Commented-out code with typo - dead code | maintainability | 100% | advisory → human |
|
||||||
|
| 18 | `scripts/mcp_interaction_server.gd` | Potentially incomplete implementation | maintainability | 50% | advisory → human |
|
||||||
|
| 19 | `.opencode/skills/kq4-room-navigator/SKILL.md:38-41` | Code block formatting changed from JSON to plain text | project-standards | 75% | advisory → human |
|
||||||
|
| 20 | `tools/kq4_room_navigator.py` | Dataclass overhead for Mismatch in CLI tool | maintainability | 50% | advisory → human |
|
||||||
|
| 21 | `.opencode/skills/kq4-room-navigator/SKILL.md` | Missing explicit retry guidance for `_busy` protocol | agent-native | 75% | advisory → human |
|
||||||
|
| 22 | `.opencode/skills/kq4-room-navigator/SKILL.md` | `mock_interact` vs `mock_interaction` typo in error messages | agent-native | 75% | safe_auto → review-fixer |
|
||||||
|
| 23 | `.opencode/skills/kq4-room-navigator/SKILL.md` | `--navigate` flag documented but not implemented in CLI | agent-native | 50% | gated_auto → downstream-resolver |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Requirements Completeness
|
||||||
|
**No plan document found** for this PR. The PR title "Stealth Cymbal" is ambiguous and doesn't reference a specific plan.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Pre-existing Issues
|
||||||
|
None identified in this review.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Learnings & Past Solutions
|
||||||
|
**No institutional learnings found.** The `docs/solutions/` directory does not exist in this repository. Consider using `/ce-compound` skill after significant work to document:
|
||||||
|
- UID generation patterns (make_uid.py + .uid files)
|
||||||
|
- Navigation/pathfinding setup (NavigationServer2D)
|
||||||
|
- MCP server integration learnings
|
||||||
|
- Room transition wiring patterns
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Agent-Native Gaps
|
||||||
|
1. **Offline-Only Graph Discovery** - Agents can't dynamically discover room connectivity at runtime
|
||||||
|
2. **Manual Verification** - Navigation completion requires polling instead of signals
|
||||||
|
3. **No Path Validation** - Agents can attempt invalid navigation without guardrails
|
||||||
|
4. **Incomplete CLI** - The `--navigate` flag is documented but not implemented
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Residual Risks
|
||||||
|
1. **UID mismatch risk** - Room graph connectivity depends on UID consistency across all .tscn and .uid files. If UIDs drift from manual edits, pathfinding will fail even though runtime transitions work.
|
||||||
|
- **Mitigation:** Run `tools/repair_uids.py --fix` before each significant room update. Consider integrating UID validation into CI pipeline.
|
||||||
|
|
||||||
|
2. **Timeout risk** - The MCP server's `_busy` flag uses a fixed 30-second timeout. If navigation animations or other operations take longer, commands may be prematurely reset.
|
||||||
|
- **Mitigation:** Monitor `_busy` timeout warnings in logs. Consider making configurable or implementing per-command timeout overrides.
|
||||||
|
|
||||||
|
3. **Arbitrary code execution** - MCP eval command allows arbitrary code execution without guardrails.
|
||||||
|
|
||||||
|
4. **Heuristic risk** - UID auto-resolution in repair_uids.py may produce incorrect fixes based on heuristics.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Testing Gaps
|
||||||
|
1. **No automated tests for UID consistency** across room transitions
|
||||||
|
2. **No tests for pathfinding edge cases** (disconnected rooms, single-room graphs, self-loops)
|
||||||
|
3. **No tests for MCP server command timeout** behavior under load
|
||||||
|
4. **No validation** that all TransitionPiece targets point to existing rooms
|
||||||
|
5. **No unit tests** for UID mismatch detection in repair_uids.py
|
||||||
|
6. **No tests** for BFS pathfinding edge cases in build_room_graph.py
|
||||||
|
7. **No tests** for SetPiece signal emission logic
|
||||||
|
8. **No tests** for busy-state timeout recovery in MCP server
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Coverage
|
||||||
|
- **Findings:** 23 total (2 P1, 9 P2, 12 P3)
|
||||||
|
- **Safe-auto (fixable now):** 3 findings
|
||||||
|
- **Manual (needs handoff):** 4 findings
|
||||||
|
- **Gated-auto (needs review):** 4 findings
|
||||||
|
- **Advisory (report-only):** 12 findings
|
||||||
|
- **Failed reviewers:** 0 of 6
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Verdict
|
||||||
|
**Ready with fixes**
|
||||||
|
|
||||||
|
**Fix order:**
|
||||||
|
1. **Critical:** Fix UID mismatch in kq4_004_ogres_cottage.tscn (finding #1) - this breaks navigation
|
||||||
|
2. **High:** Add missing .uid file for kq4_098_transitional_room (finding #3)
|
||||||
|
3. **Medium:** Fix None handling in build_room_graph.py (finding #4)
|
||||||
|
4. **Medium:** Consolidate code duplication in repair_uids.py (finding #5)
|
||||||
|
5. **Low:** Address dead code and formatting issues (findings #12-23)
|
||||||
|
|
||||||
|
**Before merge:** Run `tools/repair_uids.py --fix` to synchronize all UIDs and verify the UID mismatch is resolved.
|
||||||
546
docs/plans/2026-04-26-001-feat-inventory-backpack-system-plan.md
Normal file
546
docs/plans/2026-04-26-001-feat-inventory-backpack-system-plan.md
Normal file
@@ -0,0 +1,546 @@
|
|||||||
|
---
|
||||||
|
title: feat: Inventory and Backpack System
|
||||||
|
type: feat
|
||||||
|
status: active
|
||||||
|
date: 2026-04-26
|
||||||
|
origin: inventory-prd.md
|
||||||
|
---
|
||||||
|
|
||||||
|
# Inventory and Backpack System
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Add a full inventory and backpack system to the point-and-click adventure game: a global inventory manager, an animated HUD backpack icon with a finite state machine, a full-screen inventory overlay for item viewing and combination, and integration with the existing cursor and scene systems.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problem Frame
|
||||||
|
|
||||||
|
The game currently has no concept of items, inventory, or item interaction. Players cannot pick up objects, combine items, or use items on entities in the game world. This system establishes the foundational item management infrastructure needed for adventure game gameplay.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements Trace
|
||||||
|
|
||||||
|
- R1. Current inventory is an ordered list preserving insertion order (AC-1)
|
||||||
|
- R2. Obtained items set persists across removal (AC-1)
|
||||||
|
- R3. Stripped items vault for forced removal recovery (AC-9)
|
||||||
|
- R4. Item definitions include name, identifier, and optional combination category. Interaction handlers are signals emitted by items, not embedded data (PRD §2.2)
|
||||||
|
- R5. Inventory queries: has_item, has_obtained, has_any_of, has_obtained_any_of, has_obtained_all_of (PRD §2.3)
|
||||||
|
- R6. HUD Backpack FSM with Idle, Open, Selected, Acquire, Remove states. Multi-step transition queuing is deferred — transitions execute immediately and interrupt any in-flight animation (AC-2, PRD §4)
|
||||||
|
- R7. Inventory overlay with grid layout, hover text, drag-and-drop, item selection, and combination (AC-3 through AC-6, AC-12, AC-13, PRD §5)
|
||||||
|
- R8. Item acquisition animation and sound (AC-7, PRD §6)
|
||||||
|
- R9. Item removal animation with quiet mode and bulk removal support (AC-8, AC-9, PRD §7)
|
||||||
|
- R10. Cursor system integration with item-specific cursors (AC-10, AC-14, PRD §8)
|
||||||
|
- R11. Guard conditions: foreground action, screen fade, game pause (AC-11, PRD §9)
|
||||||
|
- R12. Game world item use: left-click entity interaction, right-click return (AC-10, PRD §10)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scope Boundaries
|
||||||
|
|
||||||
|
- Audio assets are not part of this system
|
||||||
|
- Item sprite assets are out of scope — use colored `ColorRect` boxes as placeholders for all item/backpack visuals
|
||||||
|
- Save/load persistence for inventory is deferred — the manager should be structured to support it, but serialization is not implemented
|
||||||
|
- Item tooltips beyond name and combination hints are deferred
|
||||||
|
- Multi-step transition queuing is deferred — transitions interrupt in-flight animations immediately
|
||||||
|
|
||||||
|
### Deferred to Follow-Up Work
|
||||||
|
|
||||||
|
- Inventory save/load serialization: separate PR once save system infrastructure exists
|
||||||
|
- Item sprite asset creation: replace colored boxes with actual sprites in a separate art pass
|
||||||
|
- Multi-step transition queuing: add FIFO queue for rapid transitions in a follow-up
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Context & Research
|
||||||
|
|
||||||
|
### Relevant Code and Patterns
|
||||||
|
|
||||||
|
- `ActionState.gd` — Existing autoload singleton tracking cursor action (WALK/LOOK/TOUCH/TALK). Pattern to follow for `InventoryManager` autoload.
|
||||||
|
- `MainGame.gd` — Root scene (`Game.tscn`) that handles cursor switching via `Input.set_custom_mouse_cursor()`, scene transitions, and script-running cursor lock. The inventory system must integrate here for cursor management and guard conditions.
|
||||||
|
- `GameScript.gd` — Script builder with `ScriptGraph` for cutscenes. The `Narrate` class shows the pattern for overlay fade-in/fade-out with `modulate.a` tweens, and the `is_script_running` / `is_cursor_locked` pattern in `MainGame.gd` is the guard condition model.
|
||||||
|
- `Scene.gd` — Base room class. `_unhandled_input()` handles walk and look actions. Inventory input must be gated so overlay blocks game-world input.
|
||||||
|
- `SetPiece_.gd` — Interactive polygon areas. The `_input()` pattern shows how `ActionState` and `GameScript.current_script` are checked before processing input.
|
||||||
|
- `Game.tscn` — Root scene tree with `SubViewport` for game world, `CanvasLayer` for overlays (NarratorOverlay at layer 10), and `AnimationPlayer` for fades.
|
||||||
|
- `label.gd` — Floating label that follows mouse position in game world coordinates.
|
||||||
|
|
||||||
|
### Institutional Learnings
|
||||||
|
|
||||||
|
- None yet — no `docs/solutions/` entries exist.
|
||||||
|
|
||||||
|
### External References
|
||||||
|
|
||||||
|
- PRD §13 provides detailed Godot 4 node architecture brainstorm, including FSM implementation options, drag-and-drop approach, cursor system, input priority patterns, and signal flow. The plan follows the PRD's recommended approaches throughout.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Technical Decisions
|
||||||
|
|
||||||
|
- **Hand-rolled FSM (PRD Option A)**: The backpack FSM uses a GDScript enum + Tween-based transitions, not `AnimationTree`. Transitions execute immediately and kill any in-flight animation — no FIFO queuing.
|
||||||
|
- **AutoLoad singleton for InventoryManager**: Follows the `ActionState` pattern. Signals (`item_acquired`, `item_removed`, `inventory_changed`) decouple the manager from UI components.
|
||||||
|
- **Signal-based interaction handlers**: Items emit signals for interactions rather than embedding interaction data in dictionaries. Room scenes connect to item signals to handle entity-specific behavior.
|
||||||
|
- **Item cursor as ActionState slot 5**: Item selection sets `ActionState.current_action = Action.ITEM` (slot 5). Right-click cycles WALK→LOOK→TOUCH→TALK→ITEM→WALK. The selected item is stored in `InventoryManager.selected_item`. Scripts and interactions fire the same way as regular cursor actions — item use is handled through the existing interaction signal pattern.
|
||||||
|
- **Raw `_gui_input()` for overlay drag-and-drop**: Godot's built-in drag-and-drop is a partial fit. Real-time cursor following, drag-out-close, and hover-under-drag tracking are more naturally handled with `InputEventMouseButton` and `InputEventMouseMotion` in `_gui_input()`.
|
||||||
|
- **Combined input priority defense**: Overlay background `ColorRect` with `MOUSE_FILTER_STOP` + `accept_event()` blocks Control input. Game world uses `_unhandled_input()` which is already filtered by Control `accept_event()`. An explicit `overlay_active` guard flag provides a safety net for `Node2D._input_event()` bypass. (PRD §13.10)
|
||||||
|
- **Colored boxes for placeholders**: All item sprites, backpack visuals, and cursor assets use colored `ColorRect` boxes instead of textures. Easy to replace with actual sprites later.
|
||||||
|
- **GridContainer for item grid**: Static layout uses Godot's `GridContainer`. During drag, items are reparented or switch to `PRESERVE_WIDE` anchors for free movement.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Open Questions
|
||||||
|
|
||||||
|
### Resolved During Planning
|
||||||
|
|
||||||
|
- **Should the inventory overlay live under MainGame or be a separate autoload?** Under `MainGame` as a child node in `Game.tscn`. It needs to interact with the scene's input and animation system, and keeping it in the scene tree simplifies lifecycle management.
|
||||||
|
- **How does the backpack FSM know about guard conditions?** The FSM checks `GameScript.current_script` (foreground action), the Fade sprite's `modulate.a` (screen fade), and a pause flag on `MainGame`. If a guard blocks opening, clicking the backpack attempts to skip the running action.
|
||||||
|
- **Where does item combination logic live?** In `InventoryManager` as `attempt_combine(item_a, item_b)`. The manager looks up interactions on both items (forward and reverse), evaluates dynamic rules, and emits `combination_succeeded` or `combination_refused` signals.
|
||||||
|
|
||||||
|
### Deferred to Implementation
|
||||||
|
|
||||||
|
- Exact animation frame counts for backpack open/close sprite sequences — depends on final sprite assets
|
||||||
|
- Whether `ItemDefinition` interaction handlers use a `Dictionary` or a callable-based registry — either works; the implementer should choose based on what feels cleaner with GDScript's type system
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Structure
|
||||||
|
|
||||||
|
res://
|
||||||
|
├── inventory/
|
||||||
|
│ ├── InventoryManager.gd # AutoLoad singleton
|
||||||
|
│ ├── InventoryManager.gd.uid
|
||||||
|
│ ├── ItemDefinition.gd # Custom Resource class
|
||||||
|
│ ├── ItemDefinition.gd.uid
|
||||||
|
│ ├── inventory_backpack/
|
||||||
|
│ │ ├── InventoryBackpack.tscn # HUD backpack FSM scene
|
||||||
|
│ │ ├── InventoryBackpack.tscn.uid
|
||||||
|
│ │ ├── InventoryBackpack.gd # FSM script
|
||||||
|
│ │ └── InventoryBackpack.gd.uid
|
||||||
|
│ └── inventory_overlay/
|
||||||
|
│ ├── InventoryOverlay.tscn # Full-screen overlay scene
|
||||||
|
│ ├── InventoryOverlay.tscn.uid
|
||||||
|
│ ├── InventoryOverlay.gd # Overlay interaction script
|
||||||
|
│ ├── InventoryOverlay.gd.uid
|
||||||
|
│ ├── InventorySlot.tscn # Single item slot scene
|
||||||
|
│ ├── InventorySlot.tscn.uid
|
||||||
|
│ ├── InventorySlot.gd # Slot behavior script
|
||||||
|
│ └── InventorySlot.gd.uid
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## High-Level Technical Design
|
||||||
|
|
||||||
|
> *This illustrates the intended approach and is directional guidance for review, not implementation specification. The implementing agent should treat it as context, not code to reproduce.*
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Game.tscn │
|
||||||
|
│ ┌─────────────────────────────────────────────────────────┐│
|
||||||
|
│ │ SceneViewport (SubViewport) ││
|
||||||
|
│ │ └── background (Scene) ││
|
||||||
|
│ │ └── game world entities ││
|
||||||
|
│ └─────────────────────────────────────────────────────────┘│
|
||||||
|
│ ┌─────────────────────────────────────────────────────────┐│
|
||||||
|
│ │ HUD (CanvasLayer, layer=5) ││
|
||||||
|
│ │ └── InventoryBackpack (FSM) ││
|
||||||
|
│ │ ├── AnimationPlayer (backpack sprites) ││
|
||||||
|
│ │ ├── ColorRect (backpack icon placeholder) ││
|
||||||
|
│ │ └── FloatingItem (selected item placeholder) ││
|
||||||
|
│ └─────────────────────────────────────────────────────────┘│
|
||||||
|
│ ┌─────────────────────────────────────────────────────────┐│
|
||||||
|
│ │ InventoryOverlay (CanvasLayer, layer=10) ││
|
||||||
|
│ │ ├── ColorRect (MOUSE_FILTER_STOP background) ││
|
||||||
|
│ │ └── InventoryPanel ││
|
||||||
|
│ │ ├── TextureRect (decorative frame) ││
|
||||||
|
│ │ ├── GridContainer (item grid) ││
|
||||||
|
│ │ │ └── InventorySlot × N (dynamic) ││
|
||||||
|
│ │ └── HoverLabel ││
|
||||||
|
│ └─────────────────────────────────────────────────────────┘│
|
||||||
|
│ │
|
||||||
|
│ InventoryManager (AutoLoad singleton) │
|
||||||
|
│ ├── inventory: Array[String] (ordered) │
|
||||||
|
│ ├── obtained_items: Dictionary (set) │
|
||||||
|
│ ├── stripped_items: Array[String] (ordered) │
|
||||||
|
│ ├── selected_item: String (currently held item) │
|
||||||
|
│ └── signals: item_acquired, item_removed, │
|
||||||
|
│ inventory_changed, combination_attempted │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Signal Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
InventoryManager
|
||||||
|
├─ item_acquired(item_id) → InventoryBackpack._on_item_acquired()
|
||||||
|
├─ item_removed(item_id) → InventoryBackpack._on_item_removed()
|
||||||
|
└─ inventory_changed → InventoryOverlay._refresh_grid()
|
||||||
|
|
||||||
|
InventoryBackpack (FSM)
|
||||||
|
├─ overlay_show_requested → InventoryOverlay.show()
|
||||||
|
├─ item_selected(item_def) → MainGame._on_item_selected()
|
||||||
|
│ (set ActionState.ITEM, store selected item)
|
||||||
|
└─ returning_to_idle → InventoryOverlay.hide()
|
||||||
|
|
||||||
|
InventoryOverlay
|
||||||
|
├─ close_requested → InventoryBackpack.transition_to(IDLE)
|
||||||
|
├─ combine_requested(a, b) → InventoryManager.attempt_combine(a, b)
|
||||||
|
└─ inspect_requested(item) → Scene.play_ego_script(item)
|
||||||
|
|
||||||
|
ActionState
|
||||||
|
├─ right-click cycles: WALK→LOOK→TOUCH→TALK→ITEM→WALK
|
||||||
|
└─ ITEM action triggers same interaction flow as other cursors
|
||||||
|
|
||||||
|
MainGame / Scene
|
||||||
|
├─ backpack_clicked → InventoryBackpack.transition_to(OPEN) (guarded)
|
||||||
|
├─ world_entity_clicked (ITEM) → entity receives item interaction signal
|
||||||
|
└─ right-click in world → cycles cursor (ITEM→WALK, returns item)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Units
|
||||||
|
|
||||||
|
- U1. **ItemDefinition Resource**
|
||||||
|
|
||||||
|
**Goal:** Define the data structure for inventory items as a Godot `Resource`.
|
||||||
|
|
||||||
|
**Requirements:** R4
|
||||||
|
|
||||||
|
**Dependencies:** None
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `inventory/ItemDefinition.gd`
|
||||||
|
- Create: `inventory/ItemDefinition.gd.uid`
|
||||||
|
|
||||||
|
**Approach:**
|
||||||
|
- Extend `Resource` with `class_name ItemDefinition`
|
||||||
|
- Fields: `id` (String, unique key), `name` (String), `combination_category` (String, optional)
|
||||||
|
- Signals emitted by items when interacted with: `item_used_on_entity(entity)`, `item_combined_with(other_item)`, `item_inspected()`. Room scenes connect to these signals to define entity-specific behavior.
|
||||||
|
- No embedded interaction data — all interaction logic lives in the scene scripts that receive the signals.
|
||||||
|
|
||||||
|
**Patterns to follow:**
|
||||||
|
- Godot `Resource` pattern for serializable data
|
||||||
|
- Existing `PolygonPointsResource.gd` as a simple example of a custom resource
|
||||||
|
|
||||||
|
**Test scenarios:**
|
||||||
|
- Happy path: Create ItemDefinition with id, name, and combination_category; verify fields are set correctly
|
||||||
|
- Edge case: Create ItemDefinition with no combination_category; verify it works as standalone item
|
||||||
|
- Edge case: Create ItemDefinition with empty name; verify id is still valid
|
||||||
|
|
||||||
|
**Verification:**
|
||||||
|
- Resource can be instantiated in code with all fields populated
|
||||||
|
- Resource can be saved as a `.tres` file and reloaded
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- U2. **InventoryManager AutoLoad Singleton**
|
||||||
|
|
||||||
|
**Goal:** Global inventory state management with signals, queries, and combination logic.
|
||||||
|
|
||||||
|
**Requirements:** R1, R2, R3, R5, R8
|
||||||
|
|
||||||
|
**Dependencies:** U1 (ItemDefinition)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `inventory/InventoryManager.gd`
|
||||||
|
- Create: `inventory/InventoryManager.gd.uid`
|
||||||
|
- Modify: `project.godot` (add autoload)
|
||||||
|
|
||||||
|
**Approach:**
|
||||||
|
- Extend `Node` with signals: `item_acquired(item_id: String)`, `item_removed(item_id: String)`, `inventory_changed`, `combination_attempted(item_a_id: String, item_b_id: String)`
|
||||||
|
- State: `inventory` (Array[String], ordered), `obtained_items` (Dictionary used as set), `stripped_items` (Array[String])
|
||||||
|
- Query methods: `has_item(item_id)`, `has_obtained(item_id)`, `has_any_of(item_ids)`, `has_obtained_any_of(item_ids)`, `has_obtained_all_of(item_ids)`
|
||||||
|
- Mutation methods: `acquire_item(item_id)`, `remove_item(item_id, quiet=false)`, `bulk_strip_items(event_items, exempt_items)` — moves stripped items to vault
|
||||||
|
- Combination logic: `attempt_combine(item_a_id, item_b_id)` emits `combination_attempted` signal. Room scripts or scene handlers connect to this signal to define what happens when two items are combined. No embedded combination data in the manager.
|
||||||
|
- Item definitions registry: `get_item_definition(item_id)` loads from a registry. Items are registered via `register_item(item_def: ItemDefinition)`
|
||||||
|
|
||||||
|
**Patterns to follow:**
|
||||||
|
- `ActionState.gd` for autoload singleton pattern with signals
|
||||||
|
- `GameScript.gd` Narrate class for overlay fade pattern (reference for how overlays interact with game state)
|
||||||
|
|
||||||
|
**Test scenarios:**
|
||||||
|
- Happy path: Acquire item → verify it's in inventory and obtained_items
|
||||||
|
- Happy path: Remove item → verify it's removed from inventory but stays in obtained_items
|
||||||
|
- Happy path: attempt_combine emits combination_attempted signal → connected handler receives both item IDs
|
||||||
|
- Edge case: Acquire already-owned item → item added to inventory again (duplicates allowed in current inventory)
|
||||||
|
- Edge case: Remove item not in inventory → no crash, no change
|
||||||
|
- Edge case: Query has_any_of with empty set → returns false
|
||||||
|
- Edge case: Query has_obtained_all_of with empty set → returns true
|
||||||
|
- Integration: acquire_item emits item_acquired signal → connected handler receives correct item_id
|
||||||
|
- Integration: remove_item emits item_removed signal → connected handler receives correct item_id
|
||||||
|
- Integration: bulk_strip_items moves items to vault, exempts protected items, leaves obtained_items untouched
|
||||||
|
|
||||||
|
**Verification:**
|
||||||
|
- AutoLoad registered in `project.godot` and accessible as `InventoryManager` from any scene
|
||||||
|
- All query methods return correct boolean values for various inventory states
|
||||||
|
- combination_attempted signal emits correct item pair to connected handlers
|
||||||
|
- Signal emissions are correct for acquire, remove, and combination events
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- U3. **HUD Backpack FSM**
|
||||||
|
|
||||||
|
**Goal:** Animated backpack icon with state machine for Idle, Open, Selected, Acquire, Remove states and multi-step queued transitions.
|
||||||
|
|
||||||
|
**Requirements:** R6, R7, R8, R9
|
||||||
|
|
||||||
|
**Dependencies:** U2 (InventoryManager)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `inventory/inventory_backpack/InventoryBackpack.tscn`
|
||||||
|
- Create: `inventory/inventory_backpack/InventoryBackpack.tscn.uid`
|
||||||
|
- Create: `inventory/inventory_backpack/InventoryBackpack.gd`
|
||||||
|
- Create: `inventory/inventory_backpack/InventoryBackpack.gd.uid`
|
||||||
|
- Create: `inventory/inventory_backpack/InventoryBackpack.tscn.uid`
|
||||||
|
|
||||||
|
**Approach:**
|
||||||
|
- Scene tree: `InventoryBackpack` (Control) → `AnimationPlayer`, `ColorRect` (backpack icon placeholder), `FloatingItem` (Control) → `ColorRect` (dynamic item placeholder)
|
||||||
|
- Anchored to top-right using Control anchors/offsets
|
||||||
|
- FSM enum: `IDLE`, `OPEN`, `SELECTED`, `ACQUIRE`, `REMOVE`
|
||||||
|
- Transitions execute immediately. No FIFO queuing — a new transition kills any in-flight tween and starts fresh.
|
||||||
|
- Each transition is a chain of `Tween` operations with `tween_callback()` for step completion. New `Tween` per transition (Godot 4 Tweens are not reusable).
|
||||||
|
- `kill_tween()` called on any active tween before starting a new transition
|
||||||
|
- `is_busy` flag prevents concurrent transitions but does NOT queue — new transitions during busy state are dropped or interrupt immediately.
|
||||||
|
- Item appearance animation primitive: `_animate_item(fade_dir, move_dir)` with parameters for show/hide and movement direction (out/none/in/far-out)
|
||||||
|
- Connect to `InventoryManager.item_acquired` and `InventoryManager.item_removed` signals
|
||||||
|
- Guard condition checks before `transition_to(OPEN)`: `GameScript.current_script` (foreground action), Fade sprite `modulate.a` (screen fade), pause flag
|
||||||
|
- If guard blocks open and foreground action is running, emit `skip_action_requested` signal
|
||||||
|
|
||||||
|
**Tween timing (from PRD §11.2):**
|
||||||
|
- Backpack rotation: linear, 0.35s
|
||||||
|
- Backpack position: ease-in, 0.35s
|
||||||
|
- Item appear/disappear: linear, 0.5s
|
||||||
|
|
||||||
|
**Patterns to follow:**
|
||||||
|
- PRD §13.2 (Option A: Hand-Rolled FSM) for FSM structure
|
||||||
|
- PRD §13.3 for Tween chaining with callbacks
|
||||||
|
- `Game.tscn` Fade animation pattern for reference on AnimationPlayer usage
|
||||||
|
|
||||||
|
**Test scenarios:**
|
||||||
|
- Happy path: Click backpack in Idle → transitions to Open, overlay shown
|
||||||
|
- Happy path: Acquire item in Idle → backpack opens, item appears and drops in, closes
|
||||||
|
- Happy path: Select item from overlay → transitions to Selected, floating item appears
|
||||||
|
- Happy path: Remove item in Idle → backpack opens, item appears and slides up, closes
|
||||||
|
- Edge case: Rapid transition requests → new transition interrupts in-flight animation immediately
|
||||||
|
- Edge case: Acquire item while Selected → replaces selected item with acquire animation
|
||||||
|
- Edge case: Remove selected item (same item) → item slides up and fades, clears selection
|
||||||
|
- Edge case: Remove different item while Selected → deselects current, shows removed item, slides up
|
||||||
|
- Edge case: Transition interrupted by new transition → old tween killed, new transition starts
|
||||||
|
- Integration: item_acquired signal from InventoryManager triggers Acquire animation
|
||||||
|
- Integration: item_removed signal from InventoryManager triggers Remove animation
|
||||||
|
- Integration: Guard condition blocks open when script running → skip_action_requested emitted
|
||||||
|
|
||||||
|
**Verification:**
|
||||||
|
- FSM starts in IDLE state
|
||||||
|
- All state transitions execute their multi-step animation sequences
|
||||||
|
- New transitions interrupt in-flight animations (no queuing)
|
||||||
|
- Tween objects are properly killed and recreated per transition
|
||||||
|
- Guard conditions prevent opening during foreground action, screen fade, or pause
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- U4. **Inventory Overlay Screen**
|
||||||
|
|
||||||
|
**Goal:** Full-screen overlay with item grid, hover text, drag-and-drop selection, and item combination.
|
||||||
|
|
||||||
|
**Requirements:** R7, R12
|
||||||
|
|
||||||
|
**Dependencies:** U2 (InventoryManager), U3 (InventoryBackpack)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `inventory/inventory_overlay/InventoryOverlay.tscn`
|
||||||
|
- Create: `inventory/inventory_overlay/InventoryOverlay.tscn.uid`
|
||||||
|
- Create: `inventory/inventory_overlay/InventoryOverlay.gd`
|
||||||
|
- Create: `inventory/inventory_overlay/InventoryOverlay.gd.uid`
|
||||||
|
- Create: `inventory/inventory_overlay/InventorySlot.tscn`
|
||||||
|
- Create: `inventory/inventory_overlay/InventorySlot.tscn.uid`
|
||||||
|
- Create: `inventory/inventory_overlay/InventorySlot.gd`
|
||||||
|
- Create: `inventory/inventory_overlay/InventorySlot.gd.uid`
|
||||||
|
|
||||||
|
**Approach:**
|
||||||
|
- Scene tree: `InventoryOverlay` (Control, full-screen) → `ColorRect` (background, `MOUSE_FILTER_STOP`), `InventoryPanel` (Control, centered) → `TextureRect` (frame), `GridContainer` (item grid), `HoverLabel` (Label)
|
||||||
|
- Overlay opacity controlled via `modulate.a` tweened for 0.2s fade-in/fade-out
|
||||||
|
- `input_active` boolean flag — only `true` when fully opaque (AC-12)
|
||||||
|
- `_gui_input()` handles all interaction:
|
||||||
|
- Hover: track mouse-over item, update hover label text
|
||||||
|
- Press: select item for drag
|
||||||
|
- Motion during press: move item sprite to follow cursor, track hover under dragged item
|
||||||
|
- Release on same item ≤0.5s: confirm selection, emit `item_confirmed`, close
|
||||||
|
- Release on same item >0.5s: deselect (long-press cancel), stay open
|
||||||
|
- Release on different item: emit `combine_requested(a, b)` to InventoryManager
|
||||||
|
- Right-click on item: emit `inspect_requested(item)`, close
|
||||||
|
- Release on empty space: close
|
||||||
|
- Drag outside panel bounds: close immediately, discard selection
|
||||||
|
- `InventorySlot` is a lightweight Control with a `ColorRect` child (colored box placeholder), `custom_minimum_size` for cell dimensions, and hover highlight modulate
|
||||||
|
- `_refresh_grid()` called on `inventory_changed` signal: clears grid, instantiates `InventorySlot` for each item in `InventoryManager.inventory`
|
||||||
|
- Combination result handling: on `combination_succeeded`, grid refreshes automatically via signal. On `combination_refused`, show message via `GameScript.narrate()` or dialogue system.
|
||||||
|
|
||||||
|
**Patterns to follow:**
|
||||||
|
- `GameScript.gd` Narrate class for overlay fade pattern
|
||||||
|
- `Game.tscn` NarratorOverlay for CanvasLayer overlay pattern
|
||||||
|
- PRD §13.4 for Control hierarchy and drag-and-drop approach
|
||||||
|
|
||||||
|
**Test scenarios:**
|
||||||
|
- Happy path: Open overlay → items displayed in grid, left-to-right, top-to-bottom
|
||||||
|
- Happy path: Hover item with no selection → hover label shows item name
|
||||||
|
- Happy path: Select item A, hover item B → hover label shows "Use A with B"
|
||||||
|
- Happy path: Short-click item → item confirmed, overlay closes
|
||||||
|
- Happy path: Drag item A onto item B → combination attempted
|
||||||
|
- Happy path: Right-click item → inspect dialogue played, overlay closes
|
||||||
|
- Happy path: Click empty space → overlay closes, selection cleared
|
||||||
|
- Edge case: Long-press release (>0.5s) on item → deselected, overlay stays open
|
||||||
|
- Edge case: Drag item outside panel bounds → overlay closes, selection discarded
|
||||||
|
- Edge case: Overlay during fade-in → renders but doesn't accept input
|
||||||
|
- Edge case: Overlay during fade-out → renders but doesn't accept input
|
||||||
|
- Edge case: Empty inventory → grid shows no items
|
||||||
|
- Error path: Combine items with no interaction → refusal message shown
|
||||||
|
- Integration: inventory_changed signal refreshes grid with new items
|
||||||
|
- Integration: combine_requested signal sent to InventoryManager with correct item pair
|
||||||
|
- Integration: Hover text tracks item under dragged item during drag
|
||||||
|
|
||||||
|
**Verification:**
|
||||||
|
- Overlay fades in/out with correct timing
|
||||||
|
- Grid layout respects fixed maximum items per row
|
||||||
|
- All interaction outcomes match PRD §5.4 table
|
||||||
|
- Input is blocked during fade transitions
|
||||||
|
- Drag-out escape closes overlay and discards selection
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- U5. **MainGame Integration — Cursor, Guards, World Item Use**
|
||||||
|
|
||||||
|
**Goal:** Integrate inventory system with existing cursor management, guard conditions, and game world item interaction.
|
||||||
|
|
||||||
|
**Requirements:** R10, R11, R12
|
||||||
|
|
||||||
|
**Dependencies:** U2 (InventoryManager), U3 (InventoryBackpack), U4 (InventoryOverlay)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `MainGame.gd`
|
||||||
|
- Modify: `Game.tscn`
|
||||||
|
- Modify: `Scene.gd`
|
||||||
|
|
||||||
|
**Approach:**
|
||||||
|
- **Game.tscn changes:** Add `InventoryBackpack` and `InventoryOverlay` as children of `Node2D` (MainGame), under separate `CanvasLayer` nodes at appropriate layers. Backpack at layer 5 (HUD), overlay at layer 10 (full-screen).
|
||||||
|
- **ActionState.gd changes:**
|
||||||
|
- Add `ITEM` as the 5th action (value 4): `WALK=0`, `LOOK=1`, `TOUCH=2`, `TALK=3`, `ITEM=4`
|
||||||
|
- Right-click cycling logic updated: cycles through 0→1→2→3→4→0
|
||||||
|
- When cycling to ITEM, the cursor uses the selected item's colored box as cursor (placeholder)
|
||||||
|
- **MainGame.gd changes:**
|
||||||
|
- `_on_item_selected(item_def)`: Store item in `InventoryManager.selected_item`, set `ActionState.current_action = ActionState.Action.ITEM`
|
||||||
|
- Guard conditions: `can_open_inventory()` checks `GameScript.current_script` (foreground action), Fade `modulate.a` (screen fade), and pause state
|
||||||
|
- World item use: When `ActionState.current_action == Action.ITEM` and player left-clicks in game world, emit item's interaction signal for the clicked entity. If no entity clicked, show item's self-description.
|
||||||
|
- Right-click in game world with item selected → cycles cursor to next action (ITEM→WALK), effectively returning item to backpack
|
||||||
|
- Input routing: Ensure `_unhandled_input()` in `Scene.gd` checks `InventoryOverlay.input_active` before processing game-world clicks
|
||||||
|
- **Scene.gd changes:**
|
||||||
|
- Add guard in `_unhandled_input()`: if `InventoryOverlay` is active, return early
|
||||||
|
- When `ActionState.current_action == Action.ITEM`, pass selected item to clicked entity's interaction handler via signal
|
||||||
|
|
||||||
|
**Patterns to follow:**
|
||||||
|
- `ActionState.gd` for cursor action enum and cycling pattern
|
||||||
|
- `MainGame.gd` `_on_input_action()` for right-click cycling integration
|
||||||
|
- `Scene.gd` `_unhandled_input()` for input handling
|
||||||
|
- `SetPiece_.gd` for entity interaction pattern
|
||||||
|
- PRD §13.10 recommended combined input priority approach
|
||||||
|
|
||||||
|
**Test scenarios:**
|
||||||
|
- Happy path: Item selected from overlay → ActionState set to ITEM, item stored in InventoryManager
|
||||||
|
- Happy path: Right-click in world with ITEM active → cursor cycles to WALK, item returned
|
||||||
|
- Happy path: Left-click entity with ITEM active → entity receives item interaction signal
|
||||||
|
- Happy path: Left-click empty space with ITEM active → item self-description shown
|
||||||
|
- Edge case: Click backpack while script running → skip action attempted, inventory doesn't open
|
||||||
|
- Edge case: Click backpack during screen fade → inventory doesn't open
|
||||||
|
- Edge case: Inventory overlay active → game world input is suppressed
|
||||||
|
- Edge case: Entity has no handler for selected item → generic "nothing to do" message
|
||||||
|
- Integration: InventoryBackpack guard check returns false when foreground action running
|
||||||
|
- Integration: Scene._unhandled_input returns early when overlay is active
|
||||||
|
- Integration: Right-click cycling includes ITEM state (WALK→LOOK→TOUCH→TALK→ITEM→WALK)
|
||||||
|
|
||||||
|
**Verification:**
|
||||||
|
- ActionState includes ITEM as value 4, right-click cycles through all 5 states
|
||||||
|
- Guard conditions prevent inventory from opening during foreground action, screen fade, or pause
|
||||||
|
- Game world input is properly suppressed when overlay is active
|
||||||
|
- Item use triggers entity interaction signals when ActionState is ITEM
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- U6. **Scene Integration Hooks — Acquisition and Removal**
|
||||||
|
|
||||||
|
**Goal:** Provide hooks for room scenes to acquire and remove items, with proper signal propagation and animation triggering.
|
||||||
|
|
||||||
|
**Requirements:** R6, R7, R8, R9
|
||||||
|
|
||||||
|
**Dependencies:** U2 (InventoryManager), U3 (InventoryBackpack)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `Scene.gd` (add helper methods)
|
||||||
|
- Modify: `scenes/kq4_placeholder_template/kq4_placeholder_template.gd` (example usage)
|
||||||
|
|
||||||
|
**Approach:**
|
||||||
|
- Add helper methods to `Scene.gd` (or as static utilities accessible from any scene):
|
||||||
|
- `give_item(item_id)`: Calls `InventoryManager.acquire_item(item_id)`. The manager emits `item_acquired` which triggers the backpack's Acquire animation.
|
||||||
|
- `remove_item(item_id, quiet=false)`: Calls `InventoryManager.remove_item(item_id, quiet)`. The manager emits `item_removed` which triggers the backpack's Remove animation (unless quiet).
|
||||||
|
- `strip_items(event_items, exempt_items)`: Calls `InventoryManager.bulk_strip_items()`. Stripped items go to vault.
|
||||||
|
- `use_item_on_entity(item_id, entity)`: Checks if entity has an interaction handler for the item. If yes, executes it. If no, shows generic refusal.
|
||||||
|
- Room scripts can call these helpers from SetPiece signal handlers or GameScript steps.
|
||||||
|
- Add a `GameScript` step class for item acquisition: `GiveItem` step that plays dialogue, acquires the item, and triggers the animation.
|
||||||
|
- Example usage in placeholder template: show how a SetPiece `touched` signal handler calls `give_item()`.
|
||||||
|
|
||||||
|
**Patterns to follow:**
|
||||||
|
- `GameScript.gd` `Say` and `Narrate` classes for new `GiveItem` step
|
||||||
|
- `Scene.gd` `start_main_script` for script-based item acquisition
|
||||||
|
- `TransitionPiece.gd` for how room scripts interact with global systems
|
||||||
|
|
||||||
|
**Test scenarios:**
|
||||||
|
- Happy path: SetPiece touched → give_item called → item in inventory, backpack Acquire animation plays
|
||||||
|
- Happy path: Combination consumes item → remove_item called → item removed from inventory, backpack Remove animation plays
|
||||||
|
- Edge case: Quiet removal → item removed from inventory, no backpack animation
|
||||||
|
- Edge case: Give item while another item selected → selected item display replaced with new item
|
||||||
|
- Integration: give_item triggers InventoryManager.acquire_item → signal propagates to InventoryBackpack → Acquire animation starts
|
||||||
|
- Integration: bulk_strip_items moves items to vault, exempt items stay in inventory
|
||||||
|
|
||||||
|
**Verification:**
|
||||||
|
- Room scripts can call `give_item()` and `remove_item()` from signal handlers
|
||||||
|
- Item acquisition triggers proper backpack animation via signal chain
|
||||||
|
- Item removal respects quiet flag
|
||||||
|
- Bulk strip moves items to vault and exempts protected items
|
||||||
|
- `GiveItem` GameScript step integrates with existing script builder pattern
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## System-Wide Impact
|
||||||
|
|
||||||
|
- **Interaction graph:** `InventoryManager` signals connect to `InventoryBackpack` (animations), `InventoryOverlay` (grid refresh), and `MainGame` (cursor management). `InventoryBackpack` signals connect to `InventoryOverlay` (show/hide). `InventoryOverlay` signals connect back to `InventoryManager` (combination) and `InventoryBackpack` (close). The signal loop is: Manager → Backpack → Overlay → Manager.
|
||||||
|
- **Error propagation:** Combination refusals propagate as `combination_refused` signal with message, handled by the overlay or scene's dialogue system. Invalid item IDs should be guarded with `push_warning()`.
|
||||||
|
- **State lifecycle risks:** The FSM's transition queue must handle rapid state changes correctly. If the backpack node is freed during a transition, `bind_node(self)` on Tweens ensures they die cleanly. The overlay's `input_active` flag must be set/cleared at exact fade boundaries to avoid the "input black hole" problem.
|
||||||
|
- **API surface parity:** The existing `ActionState` cursor actions (WALK/LOOK/TOUCH/TALK) continue to work normally when no item is selected. When an item is selected, the walk cursor effectively becomes "use item" — this is a behavioral override, not a change to `ActionState` itself.
|
||||||
|
- **Integration coverage:** The full signal chain from `InventoryManager.acquire_item()` → backpack Acquire animation → FSM returning to Idle must work as an integration scenario that mocks alone won't prove. Similarly, the overlay combination flow: click A → click B → `attempt_combine()` → `combination_succeeded` → items removed/added → grid refreshes → overlay closes.
|
||||||
|
- **Unchanged invariants:** The existing cursor cycling (right-click cycles WALK/LOOK/TOUCH/TALK) is unchanged. The `ActionState` autoload is unchanged. The `GameScript` system continues to work for cutscenes — the new `GiveItem` step extends it without modifying existing steps.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Risks & Dependencies
|
||||||
|
|
||||||
|
| Risk | Mitigation |
|
||||||
|
|------|-----------|
|
||||||
|
| Tween lifecycle bugs: FSM transitions interrupted mid-animation leave visual state inconsistent | Always `kill()` active tween before starting new transition. Use `bind_node(self)` to auto-clean on node free. |
|
||||||
|
| Input black hole during overlay fade transitions | `input_active` flag toggled at exact fade boundaries. Overlay blocks input from fade-start through fade-end. Game world regains input only after fade-out completes. |
|
||||||
|
| Node2D vs Control input gap: overlay `accept_event()` doesn't suppress `Node2D._input_event()` | Combined defense: `MOUSE_FILTER_STOP` background + `_unhandled_input()` gate in Scene + explicit `overlay_active` guard flag checked by game world. |
|
||||||
|
| GridContainer limitations during drag: item reparenting causes layout flicker | Test drag behavior early. If GridContainer causes issues, switch to manual grid positioning in a custom Control. |
|
||||||
|
| Combination logic complexity: dynamic rules, prerequisites, order guards | Start with static dictionary lookups (forward + reverse). Add dynamic category rules and guards as separate methods that can be extended per item. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Documentation / Operational Notes
|
||||||
|
|
||||||
|
- Item definitions (`.tres` files) should be placed in a dedicated `inventory/items/` directory when they are created
|
||||||
|
- The `InventoryManager` autoload should be documented in a brief comment at the top of its file, listing all signals and public methods
|
||||||
|
- No CLAUDE.md or AGENTS.md updates needed — the inventory system follows existing patterns (autoload singletons, scene hierarchy, signal-based communication)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sources & References
|
||||||
|
|
||||||
|
- **Origin document:** [inventory-prd.md](inventory-prd.md)
|
||||||
|
- Existing code: `ActionState.gd`, `MainGame.gd`, `GameScript.gd`, `Scene.gd`, `SetPiece_.gd`, `Game.tscn`
|
||||||
|
- Godot 4.6 docs: `Tween`, `Control`, `Resource`, `CanvasLayer`, `Input.create_custom_cursor()`
|
||||||
@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/dragon.png-cd3ff3eaa8e7e24c15781ff6b9940064.c
|
|||||||
compress/mode=0
|
compress/mode=0
|
||||||
compress/high_quality=false
|
compress/high_quality=false
|
||||||
compress/lossy_quality=0.7
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
@@ -25,6 +27,10 @@ mipmaps/generate=false
|
|||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
process/fix_alpha_border=true
|
process/fix_alpha_border=true
|
||||||
process/premult_alpha=false
|
process/premult_alpha=false
|
||||||
process/normal_map_invert_y=false
|
process/normal_map_invert_y=false
|
||||||
|
|||||||
BIN
ego/animations/walk6/e/image/frame_0000.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0000.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0000.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0000.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bvrsr0b55pbou"
|
||||||
|
path="res://.godot/imported/frame_0000.png-b2da7ec48320b00652e5e34531b24409.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0000.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0000.png-b2da7ec48320b00652e5e34531b24409.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0001.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0001.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0001.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0001.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bewoslpmmowgr"
|
||||||
|
path="res://.godot/imported/frame_0001.png-13d8d4ff8fb7e4f1132c1070be1eab98.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0001.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0001.png-13d8d4ff8fb7e4f1132c1070be1eab98.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0002.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0002.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0002.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0002.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://b105ixtjlaemw"
|
||||||
|
path="res://.godot/imported/frame_0002.png-364696f5f255c004f638316c22cbe8fa.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0002.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0002.png-364696f5f255c004f638316c22cbe8fa.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0003.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0003.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0003.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0003.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dj5qqu1i60t8b"
|
||||||
|
path="res://.godot/imported/frame_0003.png-6c0016aab5739010b300d4aadf445275.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0003.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0003.png-6c0016aab5739010b300d4aadf445275.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0004.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0004.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0004.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0004.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bv6a6vt0q5luo"
|
||||||
|
path="res://.godot/imported/frame_0004.png-b620093ddbdd80ff6a65a6517f9c14b4.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0004.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0004.png-b620093ddbdd80ff6a65a6517f9c14b4.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0005.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0005.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0005.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0005.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://clrk60e8f6cto"
|
||||||
|
path="res://.godot/imported/frame_0005.png-b6c300fc202006f2fb177a3a1c513665.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0005.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0005.png-b6c300fc202006f2fb177a3a1c513665.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0006.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0006.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0006.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0006.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://hgah784brj1u"
|
||||||
|
path="res://.godot/imported/frame_0006.png-28c4b801c2546155230011f559169b9f.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0006.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0006.png-28c4b801c2546155230011f559169b9f.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0007.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0007.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0007.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0007.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dvct6l2bs4xfo"
|
||||||
|
path="res://.godot/imported/frame_0007.png-e422307b7496aacb187385bfb8795443.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0007.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0007.png-e422307b7496aacb187385bfb8795443.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0008.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0008.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0008.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0008.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://73p11ya60fhx"
|
||||||
|
path="res://.godot/imported/frame_0008.png-d5499d6e4b8d3a3eb3ad718c0335a962.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0008.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0008.png-d5499d6e4b8d3a3eb3ad718c0335a962.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0009.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0009.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0009.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0009.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://b25stwboh3o6a"
|
||||||
|
path="res://.godot/imported/frame_0009.png-8e46c04cda201e73d3528324b56e66f3.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0009.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0009.png-8e46c04cda201e73d3528324b56e66f3.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0010.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0010.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0010.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0010.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://elkyn3cmg0c2"
|
||||||
|
path="res://.godot/imported/frame_0010.png-de90a31a250647c0d5aee9a41a0b0d8c.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0010.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0010.png-de90a31a250647c0d5aee9a41a0b0d8c.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0011.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0011.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0011.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0011.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://djgn51fdby287"
|
||||||
|
path="res://.godot/imported/frame_0011.png-bbc6c99728b46e3dd8887280c9381c78.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0011.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0011.png-bbc6c99728b46e3dd8887280c9381c78.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0012.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0012.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0012.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0012.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dlbpbe6s4l1tx"
|
||||||
|
path="res://.godot/imported/frame_0012.png-f5e74974717ec212928272d323393a98.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0012.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0012.png-f5e74974717ec212928272d323393a98.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0013.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0013.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0013.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0013.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://wrn8804ysm1r"
|
||||||
|
path="res://.godot/imported/frame_0013.png-675289ff80b3e47f5fd61784ae292a76.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0013.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0013.png-675289ff80b3e47f5fd61784ae292a76.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0014.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0014.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0014.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0014.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dfknsguku55ft"
|
||||||
|
path="res://.godot/imported/frame_0014.png-9424e4272c40efeb633b65529357249a.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0014.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0014.png-9424e4272c40efeb633b65529357249a.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0015.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0015.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0015.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0015.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://o55311qur6ux"
|
||||||
|
path="res://.godot/imported/frame_0015.png-489fcfbbd3c4f4cda18e47e3dc8dcf15.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0015.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0015.png-489fcfbbd3c4f4cda18e47e3dc8dcf15.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0016.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0016.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0016.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0016.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://m5u07s02h2wm"
|
||||||
|
path="res://.godot/imported/frame_0016.png-7e03f5a0902e0df237c1d79afaef6581.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0016.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0016.png-7e03f5a0902e0df237c1d79afaef6581.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0017.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0017.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0017.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0017.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bybcqiuogapnj"
|
||||||
|
path="res://.godot/imported/frame_0017.png-2336272caeba6f1dc162cd5dfb7598a6.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0017.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0017.png-2336272caeba6f1dc162cd5dfb7598a6.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0018.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0018.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0018.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0018.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dsipxnabk7nf2"
|
||||||
|
path="res://.godot/imported/frame_0018.png-c0ef7360e08db6fe8ef11fac3e141ea7.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0018.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0018.png-c0ef7360e08db6fe8ef11fac3e141ea7.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0019.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0019.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0019.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0019.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://b178tkevj6xh6"
|
||||||
|
path="res://.godot/imported/frame_0019.png-c2ed177013a1787ee432d716372087d1.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0019.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0019.png-c2ed177013a1787ee432d716372087d1.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0020.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0020.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0020.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0020.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://buuy33224yxhk"
|
||||||
|
path="res://.godot/imported/frame_0020.png-873c63b937324b14e6038a8f66bd563c.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0020.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0020.png-873c63b937324b14e6038a8f66bd563c.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0021.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0021.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0021.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0021.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://2heg200vpyij"
|
||||||
|
path="res://.godot/imported/frame_0021.png-4b55ce999ff41efe5ba3479ebe6ea3d2.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0021.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0021.png-4b55ce999ff41efe5ba3479ebe6ea3d2.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0022.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0022.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0022.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0022.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cil7ci431vr5c"
|
||||||
|
path="res://.godot/imported/frame_0022.png-47bfede447f05f1f520b78e62d93dd2d.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0022.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0022.png-47bfede447f05f1f520b78e62d93dd2d.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0023.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0023.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0023.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0023.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cf11hpy3jxmpf"
|
||||||
|
path="res://.godot/imported/frame_0023.png-6d5ab9b27a44431b93f81160aebd8883.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0023.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0023.png-6d5ab9b27a44431b93f81160aebd8883.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0024.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0024.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0024.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0024.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cakxolxtw5evq"
|
||||||
|
path="res://.godot/imported/frame_0024.png-e59119e54e73aed9da9116e74406c80a.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0024.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0024.png-e59119e54e73aed9da9116e74406c80a.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0025.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0025.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0025.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0025.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bshdhlsdu14nf"
|
||||||
|
path="res://.godot/imported/frame_0025.png-50c986c14484b1cb5e21d6081146073c.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0025.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0025.png-50c986c14484b1cb5e21d6081146073c.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0026.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0026.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0026.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0026.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://b12pqmrqkvvu4"
|
||||||
|
path="res://.godot/imported/frame_0026.png-a4ee4c6c8b4d95c3237f600469f31f83.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0026.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0026.png-a4ee4c6c8b4d95c3237f600469f31f83.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0027.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0027.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0027.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0027.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dkeuwc65l7610"
|
||||||
|
path="res://.godot/imported/frame_0027.png-be673ffe43ad0354e9248e401e495bda.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0027.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0027.png-be673ffe43ad0354e9248e401e495bda.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0028.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0028.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0028.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0028.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dh14dji4fio5i"
|
||||||
|
path="res://.godot/imported/frame_0028.png-4083bef9dafc3551bb7858101d5baa62.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0028.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0028.png-4083bef9dafc3551bb7858101d5baa62.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0029.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0029.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0029.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0029.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dsirxkxfyujpq"
|
||||||
|
path="res://.godot/imported/frame_0029.png-8e0c6cb312722c7b1b2ab9ad39faf599.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0029.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0029.png-8e0c6cb312722c7b1b2ab9ad39faf599.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0030.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0030.png
LFS
Normal file
Binary file not shown.
40
ego/animations/walk6/e/image/frame_0030.png.import
Normal file
40
ego/animations/walk6/e/image/frame_0030.png.import
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cr221lb5mbjqx"
|
||||||
|
path="res://.godot/imported/frame_0030.png-73514f0085b41c6690929bb1c0bec043.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://ego/animations/walk6/e/image/frame_0030.png"
|
||||||
|
dest_files=["res://.godot/imported/frame_0030.png-73514f0085b41c6690929bb1c0bec043.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
ego/animations/walk6/e/image/frame_0031.png
LFS
Normal file
BIN
ego/animations/walk6/e/image/frame_0031.png
LFS
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user