Compare commits
1 Commits
feature/wh
...
ui-assets
| Author | SHA1 | Date | |
|---|---|---|---|
| 91c8b1b062 |
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"permissions": {
|
|
||||||
"allow": [
|
|
||||||
"Skill(whaletown-developer)"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,335 +0,0 @@
|
|||||||
---
|
|
||||||
name: whaletown-developer
|
|
||||||
description: Automate WhaleTown project's standard development workflow. Use this skill when implementing features, fixing bugs, creating scenes, or any code development tasks. Guides through 7-step process - architecture analysis, implementation, comment/naming validation, testing, and Git commit generation following project conventions.
|
|
||||||
---
|
|
||||||
|
|
||||||
# WhaleTown Standard Development Workflow Skill
|
|
||||||
|
|
||||||
This skill automates the standard development workflow for the WhaleTown project, ensuring all developers follow unified specifications and quality standards.
|
|
||||||
|
|
||||||
## When to Use This Skill
|
|
||||||
|
|
||||||
Activate this skill when:
|
|
||||||
- Implementing new features ("实现XX功能", "添加XX系统")
|
|
||||||
- Fixing bugs ("修复XX Bug", "解决XX问题")
|
|
||||||
- Creating scenes ("创建XX场景", "设计XX界面")
|
|
||||||
- Developing modules ("开发XX模块", "构建XX组件")
|
|
||||||
- Any code development task requiring adherence to project standards
|
|
||||||
|
|
||||||
## Development Workflow Overview
|
|
||||||
|
|
||||||
```
|
|
||||||
Step 1: Architecture Analysis (读取架构规范)
|
|
||||||
↓
|
|
||||||
Step 2: Implementation (按规范编码)
|
|
||||||
↓
|
|
||||||
Step 3: Comment Validation (注释规范检查)
|
|
||||||
↓
|
|
||||||
Step 4: Naming Validation (命名规范检查)
|
|
||||||
↓
|
|
||||||
Step 5: Test Writing (编写测试代码)
|
|
||||||
↓
|
|
||||||
Step 6: Test Execution (运行测试验证)
|
|
||||||
↓
|
|
||||||
Step 7: Git Commit (生成规范提交信息)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step-by-Step Workflow
|
|
||||||
|
|
||||||
### Step 1: Architecture Analysis
|
|
||||||
|
|
||||||
Read and apply the architecture specifications before implementation.
|
|
||||||
|
|
||||||
**Actions:**
|
|
||||||
1. Read `docs/02-开发规范/架构与通信规范.md`
|
|
||||||
2. Determine file location based on feature type:
|
|
||||||
- Core systems → `_Core/managers/` or `_Core/systems/`
|
|
||||||
- Game scenes → `scenes/Maps/`, `scenes/Entities/`, `scenes/Components/`
|
|
||||||
- UI components → `scenes/ui/`
|
|
||||||
3. Identify communication method (MUST use EventSystem for cross-module communication)
|
|
||||||
4. List dependencies (required managers and systems)
|
|
||||||
5. Design event definitions (add to `_Core/EventNames.gd`)
|
|
||||||
|
|
||||||
**Layered Architecture:**
|
|
||||||
```
|
|
||||||
UI Layer (界面层) → scenes/ui/
|
|
||||||
↑
|
|
||||||
Scenes Layer (游戏层) → scenes/Maps/, scenes/Entities/
|
|
||||||
↑
|
|
||||||
_Core Layer (框架层) → _Core/managers/, _Core/systems/
|
|
||||||
```
|
|
||||||
|
|
||||||
**Communication Principle:** "Signal Up, Call Down"
|
|
||||||
- Parents call child methods (downward calls)
|
|
||||||
- Children emit signals to notify parents (upward signals)
|
|
||||||
- Cross-module communication MUST use EventSystem
|
|
||||||
|
|
||||||
### Step 2: Implementation
|
|
||||||
|
|
||||||
Implement the feature following strict project conventions.
|
|
||||||
|
|
||||||
**Requirements:**
|
|
||||||
- **Type Safety**: All variables and functions MUST have type annotations
|
|
||||||
```gdscript
|
|
||||||
var speed: float = 200.0
|
|
||||||
func move(delta: float) -> void:
|
|
||||||
```
|
|
||||||
- **Godot 4.2+ Syntax**: NO `yield()`, use `await`
|
|
||||||
- **Node Caching**: Use `@onready` to cache node references, avoid `get_node()` in `_process()`
|
|
||||||
- **EventSystem Communication**: Use EventSystem for cross-module messaging
|
|
||||||
```gdscript
|
|
||||||
EventSystem.emit_event(EventNames.PLAYER_MOVED, {"position": global_position})
|
|
||||||
EventSystem.connect_event(EventNames.INTERACT_PRESSED, _on_interact_pressed)
|
|
||||||
```
|
|
||||||
- **Nearest Filter**: All Sprite2D/TileMap resources MUST use Nearest filter (no Linear filter)
|
|
||||||
- **AutoLoad Restrictions**: Only GameManager, SceneManager, EventSystem, NetworkManager, ResponseHandler allowed as autoloads
|
|
||||||
- **Low-level Entities**: Do NOT directly reference GameManager in Player/NPC entities, use events instead
|
|
||||||
|
|
||||||
### Step 3: Comment Validation
|
|
||||||
|
|
||||||
Ensure code comments meet project standards.
|
|
||||||
|
|
||||||
**Actions:**
|
|
||||||
1. Read `docs/02-开发规范/代码注释规范.md`
|
|
||||||
2. Verify file header comment is complete:
|
|
||||||
```gdscript
|
|
||||||
# ============================================================================
|
|
||||||
# 文件名: FeatureName.gd
|
|
||||||
# 作用: 简短描述功能
|
|
||||||
#
|
|
||||||
# 主要功能:
|
|
||||||
# - 功能点1
|
|
||||||
# - 功能点2
|
|
||||||
#
|
|
||||||
# 依赖: 列出依赖的管理器/系统
|
|
||||||
# 作者: [开发者名称]
|
|
||||||
# 创建时间: YYYY-MM-DD
|
|
||||||
# ============================================================================
|
|
||||||
```
|
|
||||||
3. Verify all public functions have complete documentation:
|
|
||||||
```gdscript
|
|
||||||
# 函数功能描述
|
|
||||||
#
|
|
||||||
# 参数:
|
|
||||||
# param_name: Type - 参数说明
|
|
||||||
#
|
|
||||||
# 返回值:
|
|
||||||
# Type - 返回值说明
|
|
||||||
#
|
|
||||||
# 使用示例:
|
|
||||||
# var result = function_name(param)
|
|
||||||
func function_name(param: Type) -> ReturnType:
|
|
||||||
```
|
|
||||||
4. Ensure complex logic has inline comments explaining WHY, not WHAT
|
|
||||||
|
|
||||||
### Step 4: Naming Validation
|
|
||||||
|
|
||||||
Verify all naming follows project conventions.
|
|
||||||
|
|
||||||
**Actions:**
|
|
||||||
1. Read `docs/02-开发规范/命名规范.md`
|
|
||||||
2. Validate naming conventions:
|
|
||||||
- **Class names**: PascalCase (`class_name PlayerController`)
|
|
||||||
- **Variables/Functions**: camelCase (`var moveSpeed: float`, `func updateMovement()`)
|
|
||||||
- **Constants**: UPPER_CASE (`const MAX_HEALTH: int = 100`)
|
|
||||||
- **Private members**: Underscore prefix (`var _velocity: Vector2`)
|
|
||||||
- **Scene files**: snake_case with suffix (`player_scene.tscn`, `enemy_prefab.tscn`)
|
|
||||||
- **Script files**: PascalCase.gd (`PlayerController.gd`, `GameManager.gd`)
|
|
||||||
|
|
||||||
**Common Patterns:**
|
|
||||||
```gdscript
|
|
||||||
# ✅ Correct
|
|
||||||
const MAX_SPEED: float = 300.0
|
|
||||||
var currentHealth: int
|
|
||||||
var _isInitialized: bool = false
|
|
||||||
func getPlayerPosition() -> Vector2:
|
|
||||||
func _calculateDamage(baseDamage: int) -> int:
|
|
||||||
|
|
||||||
# ❌ Incorrect
|
|
||||||
const maxSpeed: float = 300.0 # Constants must be UPPER_CASE
|
|
||||||
var CurrentHealth: int # Variables must be camelCase
|
|
||||||
var is_initialized: bool = false # No snake_case for variables
|
|
||||||
func GetPlayerPosition() -> Vector2: # Functions must be camelCase
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 5: Test Writing
|
|
||||||
|
|
||||||
Create unit tests for the implemented functionality.
|
|
||||||
|
|
||||||
**Actions:**
|
|
||||||
1. Read `docs/03-技术实现/测试指南.md`
|
|
||||||
2. For _Core/ managers/systems, MUST create corresponding test file in `tests/unit/`
|
|
||||||
3. Test file naming: `test_[name].gd`
|
|
||||||
4. Test file structure:
|
|
||||||
```gdscript
|
|
||||||
extends GutTest
|
|
||||||
|
|
||||||
## [FeatureName] 单元测试
|
|
||||||
|
|
||||||
var feature: FeatureName
|
|
||||||
|
|
||||||
func before_each():
|
|
||||||
feature = preload("res://_Core/managers/FeatureName.gd").new()
|
|
||||||
add_child(feature)
|
|
||||||
|
|
||||||
func after_each():
|
|
||||||
feature.queue_free()
|
|
||||||
|
|
||||||
func test_initialization():
|
|
||||||
var result = feature.initialize()
|
|
||||||
assert_true(result, "Feature should initialize successfully")
|
|
||||||
|
|
||||||
func test_core_functionality():
|
|
||||||
# Test core functionality
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 6: Test Execution
|
|
||||||
|
|
||||||
Run tests to ensure code quality.
|
|
||||||
|
|
||||||
**Actions:**
|
|
||||||
1. Run GUT tests using Bash tool:
|
|
||||||
```bash
|
|
||||||
godot --headless -s addons/gut/gut_cmdline.gd -gdir=res://tests/ -ginclude_subdirs
|
|
||||||
```
|
|
||||||
2. Verify all tests pass
|
|
||||||
3. If tests fail:
|
|
||||||
- Identify the root cause
|
|
||||||
- Fix the implementation or test
|
|
||||||
- Re-run tests until all pass
|
|
||||||
|
|
||||||
### Step 7: Git Commit
|
|
||||||
|
|
||||||
Generate standardized Git commit message.
|
|
||||||
|
|
||||||
**Actions:**
|
|
||||||
1. Read `docs/02-开发规范/Git提交规范.md`
|
|
||||||
2. Determine commit type based on changes:
|
|
||||||
- `feat` - New features
|
|
||||||
- `fix` - Bug fixes
|
|
||||||
- `docs` - Documentation updates
|
|
||||||
- `refactor` - Code refactoring
|
|
||||||
- `perf` - Performance optimization
|
|
||||||
- `test` - Test additions/modifications
|
|
||||||
- `scene` - Scene file changes
|
|
||||||
- `ui` - UI related changes
|
|
||||||
3. Generate commit message using Chinese colon (:):
|
|
||||||
```
|
|
||||||
<类型>:<简短描述>
|
|
||||||
|
|
||||||
[可选的详细描述]
|
|
||||||
```
|
|
||||||
4. Follow principles:
|
|
||||||
- **One commit, one change** - Most important rule
|
|
||||||
- Use imperative verbs (添加, 修复, 更新)
|
|
||||||
- Keep description concise (< 50 characters)
|
|
||||||
- If multiple types of changes, split into separate commits
|
|
||||||
|
|
||||||
**Examples:**
|
|
||||||
```bash
|
|
||||||
# ✅ Good commits
|
|
||||||
git commit -m "feat:实现玩家二段跳功能"
|
|
||||||
git commit -m "fix:修复角色跳跃时的碰撞检测问题"
|
|
||||||
git commit -m "test:添加角色控制器单元测试"
|
|
||||||
|
|
||||||
# ❌ Bad commits
|
|
||||||
git commit -m "fix + feat:修复Bug并添加新功能" # Mixed types
|
|
||||||
git commit -m "update player" # Vague, English
|
|
||||||
```
|
|
||||||
|
|
||||||
## Progress Tracking
|
|
||||||
|
|
||||||
Use TodoWrite tool to track workflow progress:
|
|
||||||
|
|
||||||
```gdscript
|
|
||||||
TodoWrite.create_todos([
|
|
||||||
"Step 1: 架构分析 - 读取架构规范",
|
|
||||||
"Step 2: 功能实现 - 按规范编码",
|
|
||||||
"Step 3: 注释规范检查",
|
|
||||||
"Step 4: 命名规范检查",
|
|
||||||
"Step 5: 测试代码编写",
|
|
||||||
"Step 6: 测试验证 - 运行测试",
|
|
||||||
"Step 7: Git 提交 - 生成提交信息"
|
|
||||||
])
|
|
||||||
```
|
|
||||||
|
|
||||||
Mark each step as `completed` immediately after finishing.
|
|
||||||
|
|
||||||
## Quality Checklist
|
|
||||||
|
|
||||||
Before completing the workflow, verify:
|
|
||||||
|
|
||||||
- [ ] File location follows layered architecture (_Core, scenes, UI)
|
|
||||||
- [ ] Uses EventSystem for cross-module communication
|
|
||||||
- [ ] Event names added to EventNames.gd
|
|
||||||
- [ ] All variables and functions have type annotations
|
|
||||||
- [ ] Naming conventions correct (PascalCase/camelCase/UPPER_CASE)
|
|
||||||
- [ ] File header comment complete
|
|
||||||
- [ ] Public functions have complete documentation
|
|
||||||
- [ ] Unit tests created and passing
|
|
||||||
- [ ] Git commit message follows specification
|
|
||||||
- [ ] No Godot 3.x syntax (yield → await)
|
|
||||||
- [ ] Node references cached with @onready
|
|
||||||
- [ ] Sprite2D/TileMap use Nearest filter
|
|
||||||
|
|
||||||
## Reference Documents
|
|
||||||
|
|
||||||
The skill automatically reads these documents at appropriate steps:
|
|
||||||
|
|
||||||
- Architecture: `docs/02-开发规范/架构与通信规范.md`
|
|
||||||
- Comments: `docs/02-开发规范/代码注释规范.md`
|
|
||||||
- Naming: `docs/02-开发规范/命名规范.md`
|
|
||||||
- Testing: `docs/03-技术实现/测试指南.md`
|
|
||||||
- Git: `docs/02-开发规范/Git提交规范.md`
|
|
||||||
- Project Instructions: `claude.md` (root directory)
|
|
||||||
|
|
||||||
For detailed checklist reference, see `references/checklist.md` in this skill directory.
|
|
||||||
|
|
||||||
## Example Workflow
|
|
||||||
|
|
||||||
User request: "实现玩家二段跳功能"
|
|
||||||
|
|
||||||
1. **Architecture Analysis** ✅
|
|
||||||
- Read architecture spec
|
|
||||||
- Target: `scenes/Entities/Player/Player.gd`
|
|
||||||
- Communication: Emit `PLAYER_DOUBLE_JUMPED` event
|
|
||||||
- Dependencies: EventSystem, Input
|
|
||||||
- Event: Add `PLAYER_DOUBLE_JUMPED` to EventNames.gd
|
|
||||||
|
|
||||||
2. **Implementation** ✅
|
|
||||||
- Create double jump logic with type annotations
|
|
||||||
- Use EventSystem.emit_event() for notifications
|
|
||||||
- Cache references with @onready
|
|
||||||
- Use await instead of yield
|
|
||||||
|
|
||||||
3. **Comment Validation** ✅
|
|
||||||
- Add file header with feature description
|
|
||||||
- Document double jump function parameters
|
|
||||||
- Add inline comments for jump logic
|
|
||||||
|
|
||||||
4. **Naming Validation** ✅
|
|
||||||
- Verify: `var canDoubleJump: bool` (camelCase)
|
|
||||||
- Verify: `const MAX_DOUBLE_JUMPS: int` (UPPER_CASE)
|
|
||||||
- Verify: `func performDoubleJump()` (camelCase)
|
|
||||||
|
|
||||||
5. **Test Writing** ✅
|
|
||||||
- Create `tests/unit/test_player_double_jump.gd`
|
|
||||||
- Test initialization, jump execution, limits
|
|
||||||
|
|
||||||
6. **Test Execution** ✅
|
|
||||||
- Run: `godot --headless -s addons/gut/gut_cmdline.gd`
|
|
||||||
- All tests pass ✅
|
|
||||||
|
|
||||||
7. **Git Commit** ✅
|
|
||||||
```bash
|
|
||||||
git add scenes/Entities/Player/Player.gd _Core/EventNames.gd tests/unit/test_player_double_jump.gd
|
|
||||||
git commit -m "feat:实现玩家二段跳功能"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
- This skill enforces quality standards through automated validation
|
|
||||||
- Each step builds upon the previous, ensuring comprehensive quality control
|
|
||||||
- Skipping steps will result in incomplete or non-compliant code
|
|
||||||
- The 7-step workflow is designed for team consistency and maintainability
|
|
||||||
@@ -1,285 +0,0 @@
|
|||||||
# WhaleTown Development Quality Checklist
|
|
||||||
|
|
||||||
快速参考检查清单,用于验证代码是否符合项目规范。
|
|
||||||
|
|
||||||
## 架构检查清单
|
|
||||||
|
|
||||||
### 文件位置
|
|
||||||
- [ ] 核心系统文件位于 `_Core/managers/` 或 `_Core/systems/`
|
|
||||||
- [ ] 游戏场景文件位于 `scenes/Maps/`, `scenes/Entities/`, `scenes/Components/`
|
|
||||||
- [ ] UI 组件文件位于 `scenes/ui/`
|
|
||||||
- [ ] 测试文件位于 `tests/unit/` 或 `tests/integration/`
|
|
||||||
|
|
||||||
### 通信方式
|
|
||||||
- [ ] 跨模块通信使用 EventSystem
|
|
||||||
- [ ] 新增事件定义在 `_Core/EventNames.gd` 中
|
|
||||||
- [ ] 遵循 "Signal Up, Call Down" 原则
|
|
||||||
- [ ] 父节点调用子节点方法(向下调用)
|
|
||||||
- [ ] 子节点发出信号通知父节点(向上信号)
|
|
||||||
|
|
||||||
### 依赖管理
|
|
||||||
- [ ] 仅使用允许的自动加载:GameManager, SceneManager, EventSystem, NetworkManager, ResponseHandler
|
|
||||||
- [ ] 底层实体(Player, NPC)不直接访问 GameManager
|
|
||||||
- [ ] 底层实体通过事件系统与全局管理器通信
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 代码规范检查清单
|
|
||||||
|
|
||||||
### 类型安全
|
|
||||||
- [ ] 所有变量都有类型注解:`var speed: float = 200.0`
|
|
||||||
- [ ] 所有函数都有参数和返回值类型:`func move(delta: float) -> void:`
|
|
||||||
- [ ] 常量都有类型注解:`const MAX_HEALTH: int = 100`
|
|
||||||
|
|
||||||
### Godot 4.2+ 语法
|
|
||||||
- [ ] 使用 `await` 代替 `yield()`
|
|
||||||
- [ ] 使用 `@onready` 缓存节点引用
|
|
||||||
- [ ] 避免在 `_process()` 中使用 `get_node()`
|
|
||||||
- [ ] 信号连接使用 `.connect()` 语法
|
|
||||||
|
|
||||||
### 资源设置
|
|
||||||
- [ ] 所有 Sprite2D 使用 Nearest 滤镜(不使用 Linear)
|
|
||||||
- [ ] 所有 TileMap 使用 Nearest 滤镜
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 命名规范检查清单
|
|
||||||
|
|
||||||
### 类名
|
|
||||||
- [ ] 使用 PascalCase:`class_name PlayerController`
|
|
||||||
- [ ] 文件名与类名一致:`PlayerController.gd`
|
|
||||||
|
|
||||||
### 变量
|
|
||||||
- [ ] 公共变量使用 camelCase:`var moveSpeed: float`
|
|
||||||
- [ ] 私有变量使用下划线前缀:`var _velocity: Vector2`
|
|
||||||
- [ ] 布尔变量使用 is/has/can 前缀:`var isJumping: bool`
|
|
||||||
|
|
||||||
### 函数
|
|
||||||
- [ ] 使用 camelCase:`func updateMovement()`
|
|
||||||
- [ ] 获取函数使用 `get` 前缀:`func getPlayerPosition()`
|
|
||||||
- [ ] 设置函数使用 `set` 前缀:`func setHealth(value: int)`
|
|
||||||
- [ ] 判断函数使用 `is/has/can` 前缀:`func isAlive()`, `func canJump()`
|
|
||||||
- [ ] 私有函数使用下划线前缀:`func _calculateDamage()`
|
|
||||||
|
|
||||||
### 常量
|
|
||||||
- [ ] 使用 UPPER_CASE:`const MAX_HEALTH: int = 100`
|
|
||||||
- [ ] 使用下划线分隔:`const JUMP_FORCE: float = -400.0`
|
|
||||||
|
|
||||||
### 枚举
|
|
||||||
- [ ] 枚举类型使用 PascalCase:`enum PlayerState`
|
|
||||||
- [ ] 枚举值使用 UPPER_CASE:`IDLE, WALKING, RUNNING`
|
|
||||||
|
|
||||||
### 文件命名
|
|
||||||
- [ ] 脚本文件:PascalCase.gd (`PlayerController.gd`)
|
|
||||||
- [ ] 场景文件:snake_case_scene.tscn (`main_scene.tscn`)
|
|
||||||
- [ ] 预制体文件:snake_case_prefab.tscn (`player_prefab.tscn`)
|
|
||||||
- [ ] 资源文件:snake_case (`sprite_player_idle.png`)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 注释规范检查清单
|
|
||||||
|
|
||||||
### 文件头注释
|
|
||||||
- [ ] 包含文件名
|
|
||||||
- [ ] 包含作用描述
|
|
||||||
- [ ] 列出主要功能
|
|
||||||
- [ ] 列出依赖的管理器/系统
|
|
||||||
- [ ] 包含作者和创建时间
|
|
||||||
|
|
||||||
示例:
|
|
||||||
```gdscript
|
|
||||||
# ============================================================================
|
|
||||||
# 文件名: PlayerController.gd
|
|
||||||
# 作用: 玩家角色控制器,处理玩家输入和移动逻辑
|
|
||||||
#
|
|
||||||
# 主要功能:
|
|
||||||
# - 处理键盘和手柄输入
|
|
||||||
# - 控制角色移动和跳跃
|
|
||||||
# - 管理角色状态切换
|
|
||||||
#
|
|
||||||
# 依赖: EventSystem, InputManager
|
|
||||||
# 作者: [开发者名称]
|
|
||||||
# 创建时间: 2025-01-03
|
|
||||||
# ============================================================================
|
|
||||||
```
|
|
||||||
|
|
||||||
### 函数注释
|
|
||||||
- [ ] 公共函数有完整注释
|
|
||||||
- [ ] 包含功能描述
|
|
||||||
- [ ] 列出参数说明(名称、类型、含义)
|
|
||||||
- [ ] 说明返回值(类型、含义)
|
|
||||||
- [ ] 提供使用示例(对于复杂函数)
|
|
||||||
- [ ] 标注注意事项(如果有)
|
|
||||||
|
|
||||||
示例:
|
|
||||||
```gdscript
|
|
||||||
# 处理玩家输入并更新移动状态
|
|
||||||
#
|
|
||||||
# 参数:
|
|
||||||
# delta: float - 帧时间间隔
|
|
||||||
#
|
|
||||||
# 返回值: 无
|
|
||||||
#
|
|
||||||
# 注意事项:
|
|
||||||
# - 需要在 _physics_process 中调用
|
|
||||||
# - 会自动处理重力和碰撞
|
|
||||||
func handleMovement(delta: float) -> void:
|
|
||||||
```
|
|
||||||
|
|
||||||
### 行内注释
|
|
||||||
- [ ] 复杂逻辑有注释说明
|
|
||||||
- [ ] 注释解释 WHY(为什么),不解释 WHAT(是什么)
|
|
||||||
- [ ] 避免显而易见的注释
|
|
||||||
- [ ] 使用 TODO/FIXME/NOTE 等标记
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 测试规范检查清单
|
|
||||||
|
|
||||||
### 测试文件
|
|
||||||
- [ ] _Core/ 中的管理器/系统都有对应测试文件
|
|
||||||
- [ ] 测试文件位于 `tests/unit/` 或 `tests/integration/`
|
|
||||||
- [ ] 测试文件命名:`test_[name].gd`
|
|
||||||
- [ ] 测试文件继承自 GutTest:`extends GutTest`
|
|
||||||
|
|
||||||
### 测试结构
|
|
||||||
- [ ] 包含测试类注释
|
|
||||||
- [ ] 实现 `before_each()` 进行测试前置设置
|
|
||||||
- [ ] 实现 `after_each()` 进行测试清理
|
|
||||||
- [ ] 测试方法命名:`test_[功能名称]()`
|
|
||||||
|
|
||||||
### 测试覆盖
|
|
||||||
- [ ] 测试核心功能的正常流程
|
|
||||||
- [ ] 测试错误处理和边界条件
|
|
||||||
- [ ] 测试初始化和清理逻辑
|
|
||||||
- [ ] 所有测试都能通过
|
|
||||||
|
|
||||||
示例:
|
|
||||||
```gdscript
|
|
||||||
extends GutTest
|
|
||||||
|
|
||||||
## PlayerController 单元测试
|
|
||||||
|
|
||||||
var player: PlayerController
|
|
||||||
|
|
||||||
func before_each():
|
|
||||||
player = preload("res://scenes/Entities/Player/PlayerController.gd").new()
|
|
||||||
add_child(player)
|
|
||||||
|
|
||||||
func after_each():
|
|
||||||
player.queue_free()
|
|
||||||
|
|
||||||
func test_initialization():
|
|
||||||
var result = player.initialize()
|
|
||||||
assert_true(result, "Player should initialize successfully")
|
|
||||||
|
|
||||||
func test_movement():
|
|
||||||
# 测试移动功能
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Git 提交规范检查清单
|
|
||||||
|
|
||||||
### 提交类型
|
|
||||||
- [ ] 使用正确的提交类型:
|
|
||||||
- `feat` - 新功能
|
|
||||||
- `fix` - Bug 修复
|
|
||||||
- `docs` - 文档更新
|
|
||||||
- `refactor` - 代码重构
|
|
||||||
- `test` - 测试相关
|
|
||||||
- `scene` - 场景文件
|
|
||||||
- `ui` - UI 相关
|
|
||||||
|
|
||||||
### 提交格式
|
|
||||||
- [ ] 使用中文冒号(:)
|
|
||||||
- [ ] 描述简洁明了(< 50 字符)
|
|
||||||
- [ ] 使用动词开头(添加、修复、更新)
|
|
||||||
- [ ] 一次提交只包含一种类型的改动
|
|
||||||
|
|
||||||
### 提交原则
|
|
||||||
- [ ] 一次提交只做一件事
|
|
||||||
- [ ] 提交的代码能够正常运行
|
|
||||||
- [ ] 避免 fix + feat 混合提交
|
|
||||||
- [ ] 如需多种改动,拆分成多次提交
|
|
||||||
|
|
||||||
示例:
|
|
||||||
```bash
|
|
||||||
# ✅ 正确
|
|
||||||
git commit -m "feat:实现玩家二段跳功能"
|
|
||||||
git commit -m "fix:修复角色跳跃时的碰撞检测问题"
|
|
||||||
git commit -m "test:添加角色控制器单元测试"
|
|
||||||
|
|
||||||
# ❌ 错误
|
|
||||||
git commit -m "fix + feat:修复Bug并添加新功能" # 混合类型
|
|
||||||
git commit -m "update player" # 描述不清晰,使用英文
|
|
||||||
git commit -m "fix: 修复Bug" # 使用英文冒号
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 完整工作流检查清单
|
|
||||||
|
|
||||||
使用此清单验证开发任务是否完整执行 7 步工作流:
|
|
||||||
|
|
||||||
### Step 1: 架构分析
|
|
||||||
- [ ] 已读取 `docs/02-开发规范/架构与通信规范.md`
|
|
||||||
- [ ] 已确定文件位置(_Core, scenes, UI)
|
|
||||||
- [ ] 已确定通信方式(EventSystem)
|
|
||||||
- [ ] 已列出依赖的管理器/系统
|
|
||||||
- [ ] 已设计事件定义(如需要)
|
|
||||||
|
|
||||||
### Step 2: 功能实现
|
|
||||||
- [ ] 代码遵循分层架构
|
|
||||||
- [ ] 所有变量和函数有类型注解
|
|
||||||
- [ ] 使用 Godot 4.2+ 语法
|
|
||||||
- [ ] 使用 EventSystem 进行跨模块通信
|
|
||||||
- [ ] 使用 @onready 缓存节点引用
|
|
||||||
|
|
||||||
### Step 3: 注释规范检查
|
|
||||||
- [ ] 已读取 `docs/02-开发规范/代码注释规范.md`
|
|
||||||
- [ ] 文件头注释完整
|
|
||||||
- [ ] 公共函数有完整注释
|
|
||||||
- [ ] 复杂逻辑有行内注释
|
|
||||||
|
|
||||||
### Step 4: 命名规范检查
|
|
||||||
- [ ] 已读取 `docs/02-开发规范/命名规范.md`
|
|
||||||
- [ ] 类名使用 PascalCase
|
|
||||||
- [ ] 变量/函数使用 camelCase
|
|
||||||
- [ ] 常量使用 UPPER_CASE
|
|
||||||
- [ ] 私有成员使用下划线前缀
|
|
||||||
|
|
||||||
### Step 5: 测试代码编写
|
|
||||||
- [ ] 已读取 `docs/03-技术实现/测试指南.md`
|
|
||||||
- [ ] 创建了测试文件 `tests/unit/test_[name].gd`
|
|
||||||
- [ ] 测试文件继承自 GutTest
|
|
||||||
- [ ] 编写了核心功能测试
|
|
||||||
|
|
||||||
### Step 6: 测试验证
|
|
||||||
- [ ] 运行了 GUT 测试命令
|
|
||||||
- [ ] 所有测试通过
|
|
||||||
- [ ] 如有失败,已修复并重新测试
|
|
||||||
|
|
||||||
### Step 7: Git 提交
|
|
||||||
- [ ] 已读取 `docs/02-开发规范/Git提交规范.md`
|
|
||||||
- [ ] 生成了符合规范的提交信息
|
|
||||||
- [ ] 提交类型正确
|
|
||||||
- [ ] 使用中文冒号
|
|
||||||
- [ ] 遵循"一次提交只做一件事"原则
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 快速自检问题
|
|
||||||
|
|
||||||
在提交代码前,问自己以下问题:
|
|
||||||
|
|
||||||
1. **架构**: 文件放在正确的位置了吗?
|
|
||||||
2. **通信**: 是否使用 EventSystem 进行跨模块通信?
|
|
||||||
3. **类型**: 所有变量和函数都有类型注解吗?
|
|
||||||
4. **命名**: 命名是否符合规范(PascalCase/camelCase/UPPER_CASE)?
|
|
||||||
5. **注释**: 文件头和公共函数有完整注释吗?
|
|
||||||
6. **测试**: 创建并运行测试了吗?所有测试都通过了吗?
|
|
||||||
7. **提交**: Git 提交信息符合规范吗?
|
|
||||||
|
|
||||||
如果以上问题都能回答"是",那么代码已经符合 WhaleTown 项目的质量标准!✅
|
|
||||||
@@ -1,312 +0,0 @@
|
|||||||
# WhaleTown Developer Skill 使用说明
|
|
||||||
|
|
||||||
## 📖 简介
|
|
||||||
|
|
||||||
`whaletown-developer` 是 WhaleTown 项目的标准开发工作流自动化技能,确保所有开发任务都遵循统一的项目规范和质量标准。
|
|
||||||
|
|
||||||
## 🎯 适用场景
|
|
||||||
|
|
||||||
在以下情况下使用此 skill:
|
|
||||||
|
|
||||||
- ✅ 实现新功能("实现玩家二段跳"、"添加存档系统")
|
|
||||||
- ✅ 修复 Bug("修复角色碰撞问题"、"解决UI显示错误")
|
|
||||||
- ✅ 创建场景("创建商店场景"、"设计背包界面")
|
|
||||||
- ✅ 开发模块("开发任务系统"、"构建战斗组件")
|
|
||||||
- ✅ 任何需要遵循项目规范的代码开发任务
|
|
||||||
|
|
||||||
## 🚀 调用方式
|
|
||||||
|
|
||||||
### 方式一:通过 Claude(推荐)
|
|
||||||
|
|
||||||
```
|
|
||||||
用户:帮我实现一个 NPC
|
|
||||||
Claude:/whaletown-developer 实现一个 NPC
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方式二:直接请求
|
|
||||||
|
|
||||||
```
|
|
||||||
用户:使用 whaletown-developer skill 创建玩家移动系统
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📋 7 步工作流程
|
|
||||||
|
|
||||||
skill 会自动执行以下标准化流程:
|
|
||||||
|
|
||||||
```
|
|
||||||
Step 1: 架构分析
|
|
||||||
↓ 读取架构规范,确定文件位置、通信方式、依赖关系
|
|
||||||
|
|
||||||
Step 2: 功能实现
|
|
||||||
↓ 按照类型安全、命名规范、EventSystem 通信等要求编码
|
|
||||||
|
|
||||||
Step 3: 注释规范检查
|
|
||||||
↓ 验证文件头、函数文档、行内注释是否完整
|
|
||||||
|
|
||||||
Step 4: 命名规范检查
|
|
||||||
↓ 验证 PascalCase/camelCase/UPPER_CASE 命名规范
|
|
||||||
|
|
||||||
Step 5: 测试代码编写
|
|
||||||
↓ 为核心功能创建 GUT 单元测试
|
|
||||||
|
|
||||||
Step 6: 测试验证
|
|
||||||
↓ 运行测试确保功能正常
|
|
||||||
|
|
||||||
Step 7: Git 提交
|
|
||||||
↓ 生成符合规范的提交信息
|
|
||||||
```
|
|
||||||
|
|
||||||
## 💡 使用示例
|
|
||||||
|
|
||||||
### 示例 1:创建玩家控制器
|
|
||||||
|
|
||||||
**用户输入:**
|
|
||||||
```
|
|
||||||
帮我创建一个玩家角色控制器
|
|
||||||
```
|
|
||||||
|
|
||||||
**Skill 执行:**
|
|
||||||
1. 分析架构 → 确定放在 `scenes/Entities/Player/PlayerController.gd`
|
|
||||||
2. 实现功能 → 创建带类型注解的移动、跳跃逻辑
|
|
||||||
3. 检查注释 → 添加完整的文件头和函数文档
|
|
||||||
4. 检查命名 → 确保 `moveSpeed`、`MAX_HEALTH` 等命名正确
|
|
||||||
5. 编写测试 → 创建 `tests/unit/test_player_controller.gd`
|
|
||||||
6. 运行测试 → 验证功能正常
|
|
||||||
7. 生成提交 → `feat:实现玩家角色控制器`
|
|
||||||
|
|
||||||
### 示例 2:修复跳跃 Bug
|
|
||||||
|
|
||||||
**用户输入:**
|
|
||||||
```
|
|
||||||
修复玩家跳跃时的碰撞检测问题
|
|
||||||
```
|
|
||||||
|
|
||||||
**Skill 执行:**
|
|
||||||
1. 分析架构 → 定位到 `scenes/Entities/Player/Player.gd`
|
|
||||||
2. 实现修复 → 修改碰撞检测逻辑
|
|
||||||
3. 检查注释 → 添加修复说明注释
|
|
||||||
4. 检查命名 → 确保变量命名规范
|
|
||||||
5. 编写测试 → 添加碰撞测试用例
|
|
||||||
6. 运行测试 → 确认 Bug 已修复
|
|
||||||
7. 生成提交 → `fix:修复玩家跳跃时的碰撞检测问题`
|
|
||||||
|
|
||||||
### 示例 3:添加事件通信
|
|
||||||
|
|
||||||
**用户输入:**
|
|
||||||
```
|
|
||||||
实现 NPC 对话系统的事件通信
|
|
||||||
```
|
|
||||||
|
|
||||||
**Skill 执行:**
|
|
||||||
1. 分析架构 → 使用 EventSystem 跨模块通信
|
|
||||||
2. 实现功能 → 在 EventNames.gd 添加 `NPC_DIALOG_STARTED` 事件
|
|
||||||
3. 检查注释 → 文档化事件数据格式
|
|
||||||
4. 检查命名 → 确保事件名称符合规范
|
|
||||||
5. 编写测试 → 测试事件发送和接收
|
|
||||||
6. 运行测试 → 验证通信正常
|
|
||||||
7. 生成提交 → `feat:实现NPC对话系统的事件通信`
|
|
||||||
|
|
||||||
## ✅ 质量保证
|
|
||||||
|
|
||||||
每次使用 skill 后,代码都会符合以下标准:
|
|
||||||
|
|
||||||
### 架构层面
|
|
||||||
- ✅ 文件位置符合分层架构(_Core、scenes、UI)
|
|
||||||
- ✅ 使用 EventSystem 实现跨模块通信
|
|
||||||
- ✅ 事件名称已添加到 EventNames.gd
|
|
||||||
- ✅ 遵循"Signal Up, Call Down"原则
|
|
||||||
|
|
||||||
### 代码质量
|
|
||||||
- ✅ 所有变量和函数都有类型注解
|
|
||||||
- ✅ 命名规范正确(PascalCase/camelCase/UPPER_CASE)
|
|
||||||
- ✅ 使用 Godot 4.2+ 语法(await 而非 yield)
|
|
||||||
- ✅ 节点引用使用 @onready 缓存
|
|
||||||
|
|
||||||
### 文档规范
|
|
||||||
- ✅ 文件头注释完整(文件名、作用、功能、依赖)
|
|
||||||
- ✅ 公共函数有完整文档(参数、返回值、示例)
|
|
||||||
- ✅ 复杂逻辑有行内注释说明
|
|
||||||
|
|
||||||
### 测试覆盖
|
|
||||||
- ✅ 核心功能有单元测试
|
|
||||||
- ✅ 测试文件命名规范(test_*.gd)
|
|
||||||
- ✅ 测试通过验证
|
|
||||||
|
|
||||||
### Git 规范
|
|
||||||
- ✅ 提交信息格式正确(类型:描述)
|
|
||||||
- ✅ 遵循"一次提交只做一件事"原则
|
|
||||||
- ✅ 使用中文冒号和动词开头
|
|
||||||
|
|
||||||
## 📚 相关文档
|
|
||||||
|
|
||||||
Skill 会自动读取以下规范文档:
|
|
||||||
|
|
||||||
- `docs/02-开发规范/架构与通信规范.md` - 分层架构和 EventSystem
|
|
||||||
- `docs/02-开发规范/代码注释规范.md` - 注释格式要求
|
|
||||||
- `docs/02-开发规范/命名规范.md` - 命名约定
|
|
||||||
- `docs/03-技术实现/测试指南.md` - 测试框架使用
|
|
||||||
- `docs/02-开发规范/Git提交规范.md` - 提交信息格式
|
|
||||||
- `CLAUDE.md` - 项目总体指导
|
|
||||||
|
|
||||||
## ⚙️ 配置文件
|
|
||||||
|
|
||||||
Skill 相关配置文件位置:
|
|
||||||
|
|
||||||
```
|
|
||||||
.claude/skills/whaletown-developer/
|
|
||||||
├── SKILL.md # Skill 定义文件
|
|
||||||
├── 使用说明.md # 本文档
|
|
||||||
└── references/
|
|
||||||
└── checklist.md # 质量检查清单
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔄 工作流程可视化
|
|
||||||
|
|
||||||
```
|
|
||||||
用户请求
|
|
||||||
↓
|
|
||||||
调用 whaletown-developer skill
|
|
||||||
↓
|
|
||||||
[Step 1] 架构分析
|
|
||||||
├─ 读取架构规范文档
|
|
||||||
├─ 确定文件位置
|
|
||||||
├─ 识别通信方式
|
|
||||||
└─ 设计事件定义
|
|
||||||
↓
|
|
||||||
[Step 2] 功能实现
|
|
||||||
├─ 遵循类型安全
|
|
||||||
├─ 使用 EventSystem
|
|
||||||
├─ 缓存节点引用
|
|
||||||
└─ 使用 Godot 4.2+ 语法
|
|
||||||
↓
|
|
||||||
[Step 3] 注释规范检查
|
|
||||||
├─ 验证文件头注释
|
|
||||||
├─ 验证函数文档
|
|
||||||
└─ 检查行内注释
|
|
||||||
↓
|
|
||||||
[Step 4] 命名规范检查
|
|
||||||
├─ 类名 PascalCase
|
|
||||||
├─ 变量/函数 camelCase
|
|
||||||
├─ 常量 UPPER_CASE
|
|
||||||
└─ 私有成员 _prefix
|
|
||||||
↓
|
|
||||||
[Step 5] 测试代码编写
|
|
||||||
├─ 创建测试文件
|
|
||||||
├─ 编写测试用例
|
|
||||||
└─ 覆盖核心功能
|
|
||||||
↓
|
|
||||||
[Step 6] 测试验证
|
|
||||||
├─ 运行 GUT 测试
|
|
||||||
├─ 验证测试通过
|
|
||||||
└─ 修复失败测试
|
|
||||||
↓
|
|
||||||
[Step 7] Git 提交
|
|
||||||
├─ 确定提交类型
|
|
||||||
├─ 生成提交信息
|
|
||||||
└─ 遵循提交规范
|
|
||||||
↓
|
|
||||||
完成 ✅
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎓 最佳实践
|
|
||||||
|
|
||||||
### 1. 明确任务描述
|
|
||||||
```bash
|
|
||||||
# ✅ 好的描述
|
|
||||||
"实现玩家二段跳功能"
|
|
||||||
"修复敌人AI路径寻找Bug"
|
|
||||||
"创建商店购买界面"
|
|
||||||
|
|
||||||
# ❌ 模糊描述
|
|
||||||
"改一下玩家"
|
|
||||||
"修复Bug"
|
|
||||||
"做个界面"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 一次处理一个功能
|
|
||||||
```bash
|
|
||||||
# ✅ 推荐
|
|
||||||
用户:实现玩家移动
|
|
||||||
用户:实现玩家跳跃
|
|
||||||
|
|
||||||
# ❌ 不推荐
|
|
||||||
用户:实现玩家移动、跳跃、攻击、技能系统
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 信任 Skill 流程
|
|
||||||
- Skill 会按照 7 步流程确保质量
|
|
||||||
- 不需要手动检查命名、注释等细节
|
|
||||||
- 专注于功能需求和业务逻辑
|
|
||||||
|
|
||||||
### 4. 查看生成的提交信息
|
|
||||||
- Skill 会在 Step 7 生成规范的提交信息
|
|
||||||
- 可以直接使用或根据需要微调
|
|
||||||
|
|
||||||
## ⚠️ 注意事项
|
|
||||||
|
|
||||||
1. **首次使用**
|
|
||||||
- 确保已阅读 `CLAUDE.md` 了解项目规范
|
|
||||||
- 确认所有规范文档都已存在
|
|
||||||
|
|
||||||
2. **测试环境**
|
|
||||||
- 确保 GUT 测试框架已安装(如需运行测试)
|
|
||||||
- Godot 可执行文件在 PATH 中(Step 6 测试执行)
|
|
||||||
|
|
||||||
3. **中断处理**
|
|
||||||
- 如果工作流被中断,可以继续执行剩余步骤
|
|
||||||
- Skill 使用 TodoWrite 追踪进度
|
|
||||||
|
|
||||||
4. **规范更新**
|
|
||||||
- 项目规范文档更新时,Skill 会自动读取最新版本
|
|
||||||
- 无需手动同步
|
|
||||||
|
|
||||||
## 🤝 反馈与改进
|
|
||||||
|
|
||||||
如果遇到问题或有改进建议:
|
|
||||||
|
|
||||||
1. 检查是否所有规范文档都已更新
|
|
||||||
2. 确认任务描述清晰明确
|
|
||||||
3. 查看 Skill 执行日志定位问题
|
|
||||||
4. 向团队报告问题或建议
|
|
||||||
|
|
||||||
## 📊 效果对比
|
|
||||||
|
|
||||||
### 不使用 Skill
|
|
||||||
```
|
|
||||||
开发者手动:
|
|
||||||
1. 不确定文件放哪里 ❌
|
|
||||||
2. 可能忘记类型注解 ❌
|
|
||||||
3. 注释不完整 ❌
|
|
||||||
4. 命名不一致 ❌
|
|
||||||
5. 没有测试 ❌
|
|
||||||
6. 提交信息格式错误 ❌
|
|
||||||
结果:代码质量参差不齐
|
|
||||||
```
|
|
||||||
|
|
||||||
### 使用 Skill
|
|
||||||
```
|
|
||||||
Skill 自动化:
|
|
||||||
1. 自动确定正确位置 ✅
|
|
||||||
2. 强制类型安全 ✅
|
|
||||||
3. 完整注释文档 ✅
|
|
||||||
4. 统一命名规范 ✅
|
|
||||||
5. 自动生成测试 ✅
|
|
||||||
6. 规范提交信息 ✅
|
|
||||||
结果:高质量、一致性代码
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎯 总结
|
|
||||||
|
|
||||||
whaletown-developer skill 是你的开发助手,它会:
|
|
||||||
|
|
||||||
- 🤖 **自动化** 7 步标准流程
|
|
||||||
- 📏 **标准化** 代码质量
|
|
||||||
- 🔒 **保证** 规范遵循
|
|
||||||
- ⚡ **加速** 开发效率
|
|
||||||
- 🧪 **确保** 测试覆盖
|
|
||||||
|
|
||||||
**记住:专注于功能实现,让 Skill 处理规范和质量!**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**开始使用:** 只需告诉 Claude "帮我实现 XXX 功能" 即可!
|
|
||||||
@@ -29,7 +29,7 @@ extends RefCounted
|
|||||||
# ============ 信号定义 ============
|
# ============ 信号定义 ============
|
||||||
|
|
||||||
# 登录成功信号
|
# 登录成功信号
|
||||||
signal login_success(username: String, token: String)
|
signal login_success(username: String)
|
||||||
|
|
||||||
# 登录失败信号
|
# 登录失败信号
|
||||||
signal login_failed(message: String)
|
signal login_failed(message: String)
|
||||||
@@ -80,9 +80,6 @@ var current_email: String = ""
|
|||||||
# 网络请求管理
|
# 网络请求管理
|
||||||
var active_request_ids: Array = []
|
var active_request_ids: Array = []
|
||||||
|
|
||||||
# 当前登录用户ID (静态变量,全局访问)
|
|
||||||
static var current_user_id: String = ""
|
|
||||||
|
|
||||||
# ============ 生命周期方法 ============
|
# ============ 生命周期方法 ============
|
||||||
|
|
||||||
# 初始化管理器
|
# 初始化管理器
|
||||||
@@ -434,20 +431,12 @@ func _on_login_response(success: bool, data: Dictionary, error_info: Dictionary)
|
|||||||
|
|
||||||
if result.success:
|
if result.success:
|
||||||
var username = ""
|
var username = ""
|
||||||
if data.has("data") and data.data.has("user"):
|
if data.has("data") and data.data.has("user") and data.data.user.has("username"):
|
||||||
var user_data = data.data.user
|
username = data.data.user.username
|
||||||
if user_data.has("username"):
|
|
||||||
username = user_data.username
|
|
||||||
if user_data.has("id"):
|
|
||||||
current_user_id = user_data.id
|
|
||||||
print("AuthManager: Current User ID set to ", current_user_id)
|
|
||||||
|
|
||||||
# 延迟发送登录成功信号
|
# 延迟发送登录成功信号
|
||||||
await Engine.get_main_loop().create_timer(1.0).timeout
|
await Engine.get_main_loop().create_timer(1.0).timeout
|
||||||
var token = ""
|
login_success.emit(username)
|
||||||
if data.has("data") and data.data.has("access_token"):
|
|
||||||
token = data.data.access_token
|
|
||||||
login_success.emit(username, token)
|
|
||||||
else:
|
else:
|
||||||
login_failed.emit(result.message)
|
login_failed.emit(result.message)
|
||||||
|
|
||||||
@@ -462,16 +451,11 @@ func _on_verification_login_response(success: bool, data: Dictionary, error_info
|
|||||||
|
|
||||||
if result.success:
|
if result.success:
|
||||||
var username = ""
|
var username = ""
|
||||||
if data.has("data") and data.data.has("user"):
|
if data.has("data") and data.data.has("user") and data.data.user.has("username"):
|
||||||
var user_data = data.data.user
|
username = data.data.user.username
|
||||||
if user_data.has("username"):
|
|
||||||
username = user_data.username
|
|
||||||
if user_data.has("id"):
|
|
||||||
current_user_id = user_data.id
|
|
||||||
print("AuthManager: Current User ID set to ", current_user_id)
|
|
||||||
|
|
||||||
await Engine.get_main_loop().create_timer(1.0).timeout
|
await Engine.get_main_loop().create_timer(1.0).timeout
|
||||||
login_success.emit(username, data.get("access_token", ""))
|
login_success.emit(username)
|
||||||
else:
|
else:
|
||||||
login_failed.emit(result.message)
|
login_failed.emit(result.message)
|
||||||
|
|
||||||
|
|||||||
@@ -38,17 +38,10 @@ signal request_completed(request_id: String, success: bool, data: Dictionary)
|
|||||||
# message: String - 错误消息
|
# message: String - 错误消息
|
||||||
signal request_failed(request_id: String, error_type: String, message: String)
|
signal request_failed(request_id: String, error_type: String, message: String)
|
||||||
|
|
||||||
# 公告列表接收信号
|
|
||||||
signal notices_received(data: Array)
|
|
||||||
|
|
||||||
# ============ 常量定义 ============
|
# ============ 常量定义 ============
|
||||||
|
|
||||||
# API基础URL - 所有请求的根地址
|
# API基础URL - 所有请求的根地址
|
||||||
# [Remote] 正式环境地址 (实际正式项目用此地址)
|
const API_BASE_URL = "https://whaletownend.xinghangee.icu"
|
||||||
# const API_BASE_URL = "https://whaletownend.xinghangee.icu"
|
|
||||||
|
|
||||||
# [Local] 本地调试地址 (本地调试用此地址)
|
|
||||||
const API_BASE_URL = "http://localhost:3000"
|
|
||||||
|
|
||||||
# 默认请求超时时间(秒)
|
# 默认请求超时时间(秒)
|
||||||
const DEFAULT_TIMEOUT = 30.0
|
const DEFAULT_TIMEOUT = 30.0
|
||||||
@@ -121,7 +114,6 @@ var request_counter: int = 0 # 请求计数器,用于
|
|||||||
# 初始化网络管理器
|
# 初始化网络管理器
|
||||||
# 在节点准备就绪时调用
|
# 在节点准备就绪时调用
|
||||||
func _ready():
|
func _ready():
|
||||||
process_mode = Node.PROCESS_MODE_ALWAYS
|
|
||||||
print("NetworkManager 已初始化")
|
print("NetworkManager 已初始化")
|
||||||
|
|
||||||
# ============ 公共API接口 ============
|
# ============ 公共API接口 ============
|
||||||
@@ -444,18 +436,6 @@ func github_login(github_id: String, username: String, nickname: String, email:
|
|||||||
|
|
||||||
return post_request("/auth/github", data, callback)
|
return post_request("/auth/github", data, callback)
|
||||||
|
|
||||||
# TODO: 获取公告列表
|
|
||||||
func request_notices():
|
|
||||||
# 发送 GET 请求到 /notices 接口
|
|
||||||
get_request("/notices", _on_notices_response)
|
|
||||||
|
|
||||||
func _on_notices_response(success: bool, data: Dictionary, error_info: Dictionary):
|
|
||||||
if success and data.has("data"):
|
|
||||||
notices_received.emit(data["data"])
|
|
||||||
else:
|
|
||||||
# 失败或无数据时发送空数组
|
|
||||||
notices_received.emit([])
|
|
||||||
|
|
||||||
# ============ 核心请求处理 ============
|
# ============ 核心请求处理 ============
|
||||||
|
|
||||||
# 发送请求的核心方法
|
# 发送请求的核心方法
|
||||||
|
|||||||
@@ -36,8 +36,6 @@ signal scene_change_started(scene_name: String)
|
|||||||
# 场景状态
|
# 场景状态
|
||||||
var current_scene_name: String = "" # 当前场景名称
|
var current_scene_name: String = "" # 当前场景名称
|
||||||
var is_changing_scene: bool = false # 是否正在切换场景
|
var is_changing_scene: bool = false # 是否正在切换场景
|
||||||
var _next_scene_position: Variant = null # 下一个场景的初始位置 (Vector2 or null)
|
|
||||||
var _next_spawn_name: String = "" # 下一个场景的出生点名称 (String)
|
|
||||||
|
|
||||||
# 场景路径映射表
|
# 场景路径映射表
|
||||||
# 将场景名称映射到实际的文件路径
|
# 将场景名称映射到实际的文件路径
|
||||||
@@ -49,9 +47,7 @@ var scene_paths: Dictionary = {
|
|||||||
"battle": "res://scenes/maps/battle_scene.tscn", # 战斗场景 - 战斗系统
|
"battle": "res://scenes/maps/battle_scene.tscn", # 战斗场景 - 战斗系统
|
||||||
"inventory": "res://scenes/ui/InventoryWindow.tscn", # 背包界面
|
"inventory": "res://scenes/ui/InventoryWindow.tscn", # 背包界面
|
||||||
"shop": "res://scenes/ui/ShopWindow.tscn", # 商店界面
|
"shop": "res://scenes/ui/ShopWindow.tscn", # 商店界面
|
||||||
"settings": "res://scenes/ui/SettingsWindow.tscn", # 设置界面
|
"settings": "res://scenes/ui/SettingsWindow.tscn" # 设置界面
|
||||||
"room": "res://scenes/Maps/room.tscn", # 房间场景
|
|
||||||
"square": "res://scenes/Maps/square.tscn" # 广场场景
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============ 生命周期方法 ============
|
# ============ 生命周期方法 ============
|
||||||
@@ -110,18 +106,15 @@ func change_scene(scene_name: String, use_transition: bool = true):
|
|||||||
if use_transition:
|
if use_transition:
|
||||||
await show_transition()
|
await show_transition()
|
||||||
|
|
||||||
# 更新场景名称(在切换之前设置,确保新场景的 _ready 能获取正确的名称)
|
|
||||||
current_scene_name = scene_name
|
|
||||||
|
|
||||||
# 执行场景切换
|
# 执行场景切换
|
||||||
var error = get_tree().change_scene_to_file(scene_path)
|
var error = get_tree().change_scene_to_file(scene_path)
|
||||||
if error != OK:
|
if error != OK:
|
||||||
print("场景切换失败: ", error)
|
print("场景切换失败: ", error)
|
||||||
current_scene_name = "" # 恢复为空
|
|
||||||
is_changing_scene = false
|
is_changing_scene = false
|
||||||
return false
|
return false
|
||||||
|
|
||||||
# 更新状态
|
# 更新状态
|
||||||
|
current_scene_name = scene_name
|
||||||
is_changing_scene = false
|
is_changing_scene = false
|
||||||
scene_changed.emit(scene_name)
|
scene_changed.emit(scene_name)
|
||||||
|
|
||||||
@@ -141,27 +134,6 @@ func change_scene(scene_name: String, use_transition: bool = true):
|
|||||||
func get_current_scene_name() -> String:
|
func get_current_scene_name() -> String:
|
||||||
return current_scene_name
|
return current_scene_name
|
||||||
|
|
||||||
# 设置下一个场景的初始位置
|
|
||||||
func set_next_scene_position(pos: Vector2) -> void:
|
|
||||||
_next_scene_position = pos
|
|
||||||
|
|
||||||
# 获取并清除下一个场景的初始位置
|
|
||||||
func get_next_scene_position() -> Variant:
|
|
||||||
var pos = _next_scene_position
|
|
||||||
_next_scene_position = null
|
|
||||||
return pos
|
|
||||||
|
|
||||||
# 设置下一个场景的出生点名称
|
|
||||||
func set_next_spawn_name(spawn_name: String) -> void:
|
|
||||||
_next_spawn_name = spawn_name
|
|
||||||
|
|
||||||
# 获取并清除下一个场景的出生点名称
|
|
||||||
func get_next_spawn_name() -> String:
|
|
||||||
var name = _next_spawn_name
|
|
||||||
_next_spawn_name = ""
|
|
||||||
return name
|
|
||||||
|
|
||||||
|
|
||||||
# ============ 场景注册方法 ============
|
# ============ 场景注册方法 ============
|
||||||
|
|
||||||
# 注册新场景
|
# 注册新场景
|
||||||
|
|||||||
@@ -1,172 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
# ============================================================================
|
|
||||||
# WebSocketManager.gd - WebSocket连接管理器
|
|
||||||
# ============================================================================
|
|
||||||
# 负责与后端 Native WebSocket 服务进行实时通信
|
|
||||||
#
|
|
||||||
# 协议文档: new_docs/game_architecture_design.md
|
|
||||||
# 后端地址: ws://localhost:3000/location-broadcast
|
|
||||||
# ============================================================================
|
|
||||||
|
|
||||||
signal connected_to_server()
|
|
||||||
signal connection_closed()
|
|
||||||
signal connection_error()
|
|
||||||
signal session_joined(data: Dictionary)
|
|
||||||
signal user_joined(data: Dictionary)
|
|
||||||
signal user_left(data: Dictionary)
|
|
||||||
signal position_updated(data: Dictionary)
|
|
||||||
|
|
||||||
const WS_URL = "wss://whaletownend.xinghangee.icu/location-broadcast"
|
|
||||||
const PING_INTERVAL = 25.0 # 秒
|
|
||||||
|
|
||||||
var _socket: WebSocketPeer
|
|
||||||
var _connected: bool = false
|
|
||||||
var _ping_timer: float = 0.0
|
|
||||||
var _auth_token: String = ""
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
_socket = WebSocketPeer.new()
|
|
||||||
process_mode = Node.PROCESS_MODE_ALWAYS # 保证暂停时也能处理网络
|
|
||||||
print("WebSocketManager Initialized")
|
|
||||||
|
|
||||||
func _process(delta):
|
|
||||||
_socket.poll()
|
|
||||||
var state = _socket.get_ready_state()
|
|
||||||
|
|
||||||
if state == WebSocketPeer.STATE_OPEN:
|
|
||||||
if not _connected:
|
|
||||||
_on_connected()
|
|
||||||
|
|
||||||
# 处理接收到的数据包
|
|
||||||
while _socket.get_available_packet_count() > 0:
|
|
||||||
var packet = _socket.get_packet()
|
|
||||||
_handle_packet(packet)
|
|
||||||
|
|
||||||
# 心跳处理
|
|
||||||
_ping_timer += delta
|
|
||||||
if _ping_timer >= PING_INTERVAL:
|
|
||||||
_send_heartbeat()
|
|
||||||
_ping_timer = 0.0
|
|
||||||
|
|
||||||
elif state == WebSocketPeer.STATE_CLOSED:
|
|
||||||
if _connected:
|
|
||||||
_on_disconnected()
|
|
||||||
|
|
||||||
func connect_to_server():
|
|
||||||
if _socket.get_ready_state() == WebSocketPeer.STATE_OPEN:
|
|
||||||
print("WebSocket 已经是连接状态")
|
|
||||||
return
|
|
||||||
|
|
||||||
print("正在连接 WebSocket: ", WS_URL)
|
|
||||||
var err = _socket.connect_to_url(WS_URL)
|
|
||||||
if err != OK:
|
|
||||||
print("WebSocket 连接请求失败: ", err)
|
|
||||||
connection_error.emit()
|
|
||||||
else:
|
|
||||||
# Godot WebSocket connect is non-blocking, wait for state change in _process
|
|
||||||
pass
|
|
||||||
|
|
||||||
func close_connection():
|
|
||||||
_socket.close()
|
|
||||||
|
|
||||||
func set_auth_token(token: String):
|
|
||||||
_auth_token = token
|
|
||||||
|
|
||||||
# ============ 协议发送 ============
|
|
||||||
|
|
||||||
func send_packet(event: String, data: Dictionary):
|
|
||||||
if _socket.get_ready_state() != WebSocketPeer.STATE_OPEN:
|
|
||||||
return
|
|
||||||
|
|
||||||
var message = {
|
|
||||||
"event": event,
|
|
||||||
"data": data
|
|
||||||
}
|
|
||||||
var json_str = JSON.stringify(message)
|
|
||||||
_socket.put_packet(json_str.to_utf8_buffer())
|
|
||||||
|
|
||||||
func join_session(map_id: String, initial_pos: Vector2):
|
|
||||||
var data = {
|
|
||||||
"sessionId": map_id,
|
|
||||||
"initialPosition": {
|
|
||||||
"x": initial_pos.x,
|
|
||||||
"y": initial_pos.y,
|
|
||||||
"mapId": map_id
|
|
||||||
},
|
|
||||||
"token": _auth_token
|
|
||||||
}
|
|
||||||
print("发送加入会话请求: ", map_id, " mapId Payload: ", data.initialPosition.mapId)
|
|
||||||
send_packet("join_session", data)
|
|
||||||
|
|
||||||
func leave_session(map_id: String):
|
|
||||||
print("发送离开会话请求: ", map_id)
|
|
||||||
send_packet("leave_session", {"sessionId": map_id})
|
|
||||||
|
|
||||||
func send_position_update(map_id: String, pos: Vector2, anim_data: Dictionary = {}):
|
|
||||||
var data = {
|
|
||||||
"x": pos.x,
|
|
||||||
"y": pos.y,
|
|
||||||
"mapId": map_id,
|
|
||||||
"metadata": anim_data
|
|
||||||
}
|
|
||||||
# print("发送位置更新: ", map_id)
|
|
||||||
if map_id == "":
|
|
||||||
print("WARNING: Sending position update with EMPTY mapId! Pos: ", pos)
|
|
||||||
send_packet("position_update", data)
|
|
||||||
|
|
||||||
func _send_heartbeat():
|
|
||||||
send_packet("heartbeat", {"timestamp": Time.get_unix_time_from_system()})
|
|
||||||
|
|
||||||
# ============ 事件处理 ============
|
|
||||||
|
|
||||||
func _on_connected():
|
|
||||||
_connected = true
|
|
||||||
print("WebSocket 连接成功!")
|
|
||||||
connected_to_server.emit()
|
|
||||||
|
|
||||||
func _on_disconnected():
|
|
||||||
_connected = false
|
|
||||||
var code = _socket.get_close_code()
|
|
||||||
var reason = _socket.get_close_reason()
|
|
||||||
print("WebSocket 连接断开. Code: %d, Reason: %s" % [code, reason])
|
|
||||||
connection_closed.emit()
|
|
||||||
|
|
||||||
func _handle_packet(packet: PackedByteArray):
|
|
||||||
var json_str = packet.get_string_from_utf8()
|
|
||||||
var json = JSON.new()
|
|
||||||
var err = json.parse(json_str)
|
|
||||||
|
|
||||||
if err != OK:
|
|
||||||
print("JSON 解析失败: ", json.get_error_message())
|
|
||||||
return
|
|
||||||
|
|
||||||
var message = json.data
|
|
||||||
if not message is Dictionary or not message.has("event"):
|
|
||||||
return
|
|
||||||
|
|
||||||
var event = message["event"]
|
|
||||||
var data = message.get("data", {})
|
|
||||||
|
|
||||||
if event != "heartbeat_response":
|
|
||||||
print("WebSocket Rx: ", event) # Debug logs for all events
|
|
||||||
|
|
||||||
match event:
|
|
||||||
"session_joined":
|
|
||||||
session_joined.emit(data)
|
|
||||||
print("加入会话成功,当前房间人数: ", data.get("users", []).size())
|
|
||||||
"user_joined":
|
|
||||||
user_joined.emit(data)
|
|
||||||
print("用户加入: ", data.get("userId"))
|
|
||||||
"user_left":
|
|
||||||
user_left.emit(data)
|
|
||||||
print("用户离开: ", data.get("userId"))
|
|
||||||
"position_update":
|
|
||||||
print("WebSocket Rx position_update: ", data.get("userId", "unknown"))
|
|
||||||
position_updated.emit(data)
|
|
||||||
"heartbeat_response":
|
|
||||||
pass # 静默处理
|
|
||||||
"error":
|
|
||||||
print("WebSocket 错误事件: ", JSON.stringify(data))
|
|
||||||
_:
|
|
||||||
print("未处理的 WebSocket 事件: ", event)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://stpl2jdeqo0d
|
|
||||||
|
Before Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 856 KiB |
|
Before Width: | Height: | Size: 142 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://b4aildrnhbpl4"
|
|
||||||
path="res://.godot/imported/NoticeBoard.png-038eefee12f116fb9502ed755594cede.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/materials/NoticeBoard.png"
|
|
||||||
dest_files=["res://.godot/imported/NoticeBoard.png-038eefee12f116fb9502ed755594cede.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
|
|
||||||
|
Before Width: | Height: | Size: 179 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://v7loa3smfkrd"
|
|
||||||
path="res://.godot/imported/WelcomeBoard.png-bcff7f9bf968cb5d7630e2ad47f2fb42.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/materials/WelcomeBoard.png"
|
|
||||||
dest_files=["res://.godot/imported/WelcomeBoard.png-bcff7f9bf968cb5d7630e2ad47f2fb42.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
assets/sprites/building/datawhale_house_asset_1.png
Normal file
|
After Width: | Height: | Size: 1003 KiB |
@@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://brko2ik6t6ib5"
|
uid="uid://rwawg1rprjtq"
|
||||||
path="res://.godot/imported/npc_286_241.png-dfe6daef11d0f27f7902e69d6057828f.ctex"
|
path="res://.godot/imported/datawhale_house_asset_1.png-1892bbe725ca0e23a398f090f9971251.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/characters/npc_286_241.png"
|
source_file="res://assets/sprites/building/datawhale_house_asset_1.png"
|
||||||
dest_files=["res://.godot/imported/npc_286_241.png-dfe6daef11d0f27f7902e69d6057828f.ctex"]
|
dest_files=["res://.godot/imported/datawhale_house_asset_1.png-1892bbe725ca0e23a398f090f9971251.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 1.2 MiB |
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://ctq2aeb3vbo5f"
|
||||||
|
path="res://.godot/imported/datawhale_house_single_story_enhanced.png-0676f1c2301056dd7cf2d93eb21a3a60.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/building/datawhale_house_single_story_enhanced.png"
|
||||||
|
dest_files=["res://.godot/imported/datawhale_house_single_story_enhanced.png-0676f1c2301056dd7cf2d93eb21a3a60.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
assets/sprites/building/datawhale_house_three_story_1.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://b43a04p4lsnb8"
|
||||||
|
path="res://.godot/imported/datawhale_house_three_story_1.png-a40630de3429bf9e1bf1cd3532ecf56c.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/building/datawhale_house_three_story_1.png"
|
||||||
|
dest_files=["res://.godot/imported/datawhale_house_three_story_1.png-a40630de3429bf9e1bf1cd3532ecf56c.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
assets/sprites/building/datawhale_house_three_story_2.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cvl4gndee3t0n"
|
||||||
|
path="res://.godot/imported/datawhale_house_three_story_2.png-df2ee031e5447ffbed65ac6bac803db9.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/building/datawhale_house_three_story_2.png"
|
||||||
|
dest_files=["res://.godot/imported/datawhale_house_three_story_2.png-df2ee031e5447ffbed65ac6bac803db9.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
assets/sprites/building/datawhale_house_two_story_1.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
@@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://krfed1r4qmnp"
|
uid="uid://csc5qyjif3vl"
|
||||||
path="res://.godot/imported/payer_44_30.png-100395b4756c93dec9ce9baa5c5df0f3.ctex"
|
path="res://.godot/imported/datawhale_house_two_story_1.png-76e2778208e3479c04c73b08468c76d4.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/characters/payer_44_30.png"
|
source_file="res://assets/sprites/building/datawhale_house_two_story_1.png"
|
||||||
dest_files=["res://.godot/imported/payer_44_30.png-100395b4756c93dec9ce9baa5c5df0f3.ctex"]
|
dest_files=["res://.godot/imported/datawhale_house_two_story_1.png-76e2778208e3479c04c73b08468c76d4.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
BIN
assets/sprites/building/datawhale_house_two_story_2.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
@@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://cghab1hkx5lg5"
|
uid="uid://dmgfv1cftsme"
|
||||||
path="res://.godot/imported/player_spritesheet.png-7e76f97a17946ec512358d45f2527da8.ctex"
|
path="res://.godot/imported/datawhale_house_two_story_2.png-bb0f6234ed095fde7809a3e6b884addd.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/characters/player_spritesheet.png"
|
source_file="res://assets/sprites/building/datawhale_house_two_story_2.png"
|
||||||
dest_files=["res://.godot/imported/player_spritesheet.png-7e76f97a17946ec512358d45f2527da8.ctex"]
|
dest_files=["res://.godot/imported/datawhale_house_two_story_2.png-bb0f6234ed095fde7809a3e6b884addd.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
BIN
assets/sprites/building/datawhale_house_variation_1.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
@@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://dyimi462hj6r2"
|
uid="uid://cf7x0l67wunuk"
|
||||||
path="res://.godot/imported/player_spritesheet_backup.png-6d8c966a56b0ced39cf1ecf0c772847f.ctex"
|
path="res://.godot/imported/datawhale_house_variation_1.png-b41961ae39e80d59edd846cc251e1858.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/characters/player_spritesheet_backup.png"
|
source_file="res://assets/sprites/building/datawhale_house_variation_1.png"
|
||||||
dest_files=["res://.godot/imported/player_spritesheet_backup.png-6d8c966a56b0ced39cf1ecf0c772847f.ctex"]
|
dest_files=["res://.godot/imported/datawhale_house_variation_1.png-b41961ae39e80d59edd846cc251e1858.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
BIN
assets/sprites/building/datawhale_house_variation_2.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cj7keute3ukqg"
|
||||||
|
path="res://.godot/imported/datawhale_house_variation_2.png-aadb0ada84a92f6854549c6ed9c7d472.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/building/datawhale_house_variation_2.png"
|
||||||
|
dest_files=["res://.godot/imported/datawhale_house_variation_2.png-aadb0ada84a92f6854549c6ed9c7d472.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
assets/sprites/building/datawhale_house_variation_3.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dmqs5tttttfu2"
|
||||||
|
path="res://.godot/imported/datawhale_house_variation_3.png-f112b3d4595f7f8d227d991047cc4611.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/building/datawhale_house_variation_3.png"
|
||||||
|
dest_files=["res://.godot/imported/datawhale_house_variation_3.png-f112b3d4595f7f8d227d991047cc4611.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
assets/sprites/building/datawhale_house_variation_4.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://btr8upx4fwrv0"
|
||||||
|
path="res://.godot/imported/datawhale_house_variation_4.png-2571fe57a76b75a1da89191cfe4e8fd7.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/building/datawhale_house_variation_4.png"
|
||||||
|
dest_files=["res://.godot/imported/datawhale_house_variation_4.png-2571fe57a76b75a1da89191cfe4e8fd7.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
assets/sprites/building/datawhale_house_variation_5.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://ck71qx8lrrn18"
|
||||||
|
path="res://.godot/imported/datawhale_house_variation_5.png-59996e43196ff3a448d95fd9ffa3d256.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/building/datawhale_house_variation_5.png"
|
||||||
|
dest_files=["res://.godot/imported/datawhale_house_variation_5.png-59996e43196ff3a448d95fd9ffa3d256.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
assets/sprites/building/datawhale_house_variation_6.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cuafv1aw6ig1v"
|
||||||
|
path="res://.godot/imported/datawhale_house_variation_6.png-a54f6449146245b220dbb331d353358d.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/sprites/building/datawhale_house_variation_6.png"
|
||||||
|
dest_files=["res://.godot/imported/datawhale_house_variation_6.png-a54f6449146245b220dbb331d353358d.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
|
||||||
|
Before Width: | Height: | Size: 1.1 MiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://c7jx40leuy6q1"
|
|
||||||
path="res://.godot/imported/board.png-4f7a101e7a1b1cbdc8a75666c78e8907.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/board.png"
|
|
||||||
dest_files=["res://.godot/imported/board.png-4f7a101e7a1b1cbdc8a75666c78e8907.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
|
|
||||||
|
Before Width: | Height: | Size: 5.6 MiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://7j3n0nhg8atb"
|
|
||||||
path="res://.godot/imported/community.png-a8c4bd53b7eaad8a751801ba0eb4ea69.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/community.png"
|
|
||||||
dest_files=["res://.godot/imported/community.png-a8c4bd53b7eaad8a751801ba0eb4ea69.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
|
|
||||||
|
Before Width: | Height: | Size: 458 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://cle66our01dq1"
|
|
||||||
path="res://.godot/imported/community_512_512.png-fa162180b6884ce89074ec9b8b445a11.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/community_512_512.png"
|
|
||||||
dest_files=["res://.godot/imported/community_512_512.png-fa162180b6884ce89074ec9b8b445a11.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
|
|
||||||
|
Before Width: | Height: | Size: 28 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://bxk7qx15ks23n"
|
|
||||||
path="res://.godot/imported/deck_256_111.png-1f5516606f281e4ce47eda14a0f195f6.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/deck_256_111.png"
|
|
||||||
dest_files=["res://.godot/imported/deck_256_111.png-1f5516606f281e4ce47eda14a0f195f6.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
|
|
||||||
|
Before Width: | Height: | Size: 29 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://cuoondqo7wpvm"
|
|
||||||
path="res://.godot/imported/deck_256_93.png-53cc7596920e943ad680f551cecde9c5.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/deck_256_93.png"
|
|
||||||
dest_files=["res://.godot/imported/deck_256_93.png-53cc7596920e943ad680f551cecde9c5.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
|
|
||||||
|
Before Width: | Height: | Size: 1.5 MiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://dth4pwye1huv1"
|
|
||||||
path="res://.godot/imported/deck_2784_1536.png-7209e3c01bcb29b96850c5bfe2118eb5.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/deck_2784_1536.png"
|
|
||||||
dest_files=["res://.godot/imported/deck_2784_1536.png-7209e3c01bcb29b96850c5bfe2118eb5.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
|
|
||||||
|
Before Width: | Height: | Size: 57 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://d3w3fncsm32oi"
|
|
||||||
path="res://.godot/imported/deck_384_167.png-f28a21a5574e4d3fa7c0565d6c292757.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/deck_384_167.png"
|
|
||||||
dest_files=["res://.godot/imported/deck_384_167.png-f28a21a5574e4d3fa7c0565d6c292757.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
|
|
||||||
|
Before Width: | Height: | Size: 83 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://j0twhfkpj15i"
|
|
||||||
path="res://.godot/imported/deck_512_164.png-c98703495d73d104671911f6dada9aca.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/deck_512_164.png"
|
|
||||||
dest_files=["res://.godot/imported/deck_512_164.png-c98703495d73d104671911f6dada9aca.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
|
|
||||||
|
Before Width: | Height: | Size: 37 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://blre1srim52hs"
|
|
||||||
path="res://.godot/imported/deck_512_282.png-ec2cdd543ebb499e3623cd89dff86aa4.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/deck_512_282.png"
|
|
||||||
dest_files=["res://.godot/imported/deck_512_282.png-ec2cdd543ebb499e3623cd89dff86aa4.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
|
|
||||||
|
Before Width: | Height: | Size: 570 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://drdfggxi5ecw7"
|
|
||||||
path="res://.godot/imported/deck_512_512.png-14cca0360b4e43a84ff23febdf688dce.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/deck_512_512.png"
|
|
||||||
dest_files=["res://.godot/imported/deck_512_512.png-14cca0360b4e43a84ff23febdf688dce.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
|
|
||||||
|
Before Width: | Height: | Size: 27 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://ci5myym3wxvej"
|
|
||||||
path="res://.godot/imported/e2f5aff78fae12f979d3456eca0896b4.jpg-09ffb25e15f901ba90adc883741736d3.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/e2f5aff78fae12f979d3456eca0896b4.jpg"
|
|
||||||
dest_files=["res://.godot/imported/e2f5aff78fae12f979d3456eca0896b4.jpg-09ffb25e15f901ba90adc883741736d3.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
|
|
||||||
|
Before Width: | Height: | Size: 78 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://dujutnr03apoj"
|
|
||||||
path="res://.godot/imported/fountain_256_192.png-6fb4e69b74642a426b29631ef7156f53.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/fountain_256_192.png"
|
|
||||||
dest_files=["res://.godot/imported/fountain_256_192.png-6fb4e69b74642a426b29631ef7156f53.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
|
|
||||||
|
Before Width: | Height: | Size: 9.4 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://h1kqvkvshfxo"
|
|
||||||
path="res://.godot/imported/grass_128_128.png-f99428f7721484fc94b70ea8f73a140d.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/grass_128_128.png"
|
|
||||||
dest_files=["res://.godot/imported/grass_128_128.png-f99428f7721484fc94b70ea8f73a140d.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
|
|
||||||
|
Before Width: | Height: | Size: 28 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://dwlnclqw6lsa7"
|
|
||||||
path="res://.godot/imported/grass_256_256.png-480baf97b2b792db085b32018ac813a5.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/grass_256_256.png"
|
|
||||||
dest_files=["res://.godot/imported/grass_256_256.png-480baf97b2b792db085b32018ac813a5.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
|
|
||||||
|
Before Width: | Height: | Size: 2.7 MiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://ccqxsarxnnf4e"
|
|
||||||
path="res://.godot/imported/ground.png-2205e043de9d3b8a38f01788dff375d3.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/ground.png"
|
|
||||||
dest_files=["res://.godot/imported/ground.png-2205e043de9d3b8a38f01788dff375d3.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
|
|
||||||
|
Before Width: | Height: | Size: 71 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://dtev6yddbjtvp"
|
|
||||||
path="res://.godot/imported/house_256_192.png-939b43001a6826dd2fb03b0e500d6b91.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/house_256_192.png"
|
|
||||||
dest_files=["res://.godot/imported/house_256_192.png-939b43001a6826dd2fb03b0e500d6b91.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
|
|
||||||
|
Before Width: | Height: | Size: 125 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://bxmbnywn7pd35"
|
|
||||||
path="res://.godot/imported/house_384_256.png-9c21ec19000d397cf04e3d4c46d9fd67.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/house_384_256.png"
|
|
||||||
dest_files=["res://.godot/imported/house_384_256.png-9c21ec19000d397cf04e3d4c46d9fd67.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
|
|
||||||
|
Before Width: | Height: | Size: 145 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://drl6vecqinsgw"
|
|
||||||
path="res://.godot/imported/house_384_288.png-2c4bb2980ec70d9c801e9d8f5c9da5e2.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/house_384_288.png"
|
|
||||||
dest_files=["res://.godot/imported/house_384_288.png-2c4bb2980ec70d9c801e9d8f5c9da5e2.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
|
|
||||||
|
Before Width: | Height: | Size: 9.4 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://c7v86fkrcb4go"
|
|
||||||
path="res://.godot/imported/river.png-5a4acbf78dd4e08f27a3192f37afc708.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/river.png"
|
|
||||||
dest_files=["res://.godot/imported/river.png-5a4acbf78dd4e08f27a3192f37afc708.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
|
|
||||||
|
Before Width: | Height: | Size: 44 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://df3klfat72qro"
|
|
||||||
path="res://.godot/imported/river2_256_256.png-4b34411e3a9844aea328c2b5fdd9f6d7.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/river2_256_256.png"
|
|
||||||
dest_files=["res://.godot/imported/river2_256_256.png-4b34411e3a9844aea328c2b5fdd9f6d7.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
|
|
||||||
|
Before Width: | Height: | Size: 207 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://5r75q24ww18f"
|
|
||||||
path="res://.godot/imported/river2_512_512.png-af87f8da62bcadc69167d888dc2932d0.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/river2_512_512.png"
|
|
||||||
dest_files=["res://.godot/imported/river2_512_512.png-af87f8da62bcadc69167d888dc2932d0.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
|
|
||||||
|
Before Width: | Height: | Size: 28 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://devfvbybifga6"
|
|
||||||
path="res://.godot/imported/river_256_256.png-9a57f752ac6003da70cffda69b91371a.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/river_256_256.png"
|
|
||||||
dest_files=["res://.godot/imported/river_256_256.png-9a57f752ac6003da70cffda69b91371a.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
|
|
||||||
|
Before Width: | Height: | Size: 76 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://b4wt8paqrevg2"
|
|
||||||
path="res://.godot/imported/river_512_512.png-218f1dc6fae57e80762824a68b0c08f6.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/river_512_512.png"
|
|
||||||
dest_files=["res://.godot/imported/river_512_512.png-218f1dc6fae57e80762824a68b0c08f6.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
|
|
||||||
|
Before Width: | Height: | Size: 255 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://bjcij2ncikeyw"
|
|
||||||
path="res://.godot/imported/room_512_384.png-339d4ab4d8dc5972ef1c8a09d0380694.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/room_512_384.png"
|
|
||||||
dest_files=["res://.godot/imported/room_512_384.png-339d4ab4d8dc5972ef1c8a09d0380694.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
|
|
||||||
|
Before Width: | Height: | Size: 569 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://icto1uyw4hj1"
|
|
||||||
path="res://.godot/imported/standard_brick.png.png-f806a78b5dfedf81aa2e413ced30aa6a.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/standard_brick.png.png"
|
|
||||||
dest_files=["res://.godot/imported/standard_brick.png.png-f806a78b5dfedf81aa2e413ced30aa6a.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
|
|
||||||
|
Before Width: | Height: | Size: 7.1 KiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://baa5wkuyqouh6"
|
|
||||||
path="res://.godot/imported/standard_brick_128_128.jpg-0dc76f792db60d64e5610aa75364c4ef.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/standard_brick_128_128.jpg"
|
|
||||||
dest_files=["res://.godot/imported/standard_brick_128_128.jpg-0dc76f792db60d64e5610aa75364c4ef.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
|
|
||||||
|
Before Width: | Height: | Size: 3.9 MiB |
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://balpojbve2n4f"
|
|
||||||
path="res://.godot/imported/water.png-28a245d0248e5e7513f6a266dcca901f.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/sprites/environment/water.png"
|
|
||||||
dest_files=["res://.godot/imported/water.png-28a245d0248e5e7513f6a266dcca901f.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
assets/sprites/tileset/whale-town-fence-iron.png
Normal file
|
After Width: | Height: | Size: 613 B |
BIN
assets/sprites/tileset/whale-town-fence-wood.png
Normal file
|
After Width: | Height: | Size: 897 B |
71
claude.md
@@ -27,10 +27,10 @@
|
|||||||
|
|
||||||
## 4. 📋 Coding Standards (The Law)
|
## 4. 📋 Coding Standards (The Law)
|
||||||
- **Type Safety**: ALWAYS use strict static typing: `var speed: float = 100.0`, `func _ready() -> void`.
|
- **Type Safety**: ALWAYS use strict static typing: `var speed: float = 100.0`, `func _ready() -> void`.
|
||||||
- **Naming Conventions**:
|
- **Naming Conventions**:
|
||||||
- `class_name PascalCase` at the top of every script.
|
- `class_name PascalCase` at the top of every script.
|
||||||
- Variables/Functions: `camelCase` (e.g., `var moveSpeed`, `func updateMovement()`). Constants: `UPPER_CASE`.
|
- Variables/Functions: `snake_case`. Constants: `SCREAMING_SNAKE_CASE`.
|
||||||
- Private members: Prefix with underscore `_` (e.g., `var _velocity: Vector2`).
|
- Private members: Prefix with underscore `_` (e.g., `var _health: int`).
|
||||||
- **Node Access**: Use `%UniqueName` for UI and internal scene components.
|
- **Node Access**: Use `%UniqueName` for UI and internal scene components.
|
||||||
- **Signals**: Use "Signal Up, Call Down". Parent calls child methods; Child emits signals.
|
- **Signals**: Use "Signal Up, Call Down". Parent calls child methods; Child emits signals.
|
||||||
- **Forbidden Patterns**:
|
- **Forbidden Patterns**:
|
||||||
@@ -72,74 +72,13 @@
|
|||||||
assert_signal_emitted(EventSystem, "event_raised")
|
assert_signal_emitted(EventSystem, "event_raised")
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🔄 8. Standard Development Workflow (MANDATORY)
|
## 8. 🧘 The Zen of Development
|
||||||
|
|
||||||
**CRITICAL**: When performing ANY development task (implementing features, fixing bugs, creating scenes), you MUST follow this 7-step standardized workflow:
|
|
||||||
|
|
||||||
### Quick Start: Use the Skill (Recommended) ⭐
|
|
||||||
```bash
|
|
||||||
/whaletown-developer [任务描述]
|
|
||||||
```
|
|
||||||
Example: `/whaletown-developer 实现玩家二段跳功能`
|
|
||||||
|
|
||||||
The skill automates the entire 7-step process and enforces all quality standards.
|
|
||||||
|
|
||||||
### The 7-Step Workflow
|
|
||||||
|
|
||||||
```
|
|
||||||
Step 1: Architecture Analysis → Read docs/02-开发规范/架构与通信规范.md
|
|
||||||
Step 2: Implementation → Follow layered architecture, type safety, EventSystem
|
|
||||||
Step 3: Comment Validation → Read docs/02-开发规范/代码注释规范.md
|
|
||||||
Step 4: Naming Validation → Read docs/02-开发规范/命名规范.md
|
|
||||||
Step 5: Test Writing → Read docs/03-技术实现/测试指南.md
|
|
||||||
Step 6: Test Execution → Run: godot --headless -s addons/gut/gut_cmdline.gd
|
|
||||||
Step 7: Git Commit → Read docs/02-开发规范/Git提交规范.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### Workflow Enforcement Rules
|
|
||||||
|
|
||||||
1. **Never Skip Steps**: All 7 steps are mandatory for every development task
|
|
||||||
2. **Read Specs First**: Each step requires reading the corresponding specification document
|
|
||||||
3. **Use TodoWrite**: Track progress through all 7 steps using TodoWrite tool
|
|
||||||
4. **Mark Completed**: Mark each step as completed immediately after finishing
|
|
||||||
5. **Quality Gates**: Cannot proceed to next step until current step passes validation
|
|
||||||
|
|
||||||
### Naming Convention Clarification
|
|
||||||
|
|
||||||
**IMPORTANT**: The project uses **camelCase** for variables/functions, NOT snake_case:
|
|
||||||
- ✅ Correct: `var moveSpeed: float`, `func updateMovement()`
|
|
||||||
- ❌ Incorrect: `var move_speed: float`, `func update_movement()`
|
|
||||||
|
|
||||||
See `docs/02-开发规范/命名规范.md` for complete details.
|
|
||||||
|
|
||||||
### Quality Checklist (Every Development Task)
|
|
||||||
|
|
||||||
- [ ] File location follows layered architecture (_Core, scenes, UI)
|
|
||||||
- [ ] Uses EventSystem for cross-module communication
|
|
||||||
- [ ] Event names added to EventNames.gd
|
|
||||||
- [ ] All variables/functions have type annotations
|
|
||||||
- [ ] Naming: PascalCase (classes), camelCase (vars/funcs), UPPER_CASE (constants)
|
|
||||||
- [ ] File header comment complete
|
|
||||||
- [ ] Public functions have complete documentation
|
|
||||||
- [ ] Unit tests created and passing
|
|
||||||
- [ ] Git commit message follows specification
|
|
||||||
- [ ] No Godot 3.x syntax (await not yield, @onready cached)
|
|
||||||
|
|
||||||
### Reference Documents
|
|
||||||
|
|
||||||
- **Full Workflow**: `docs/AI_docs/workflows/standard_development_workflow.md`
|
|
||||||
- **Quick Checklist**: `.claude/skills/whaletown-developer/references/checklist.md`
|
|
||||||
- **Skill Definition**: `.claude/skills/whaletown-developer/SKILL.md`
|
|
||||||
|
|
||||||
**Remember**: Consistency through automation. Use `/whaletown-developer` to ensure no steps are missed.
|
|
||||||
|
|
||||||
## 9. 🧘 The Zen of Development
|
|
||||||
- **Juice or Death**: Every interaction (UI popup, NPC talk) MUST have a Tween placeholder.
|
- **Juice or Death**: Every interaction (UI popup, NPC talk) MUST have a Tween placeholder.
|
||||||
- **Zero Magic Numbers**: All speeds/timers MUST be `@export` or defined in `Config/`.
|
- **Zero Magic Numbers**: All speeds/timers MUST be `@export` or defined in `Config/`.
|
||||||
- **Simplicity**: If a function does two things, split it.
|
- **Simplicity**: If a function does two things, split it.
|
||||||
- **Back of the Fence**: Hidden logic (like ResponseHandler.gd) must be as clean as the HUD.
|
- **Back of the Fence**: Hidden logic (like ResponseHandler.gd) must be as clean as the HUD.
|
||||||
|
|
||||||
## 10. 📝 Code Template (Entity Pattern)
|
## 9. 📝 Code Template (Entity Pattern)
|
||||||
```gdscript
|
```gdscript
|
||||||
extends CharacterBody2D
|
extends CharacterBody2D
|
||||||
class_name Player
|
class_name Player
|
||||||
|
|||||||
@@ -1,663 +0,0 @@
|
|||||||
# WhaleTown 标准开发工作流
|
|
||||||
|
|
||||||
> **AI 编程助手专用**:本文档定义了 WhaleTown 项目的标准化开发流程,确保所有开发者遵循统一的规范和质量标准。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 工作流概览
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────────┐
|
|
||||||
│ WhaleTown 7步标准开发流程 │
|
|
||||||
└─────────────────────────────────────────────────────────────────┘
|
|
||||||
|
|
||||||
Step 1: 架构分析 → 读取架构规范,确定文件位置和通信方式
|
|
||||||
↓
|
|
||||||
Step 2: 功能实现 → 按规范编码,遵循类型安全和事件驱动
|
|
||||||
↓
|
|
||||||
Step 3: 注释规范检查 → 验证文件头、函数注释的完整性
|
|
||||||
↓
|
|
||||||
Step 4: 命名规范检查 → 验证PascalCase/camelCase/UPPER_CASE
|
|
||||||
↓
|
|
||||||
Step 5: 测试代码编写 → 创建GUT单元测试,覆盖核心功能
|
|
||||||
↓
|
|
||||||
Step 6: 测试验证 → 运行测试,确保所有测试通过
|
|
||||||
↓
|
|
||||||
Step 7: Git 提交 → 生成符合规范的提交信息并提交
|
|
||||||
|
|
||||||
总耗时:约 20-40 分钟(根据功能复杂度)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📖 使用方式
|
|
||||||
|
|
||||||
### 方式一:使用 Skill(推荐)⭐
|
|
||||||
|
|
||||||
最简单、最高效的方式是使用 `whaletown-developer` skill:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
/whaletown-developer 实现玩家二段跳功能
|
|
||||||
```
|
|
||||||
|
|
||||||
Skill 会自动执行全部 7 步流程,确保不遗漏任何步骤。
|
|
||||||
|
|
||||||
### 方式二:手动执行流程
|
|
||||||
|
|
||||||
如果需要手动控制流程,请按照以下步骤逐步执行,并参考本文档的详细说明。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 详细步骤说明
|
|
||||||
|
|
||||||
### Step 1: 架构分析(5分钟)
|
|
||||||
|
|
||||||
**目标**: 理解功能在项目中的位置和通信方式
|
|
||||||
|
|
||||||
**规范文档**: `docs/02-开发规范/架构与通信规范.md`
|
|
||||||
|
|
||||||
#### 执行清单
|
|
||||||
|
|
||||||
- [ ] 读取架构规范文档
|
|
||||||
- [ ] 确定文件位置(_Core, scenes, UI)
|
|
||||||
- [ ] 确定通信方式(EventSystem)
|
|
||||||
- [ ] 列出依赖的管理器/系统
|
|
||||||
- [ ] 设计事件定义(如需要)
|
|
||||||
|
|
||||||
#### 分层架构决策树
|
|
||||||
|
|
||||||
```
|
|
||||||
功能是核心系统(管理器/全局系统)?
|
|
||||||
├─ 是 → 放在 _Core/managers/ 或 _Core/systems/
|
|
||||||
└─ 否 → 功能是游戏场景相关?
|
|
||||||
├─ 是 → 放在 scenes/Maps/, scenes/Entities/, scenes/Components/
|
|
||||||
└─ 否 → 功能是UI界面?
|
|
||||||
├─ 是 → 放在 scenes/ui/
|
|
||||||
└─ 否 → 重新分析功能定位
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 通信方式决策
|
|
||||||
|
|
||||||
- **同模块内通信**: 父调用子方法(向下),子发出信号(向上)
|
|
||||||
- **跨模块通信**: MUST 使用 EventSystem
|
|
||||||
- **事件定义位置**: 所有事件名称定义在 `_Core/EventNames.gd`
|
|
||||||
|
|
||||||
#### 示例:玩家二段跳功能
|
|
||||||
|
|
||||||
```gdscript
|
|
||||||
# 架构分析结果
|
|
||||||
文件位置: scenes/Entities/Player/Player.gd # 游戏场景层
|
|
||||||
通信方式: EventSystem.emit_event() # 跨模块通信
|
|
||||||
依赖: EventSystem, Input # 系统依赖
|
|
||||||
事件: PLAYER_DOUBLE_JUMPED # 需要在 EventNames.gd 中定义
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 2: 功能实现(10-20分钟)
|
|
||||||
|
|
||||||
**目标**: 按照规范实现功能代码
|
|
||||||
|
|
||||||
**规范文档**: `docs/02-开发规范/架构与通信规范.md`, `claude.md`
|
|
||||||
|
|
||||||
#### 执行清单
|
|
||||||
|
|
||||||
- [ ] 创建或修改文件在正确位置
|
|
||||||
- [ ] 所有变量和函数有类型注解
|
|
||||||
- [ ] 使用 Godot 4.2+ 语法(await, @onready)
|
|
||||||
- [ ] 通过 EventSystem 进行跨模块通信
|
|
||||||
- [ ] 如有新事件,添加到 EventNames.gd
|
|
||||||
- [ ] 使用 Nearest 滤镜(Sprite2D/TileMap)
|
|
||||||
|
|
||||||
#### 核心规范要点
|
|
||||||
|
|
||||||
**1. 严格类型安全**
|
|
||||||
```gdscript
|
|
||||||
# ✅ 正确
|
|
||||||
var speed: float = 200.0
|
|
||||||
var currentHealth: int = 100
|
|
||||||
func move(delta: float) -> void:
|
|
||||||
func getHealth() -> int:
|
|
||||||
|
|
||||||
# ❌ 错误
|
|
||||||
var speed = 200.0 # 缺少类型注解
|
|
||||||
func move(delta): # 缺少参数和返回值类型
|
|
||||||
```
|
|
||||||
|
|
||||||
**2. Godot 4.2+ 语法**
|
|
||||||
```gdscript
|
|
||||||
# ✅ 正确
|
|
||||||
await get_tree().create_timer(1.0).timeout
|
|
||||||
@onready var sprite: Sprite2D = $Sprite2D
|
|
||||||
|
|
||||||
# ❌ 错误
|
|
||||||
yield(get_tree().create_timer(1.0), "timeout") # Godot 3.x
|
|
||||||
var sprite = get_node("Sprite2D") # 应在 _ready 外缓存
|
|
||||||
```
|
|
||||||
|
|
||||||
**3. EventSystem 通信**
|
|
||||||
```gdscript
|
|
||||||
# 发送事件
|
|
||||||
EventSystem.emit_event(EventNames.PLAYER_DOUBLE_JUMPED, {
|
|
||||||
"position": global_position,
|
|
||||||
"direction": velocity.normalized()
|
|
||||||
})
|
|
||||||
|
|
||||||
# 监听事件
|
|
||||||
func _ready() -> void:
|
|
||||||
EventSystem.connect_event(EventNames.INTERACT_PRESSED, _on_interact_pressed)
|
|
||||||
|
|
||||||
func _on_interact_pressed(data: Dictionary = {}) -> void:
|
|
||||||
# 处理交互逻辑
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
|
|
||||||
**4. 自动加载限制**
|
|
||||||
```gdscript
|
|
||||||
# ✅ 正确:在高层组件中访问
|
|
||||||
func _ready() -> void:
|
|
||||||
var current_state = GameManager.get_game_state()
|
|
||||||
|
|
||||||
# ❌ 错误:在底层实体(Player, NPC)中直接访问
|
|
||||||
func _ready() -> void:
|
|
||||||
GameManager.register_player(self) # 不应该这样做
|
|
||||||
|
|
||||||
# ✅ 正确:底层实体使用事件
|
|
||||||
func _ready() -> void:
|
|
||||||
EventSystem.emit_event(EventNames.PLAYER_SPAWNED, {"player": self})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 3: 注释规范检查(3-5分钟)
|
|
||||||
|
|
||||||
**目标**: 确保代码注释完整且符合规范
|
|
||||||
|
|
||||||
**规范文档**: `docs/02-开发规范/代码注释规范.md`
|
|
||||||
|
|
||||||
#### 执行清单
|
|
||||||
|
|
||||||
- [ ] 文件头注释完整
|
|
||||||
- [ ] 所有公共函数有完整注释
|
|
||||||
- [ ] 复杂逻辑有行内注释
|
|
||||||
- [ ] 使用 TODO/FIXME/NOTE 标记(如需要)
|
|
||||||
|
|
||||||
#### 文件头注释模板
|
|
||||||
|
|
||||||
```gdscript
|
|
||||||
# ============================================================================
|
|
||||||
# 文件名: PlayerController.gd
|
|
||||||
# 作用: 玩家角色控制器,处理玩家输入和移动逻辑
|
|
||||||
#
|
|
||||||
# 主要功能:
|
|
||||||
# - 处理键盘和手柄输入
|
|
||||||
# - 控制角色移动和跳跃
|
|
||||||
# - 管理角色状态切换
|
|
||||||
# - 实现二段跳功能
|
|
||||||
#
|
|
||||||
# 依赖: EventSystem, InputManager
|
|
||||||
# 作者: [开发者名称]
|
|
||||||
# 创建时间: 2025-01-03
|
|
||||||
# ============================================================================
|
|
||||||
|
|
||||||
extends CharacterBody2D
|
|
||||||
class_name PlayerController
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 函数注释模板
|
|
||||||
|
|
||||||
```gdscript
|
|
||||||
# 执行二段跳
|
|
||||||
#
|
|
||||||
# 在玩家空中时允许执行一次额外的跳跃
|
|
||||||
# 二段跳的力度为普通跳跃的80%
|
|
||||||
#
|
|
||||||
# 参数: 无
|
|
||||||
#
|
|
||||||
# 返回值: 无
|
|
||||||
#
|
|
||||||
# 使用示例:
|
|
||||||
# if Input.is_action_just_pressed("jump") and canDoubleJump:
|
|
||||||
# performDoubleJump()
|
|
||||||
#
|
|
||||||
# 注意事项:
|
|
||||||
# - 只能在空中且 canDoubleJump 为 true 时调用
|
|
||||||
# - 执行后会将 canDoubleJump 设置为 false
|
|
||||||
# - 落地时会重置 canDoubleJump 为 true
|
|
||||||
func performDoubleJump() -> void:
|
|
||||||
velocity.y = JUMP_FORCE * 0.8
|
|
||||||
canDoubleJump = false
|
|
||||||
EventSystem.emit_event(EventNames.PLAYER_DOUBLE_JUMPED, {
|
|
||||||
"position": global_position
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 4: 命名规范检查(2-3分钟)
|
|
||||||
|
|
||||||
**目标**: 验证所有命名符合项目规范
|
|
||||||
|
|
||||||
**规范文档**: `docs/02-开发规范/命名规范.md`
|
|
||||||
|
|
||||||
#### 执行清单
|
|
||||||
|
|
||||||
- [ ] 类名使用 PascalCase
|
|
||||||
- [ ] 变量/函数使用 camelCase
|
|
||||||
- [ ] 常量使用 UPPER_CASE
|
|
||||||
- [ ] 私有成员使用下划线前缀
|
|
||||||
- [ ] 文件命名符合规范
|
|
||||||
|
|
||||||
#### 命名规范速查表
|
|
||||||
|
|
||||||
| 元素类型 | 命名规范 | 示例 |
|
|
||||||
|---------|---------|------|
|
|
||||||
| **类名** | PascalCase | `class_name PlayerController` |
|
|
||||||
| **变量** | camelCase | `var moveSpeed: float` |
|
|
||||||
| **私有变量** | _camelCase | `var _velocity: Vector2` |
|
|
||||||
| **函数** | camelCase | `func updateMovement()` |
|
|
||||||
| **私有函数** | _camelCase | `func _calculateDamage()` |
|
|
||||||
| **常量** | UPPER_CASE | `const MAX_HEALTH: int = 100` |
|
|
||||||
| **枚举类型** | PascalCase | `enum PlayerState` |
|
|
||||||
| **枚举值** | UPPER_CASE | `IDLE, WALKING, RUNNING` |
|
|
||||||
| **脚本文件** | PascalCase.gd | `PlayerController.gd` |
|
|
||||||
| **场景文件** | snake_case_scene.tscn | `main_scene.tscn` |
|
|
||||||
| **预制体** | snake_case_prefab.tscn | `player_prefab.tscn` |
|
|
||||||
|
|
||||||
#### 常见错误检查
|
|
||||||
|
|
||||||
```gdscript
|
|
||||||
# ✅ 正确
|
|
||||||
class_name PlayerController
|
|
||||||
const MAX_JUMPS: int = 2
|
|
||||||
var moveSpeed: float = 200.0
|
|
||||||
var canDoubleJump: bool = true
|
|
||||||
var _velocity: Vector2 = Vector2.ZERO
|
|
||||||
func performDoubleJump() -> void:
|
|
||||||
func _calculateJumpForce() -> float:
|
|
||||||
|
|
||||||
# ❌ 错误
|
|
||||||
class_name player_controller # 应使用 PascalCase
|
|
||||||
const maxJumps: int = 2 # 常量应使用 UPPER_CASE
|
|
||||||
var MoveSpeed: float = 200.0 # 变量应使用 camelCase
|
|
||||||
var can_double_jump: bool = true # 不要使用 snake_case
|
|
||||||
func PerformDoubleJump(): # 函数应使用 camelCase
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 5: 测试代码编写(5-10分钟)
|
|
||||||
|
|
||||||
**目标**: 为实现的功能创建单元测试
|
|
||||||
|
|
||||||
**规范文档**: `docs/03-技术实现/测试指南.md`
|
|
||||||
|
|
||||||
#### 执行清单
|
|
||||||
|
|
||||||
- [ ] 创建测试文件 `tests/unit/test_[name].gd`
|
|
||||||
- [ ] 测试文件继承自 GutTest
|
|
||||||
- [ ] 实现 before_each 和 after_each
|
|
||||||
- [ ] 编写核心功能测试
|
|
||||||
- [ ] 编写边界条件测试
|
|
||||||
|
|
||||||
#### 测试文件模板
|
|
||||||
|
|
||||||
```gdscript
|
|
||||||
# tests/unit/test_player_double_jump.gd
|
|
||||||
extends GutTest
|
|
||||||
|
|
||||||
## PlayerController 二段跳功能单元测试
|
|
||||||
|
|
||||||
var player: PlayerController
|
|
||||||
|
|
||||||
func before_each():
|
|
||||||
# 每个测试前创建新的 Player 实例
|
|
||||||
player = preload("res://scenes/Entities/Player/PlayerController.gd").new()
|
|
||||||
add_child(player)
|
|
||||||
player.initialize()
|
|
||||||
|
|
||||||
func after_each():
|
|
||||||
# 每个测试后清理
|
|
||||||
player.queue_free()
|
|
||||||
|
|
||||||
func test_can_double_jump_after_first_jump():
|
|
||||||
# 测试:第一次跳跃后可以二段跳
|
|
||||||
player.performJump()
|
|
||||||
assert_true(player.canDoubleJump, "Should be able to double jump after first jump")
|
|
||||||
|
|
||||||
func test_cannot_triple_jump():
|
|
||||||
# 测试:不能三段跳
|
|
||||||
player.performJump()
|
|
||||||
player.performDoubleJump()
|
|
||||||
assert_false(player.canDoubleJump, "Should not be able to triple jump")
|
|
||||||
|
|
||||||
func test_reset_double_jump_on_ground():
|
|
||||||
# 测试:落地后重置二段跳
|
|
||||||
player.performJump()
|
|
||||||
player.performDoubleJump()
|
|
||||||
player._on_landed() # 模拟落地
|
|
||||||
assert_true(player.canDoubleJump, "Double jump should reset when landing")
|
|
||||||
|
|
||||||
func test_double_jump_emits_event():
|
|
||||||
# 测试:二段跳发出事件
|
|
||||||
watch_signals(EventSystem)
|
|
||||||
player.performDoubleJump()
|
|
||||||
assert_signal_emitted(EventSystem, "event_raised")
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 测试覆盖建议
|
|
||||||
|
|
||||||
1. **正常流程**: 功能的标准使用场景
|
|
||||||
2. **边界条件**: 极限值、特殊输入
|
|
||||||
3. **错误处理**: 异常情况、错误输入
|
|
||||||
4. **事件通信**: 验证事件正确发送和接收
|
|
||||||
5. **状态管理**: 状态转换的正确性
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 6: 测试验证(2-3分钟)
|
|
||||||
|
|
||||||
**目标**: 运行测试确保代码质量
|
|
||||||
|
|
||||||
**规范文档**: `docs/03-技术实现/测试指南.md`
|
|
||||||
|
|
||||||
#### 执行清单
|
|
||||||
|
|
||||||
- [ ] 运行 GUT 测试命令
|
|
||||||
- [ ] 所有测试通过
|
|
||||||
- [ ] 如有失败,修复并重新测试
|
|
||||||
- [ ] 确认测试覆盖核心功能
|
|
||||||
|
|
||||||
#### 运行测试
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 运行所有测试
|
|
||||||
godot --headless -s addons/gut/gut_cmdline.gd -gdir=res://tests/ -ginclude_subdirs
|
|
||||||
|
|
||||||
# 运行特定测试文件
|
|
||||||
godot --headless -s addons/gut/gut_cmdline.gd -gtest=res://tests/unit/test_player_double_jump.gd
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 测试结果分析
|
|
||||||
|
|
||||||
**所有测试通过**:
|
|
||||||
```
|
|
||||||
========================
|
|
||||||
= PASSED: 4 of 4 tests =
|
|
||||||
========================
|
|
||||||
```
|
|
||||||
✅ 进入下一步
|
|
||||||
|
|
||||||
**部分测试失败**:
|
|
||||||
```
|
|
||||||
==========================
|
|
||||||
= FAILED: 1 of 4 tests =
|
|
||||||
==========================
|
|
||||||
FAILED: test_cannot_triple_jump
|
|
||||||
Expected: false
|
|
||||||
Got: true
|
|
||||||
```
|
|
||||||
❌ 修复问题后重新测试
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 7: Git 提交(3-5分钟)
|
|
||||||
|
|
||||||
**目标**: 生成符合规范的 Git 提交信息
|
|
||||||
|
|
||||||
**规范文档**: `docs/02-开发规范/Git提交规范.md`
|
|
||||||
|
|
||||||
#### 执行清单
|
|
||||||
|
|
||||||
- [ ] 确定提交类型(feat/fix/docs/refactor等)
|
|
||||||
- [ ] 生成规范的提交信息
|
|
||||||
- [ ] 使用中文冒号(:)
|
|
||||||
- [ ] 描述简洁明了
|
|
||||||
- [ ] 遵循"一次提交只做一件事"
|
|
||||||
|
|
||||||
#### 提交类型选择
|
|
||||||
|
|
||||||
| 改动类型 | 提交类型 | 示例 |
|
|
||||||
|---------|---------|------|
|
|
||||||
| 新功能 | `feat` | `feat:实现玩家二段跳功能` |
|
|
||||||
| Bug修复 | `fix` | `fix:修复跳跃碰撞检测问题` |
|
|
||||||
| 文档更新 | `docs` | `docs:更新架构规范文档` |
|
|
||||||
| 代码重构 | `refactor` | `refactor:重构移动系统逻辑` |
|
|
||||||
| 性能优化 | `perf` | `perf:优化物理计算性能` |
|
|
||||||
| 测试相关 | `test` | `test:添加二段跳单元测试` |
|
|
||||||
| 场景文件 | `scene` | `scene:创建战斗场景` |
|
|
||||||
| UI界面 | `ui` | `ui:设计暂停菜单界面` |
|
|
||||||
|
|
||||||
#### 提交示例
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 示例1:新功能(完整流程)
|
|
||||||
git add scenes/Entities/Player/PlayerController.gd
|
|
||||||
git add _Core/EventNames.gd
|
|
||||||
git add tests/unit/test_player_double_jump.gd
|
|
||||||
git commit -m "feat:实现玩家二段跳功能"
|
|
||||||
|
|
||||||
# 示例2:Bug修复
|
|
||||||
git add scenes/Entities/Player/PlayerController.gd
|
|
||||||
git commit -m "fix:修复二段跳状态未重置的问题"
|
|
||||||
|
|
||||||
# 示例3:测试添加
|
|
||||||
git add tests/unit/test_player_movement.gd
|
|
||||||
git commit -m "test:添加玩家移动系统单元测试"
|
|
||||||
|
|
||||||
# 示例4:带详细描述的提交
|
|
||||||
git commit -m "feat:实现玩家二段跳功能
|
|
||||||
|
|
||||||
- 添加二段跳核心逻辑
|
|
||||||
- 在空中允许执行一次额外跳跃
|
|
||||||
- 二段跳力度为普通跳跃的80%
|
|
||||||
- 发送 PLAYER_DOUBLE_JUMPED 事件
|
|
||||||
- 落地时重置二段跳能力"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 多类型改动处理
|
|
||||||
|
|
||||||
**⚠️ 如果同时有多种类型改动,必须拆分提交:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# ❌ 错误:混合提交
|
|
||||||
git commit -m "fix + feat:修复Bug并添加新功能"
|
|
||||||
|
|
||||||
# ✅ 正确:拆分提交
|
|
||||||
git add PlayerController.gd # 只暂存 Bug 修复部分
|
|
||||||
git commit -m "fix:修复跳跃碰撞检测问题"
|
|
||||||
|
|
||||||
git add PlayerController.gd # 暂存新功能部分
|
|
||||||
git commit -m "feat:实现玩家二段跳功能"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ 完整工作流检查清单
|
|
||||||
|
|
||||||
在完成开发任务后,使用此清单验证是否执行了全部流程:
|
|
||||||
|
|
||||||
### 总览检查
|
|
||||||
- [ ] ✅ Step 1: 架构分析完成
|
|
||||||
- [ ] ✅ Step 2: 功能实现完成
|
|
||||||
- [ ] ✅ Step 3: 注释规范检查通过
|
|
||||||
- [ ] ✅ Step 4: 命名规范检查通过
|
|
||||||
- [ ] ✅ Step 5: 测试代码编写完成
|
|
||||||
- [ ] ✅ Step 6: 测试验证通过
|
|
||||||
- [ ] ✅ Step 7: Git 提交完成
|
|
||||||
|
|
||||||
### 详细检查
|
|
||||||
- [ ] 文件位置符合分层架构(_Core, scenes, UI)
|
|
||||||
- [ ] 使用 EventSystem 进行跨模块通信
|
|
||||||
- [ ] 新事件已添加到 EventNames.gd
|
|
||||||
- [ ] 所有变量和函数有类型注解
|
|
||||||
- [ ] 使用 Godot 4.2+ 语法(await, @onready)
|
|
||||||
- [ ] 命名规范正确(PascalCase/camelCase/UPPER_CASE)
|
|
||||||
- [ ] 文件头注释完整
|
|
||||||
- [ ] 公共函数有完整文档注释
|
|
||||||
- [ ] 创建了单元测试文件
|
|
||||||
- [ ] 所有测试通过
|
|
||||||
- [ ] Git 提交信息符合规范
|
|
||||||
- [ ] Sprite2D/TileMap 使用 Nearest 滤镜
|
|
||||||
- [ ] 未违反自动加载限制
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 最佳实践
|
|
||||||
|
|
||||||
### 使用 TodoWrite 追踪进度
|
|
||||||
|
|
||||||
在执行工作流时,使用 TodoWrite 工具追踪每个步骤:
|
|
||||||
|
|
||||||
```gdscript
|
|
||||||
TodoWrite.create_todos([
|
|
||||||
"Step 1: 架构分析 - 读取架构规范",
|
|
||||||
"Step 2: 功能实现 - 按规范编码",
|
|
||||||
"Step 3: 注释规范检查",
|
|
||||||
"Step 4: 命名规范检查",
|
|
||||||
"Step 5: 测试代码编写",
|
|
||||||
"Step 6: 测试验证 - 运行测试",
|
|
||||||
"Step 7: Git 提交 - 生成提交信息"
|
|
||||||
])
|
|
||||||
```
|
|
||||||
|
|
||||||
每完成一步,立即标记为 `completed`。
|
|
||||||
|
|
||||||
### 常见错误避免
|
|
||||||
|
|
||||||
1. **跳过测试**: 测试不是可选项,必须为核心功能编写测试
|
|
||||||
2. **混合提交**: 不要在一次提交中混合 fix 和 feat
|
|
||||||
3. **命名不一致**: 严格遵循 PascalCase/camelCase/UPPER_CASE
|
|
||||||
4. **缺少注释**: 公共函数必须有完整注释
|
|
||||||
5. **直接访问单例**: 底层实体使用事件,不直接访问 GameManager
|
|
||||||
|
|
||||||
### 提升效率技巧
|
|
||||||
|
|
||||||
1. **使用 Skill**: 调用 `/whaletown-developer` 自动执行全流程
|
|
||||||
2. **模板复用**: 参考现有代码的结构和注释模板
|
|
||||||
3. **增量提交**: 不要等所有功能完成才提交,完成一个逻辑单元就提交
|
|
||||||
4. **快速参考**: 使用 `.claude/skills/whaletown-developer/references/checklist.md` 快速自检
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 相关文档索引
|
|
||||||
|
|
||||||
### 核心规范文档
|
|
||||||
- **架构与通信**: `docs/02-开发规范/架构与通信规范.md`
|
|
||||||
- **代码注释**: `docs/02-开发规范/代码注释规范.md`
|
|
||||||
- **命名规范**: `docs/02-开发规范/命名规范.md`
|
|
||||||
- **Git 提交**: `docs/02-开发规范/Git提交规范.md`
|
|
||||||
- **测试指南**: `docs/03-技术实现/测试指南.md`
|
|
||||||
- **项目指令**: `claude.md` (根目录)
|
|
||||||
|
|
||||||
### 辅助文档
|
|
||||||
- **Skill 指令**: `.claude/skills/whaletown-developer/SKILL.md`
|
|
||||||
- **快速检查清单**: `.claude/skills/whaletown-developer/references/checklist.md`
|
|
||||||
- **功能开发流程**: `docs/AI_docs/workflows/feature_development.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💡 示例:完整开发流程
|
|
||||||
|
|
||||||
### 任务:实现玩家二段跳功能
|
|
||||||
|
|
||||||
#### Step 1: 架构分析 (3分钟)
|
|
||||||
```
|
|
||||||
读取: docs/02-开发规范/架构与通信规范.md
|
|
||||||
分析结果:
|
|
||||||
- 文件位置: scenes/Entities/Player/PlayerController.gd
|
|
||||||
- 通信方式: EventSystem
|
|
||||||
- 依赖: EventSystem, Input
|
|
||||||
- 事件: PLAYER_DOUBLE_JUMPED (需添加到 EventNames.gd)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 2: 功能实现 (15分钟)
|
|
||||||
```gdscript
|
|
||||||
# scenes/Entities/Player/PlayerController.gd
|
|
||||||
extends CharacterBody2D
|
|
||||||
class_name PlayerController
|
|
||||||
|
|
||||||
const JUMP_FORCE: float = -400.0
|
|
||||||
const MAX_DOUBLE_JUMPS: int = 1
|
|
||||||
|
|
||||||
var canDoubleJump: bool = true
|
|
||||||
var doubleJumpCount: int = 0
|
|
||||||
|
|
||||||
func performDoubleJump() -> void:
|
|
||||||
if not canDoubleJump or doubleJumpCount >= MAX_DOUBLE_JUMPS:
|
|
||||||
return
|
|
||||||
|
|
||||||
velocity.y = JUMP_FORCE * 0.8
|
|
||||||
doubleJumpCount += 1
|
|
||||||
canDoubleJump = false
|
|
||||||
|
|
||||||
EventSystem.emit_event(EventNames.PLAYER_DOUBLE_JUMPED, {
|
|
||||||
"position": global_position
|
|
||||||
})
|
|
||||||
|
|
||||||
func _on_landed() -> void:
|
|
||||||
doubleJumpCount = 0
|
|
||||||
canDoubleJump = true
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 3-4: 注释和命名检查 (5分钟)
|
|
||||||
```
|
|
||||||
✅ 文件头注释完整
|
|
||||||
✅ 函数注释完整
|
|
||||||
✅ 类名 PascalCase: PlayerController
|
|
||||||
✅ 变量 camelCase: canDoubleJump
|
|
||||||
✅ 常量 UPPER_CASE: MAX_DOUBLE_JUMPS
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 5: 编写测试 (8分钟)
|
|
||||||
```gdscript
|
|
||||||
# tests/unit/test_player_double_jump.gd
|
|
||||||
extends GutTest
|
|
||||||
|
|
||||||
var player: PlayerController
|
|
||||||
|
|
||||||
func before_each():
|
|
||||||
player = PlayerController.new()
|
|
||||||
add_child(player)
|
|
||||||
|
|
||||||
func test_can_double_jump():
|
|
||||||
assert_true(player.canDoubleJump)
|
|
||||||
|
|
||||||
func test_double_jump_resets_on_landing():
|
|
||||||
player.performDoubleJump()
|
|
||||||
player._on_landed()
|
|
||||||
assert_true(player.canDoubleJump)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 6: 测试验证 (2分钟)
|
|
||||||
```bash
|
|
||||||
$ godot --headless -s addons/gut/gut_cmdline.gd
|
|
||||||
========================
|
|
||||||
= PASSED: 2 of 2 tests =
|
|
||||||
========================
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 7: Git 提交 (3分钟)
|
|
||||||
```bash
|
|
||||||
git add scenes/Entities/Player/PlayerController.gd
|
|
||||||
git add _Core/EventNames.gd
|
|
||||||
git add tests/unit/test_player_double_jump.gd
|
|
||||||
git commit -m "feat:实现玩家二段跳功能"
|
|
||||||
```
|
|
||||||
|
|
||||||
**总耗时**: 约 36 分钟
|
|
||||||
**结果**: ✅ 功能实现完整,符合所有规范
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎓 总结
|
|
||||||
|
|
||||||
遵循此 7 步标准开发工作流,可以确保:
|
|
||||||
|
|
||||||
1. **代码质量**: 符合项目的所有规范和标准
|
|
||||||
2. **团队一致**: 所有开发者使用相同的流程和规范
|
|
||||||
3. **可维护性**: 清晰的注释、规范的命名、完整的测试
|
|
||||||
4. **高效协作**: 规范的 Git 提交历史,便于追溯和回滚
|
|
||||||
5. **质量保证**: 测试驱动开发,确保功能正确性
|
|
||||||
|
|
||||||
**记住**: 使用 `/whaletown-developer` skill 可以自动化执行此流程!🚀
|
|
||||||
@@ -22,7 +22,6 @@ SceneManager="*res://_Core/managers/SceneManager.gd"
|
|||||||
EventSystem="*res://_Core/systems/EventSystem.gd"
|
EventSystem="*res://_Core/systems/EventSystem.gd"
|
||||||
NetworkManager="*res://_Core/managers/NetworkManager.gd"
|
NetworkManager="*res://_Core/managers/NetworkManager.gd"
|
||||||
ResponseHandler="*res://_Core/managers/ResponseHandler.gd"
|
ResponseHandler="*res://_Core/managers/ResponseHandler.gd"
|
||||||
WebSocketManager="*res://_Core/managers/WebSocketManager.gd"
|
|
||||||
|
|
||||||
[debug]
|
[debug]
|
||||||
|
|
||||||
@@ -30,10 +29,10 @@ gdscript/warnings/treat_warnings_as_errors=false
|
|||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
window/size/viewport_width=1920
|
window/size/viewport_width=1376
|
||||||
window/size/viewport_height=1440
|
window/size/viewport_height=768
|
||||||
window/size/mode=2
|
window/size/mode=2
|
||||||
window/stretch/mode="viewport"
|
window/stretch/mode="canvas_items"
|
||||||
window/stretch/aspect="expand"
|
window/stretch/aspect="expand"
|
||||||
|
|
||||||
[gui]
|
[gui]
|
||||||
@@ -86,8 +85,6 @@ locale/test="zh_CN"
|
|||||||
renderer/rendering_method="gl_compatibility"
|
renderer/rendering_method="gl_compatibility"
|
||||||
renderer/rendering_method.mobile="gl_compatibility"
|
renderer/rendering_method.mobile="gl_compatibility"
|
||||||
textures/vram_compression/import_etc2_astc=true
|
textures/vram_compression/import_etc2_astc=true
|
||||||
2d/snap/snap_2d_transforms_to_pixel=true
|
|
||||||
2d/snap/snap_2d_vertices_to_pixel=true
|
|
||||||
fonts/dynamic_fonts/use_oversampling=true
|
fonts/dynamic_fonts/use_oversampling=true
|
||||||
debug/disable_vsync=false
|
debug/disable_vsync=false
|
||||||
debug/settings/stdout/print_fps=false
|
debug/settings/stdout/print_fps=false
|
||||||
|
|||||||