Compare commits
21 Commits
eb99c6a18e
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| d1761a2464 | |||
| ffd88c02e1 | |||
| bd9b7c009a | |||
| e61ab94935 | |||
| 9150622e74 | |||
| 501cad6175 | |||
| 5275c5ca94 | |||
| 61951a047b | |||
| 5f6a3ae175 | |||
| 40c06ae249 | |||
| 1189ce0931 | |||
| ff04b6ee22 | |||
| ff0a4fefe1 | |||
| 666823c641 | |||
| 02f2bb2703 | |||
| 38e85c2a24 | |||
| e31278e389 | |||
| 024343db19 | |||
| ad7a2575da | |||
| 26991ce61a | |||
| 8ded8c81ee |
@@ -4,8 +4,11 @@
|
|||||||
"WebSearch",
|
"WebSearch",
|
||||||
"Bash(find:*)",
|
"Bash(find:*)",
|
||||||
"Bash(godot:*)",
|
"Bash(godot:*)",
|
||||||
|
"Bash(python:*)",
|
||||||
|
"Bash(git mv:*)",
|
||||||
|
"Bash(dir:*)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
498
.gitea/workflows/build.yml
Normal file
498
.gitea/workflows/build.yml
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
name: Build Game
|
||||||
|
|
||||||
|
# Build pipeline for creating game executables across multiple platforms
|
||||||
|
#
|
||||||
|
# Features:
|
||||||
|
# - Manual trigger with individual platform checkboxes
|
||||||
|
# - Tag-based automatic builds for releases
|
||||||
|
# - Multi-platform builds (Windows, Linux, macOS, Android)
|
||||||
|
# - Artifact storage for one week
|
||||||
|
# - Configurable build options
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Manual trigger with platform selection
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
build_windows:
|
||||||
|
description: 'Build for Windows'
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
type: boolean
|
||||||
|
build_linux:
|
||||||
|
description: 'Build for Linux'
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
build_macos:
|
||||||
|
description: 'Build for macOS'
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
build_android:
|
||||||
|
description: 'Build for Android'
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
build_type:
|
||||||
|
description: 'Build type'
|
||||||
|
required: true
|
||||||
|
default: 'release'
|
||||||
|
type: debug
|
||||||
|
options:
|
||||||
|
- release
|
||||||
|
- debug
|
||||||
|
version_override:
|
||||||
|
description: 'Override version (optional)'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# Automatic trigger on git tags (for releases)
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*' # Version tags (v1.0.0, v2.1.0, etc.)
|
||||||
|
- 'release-*' # Release tags
|
||||||
|
|
||||||
|
env:
|
||||||
|
GODOT_VERSION: "4.4.1"
|
||||||
|
PROJECT_NAME: "Skelly"
|
||||||
|
BUILD_DIR: "builds"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Preparation job - determines build configuration
|
||||||
|
prepare:
|
||||||
|
name: Prepare Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
platforms: ${{ steps.config.outputs.platforms }}
|
||||||
|
build_type: ${{ steps.config.outputs.build_type }}
|
||||||
|
version: ${{ steps.config.outputs.version }}
|
||||||
|
artifact_name: ${{ steps.config.outputs.artifact_name }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Configure build parameters
|
||||||
|
id: config
|
||||||
|
run: |
|
||||||
|
# Determine platforms to build
|
||||||
|
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||||
|
# Build platforms array from individual checkboxes
|
||||||
|
platforms=""
|
||||||
|
if [[ "${{ github.event.inputs.build_windows }}" == "true" ]]; then
|
||||||
|
platforms="${platforms}windows,"
|
||||||
|
fi
|
||||||
|
if [[ "${{ github.event.inputs.build_linux }}" == "true" ]]; then
|
||||||
|
platforms="${platforms}linux,"
|
||||||
|
fi
|
||||||
|
if [[ "${{ github.event.inputs.build_macos }}" == "true" ]]; then
|
||||||
|
platforms="${platforms}macos,"
|
||||||
|
fi
|
||||||
|
if [[ "${{ github.event.inputs.build_android }}" == "true" ]]; then
|
||||||
|
platforms="${platforms}android,"
|
||||||
|
fi
|
||||||
|
# Remove trailing comma
|
||||||
|
platforms="${platforms%,}"
|
||||||
|
|
||||||
|
build_type="${{ github.event.inputs.build_type }}"
|
||||||
|
version_override="${{ github.event.inputs.version_override }}"
|
||||||
|
else
|
||||||
|
# Tag-triggered build - build all platforms
|
||||||
|
platforms="windows,linux,macos,android"
|
||||||
|
build_type="release"
|
||||||
|
version_override=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine version
|
||||||
|
if [[ -n "$version_override" ]]; then
|
||||||
|
version="$version_override"
|
||||||
|
elif [[ "${{ github.ref_type }}" == "tag" ]]; then
|
||||||
|
version="${{ github.ref_name }}"
|
||||||
|
else
|
||||||
|
# Generate version from git info
|
||||||
|
commit_short=$(git rev-parse --short HEAD)
|
||||||
|
branch_name="${{ github.ref_name }}"
|
||||||
|
timestamp=$(date +%Y%m%d-%H%M)
|
||||||
|
version="${branch_name}-${commit_short}-${timestamp}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create artifact name
|
||||||
|
artifact_name="${{ env.PROJECT_NAME }}-${version}-${build_type}"
|
||||||
|
|
||||||
|
echo "platforms=${platforms}" >> $GITHUB_OUTPUT
|
||||||
|
echo "build_type=${build_type}" >> $GITHUB_OUTPUT
|
||||||
|
echo "version=${version}" >> $GITHUB_OUTPUT
|
||||||
|
echo "artifact_name=${artifact_name}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
echo "🔧 Build Configuration:"
|
||||||
|
echo " Platforms: ${platforms}"
|
||||||
|
echo " Build Type: ${build_type}"
|
||||||
|
echo " Version: ${version}"
|
||||||
|
echo " Artifact: ${artifact_name}"
|
||||||
|
|
||||||
|
# Setup export templates (shared across all platform builds)
|
||||||
|
setup-templates:
|
||||||
|
name: Setup Export Templates
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: prepare
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Cache export templates
|
||||||
|
id: cache-templates
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.local/share/godot/export_templates
|
||||||
|
key: godot-templates-${{ env.GODOT_VERSION }}
|
||||||
|
restore-keys: |
|
||||||
|
godot-templates-
|
||||||
|
|
||||||
|
- name: Setup Godot
|
||||||
|
if: steps.cache-templates.outputs.cache-hit != 'true'
|
||||||
|
uses: chickensoft-games/setup-godot@v1
|
||||||
|
with:
|
||||||
|
version: ${{ env.GODOT_VERSION }}
|
||||||
|
use-dotnet: false
|
||||||
|
|
||||||
|
- name: Install export templates
|
||||||
|
if: steps.cache-templates.outputs.cache-hit != 'true'
|
||||||
|
run: |
|
||||||
|
echo "📦 Installing Godot export templates..."
|
||||||
|
mkdir -p ~/.local/share/godot/export_templates/${{ env.GODOT_VERSION }}.stable
|
||||||
|
wget -q https://github.com/godotengine/godot/releases/download/${{ env.GODOT_VERSION }}-stable/Godot_v${{ env.GODOT_VERSION }}-stable_export_templates.tpz
|
||||||
|
unzip -q Godot_v${{ env.GODOT_VERSION }}-stable_export_templates.tpz
|
||||||
|
mv templates/* ~/.local/share/godot/export_templates/${{ env.GODOT_VERSION }}.stable/
|
||||||
|
echo "✅ Export templates installed successfully"
|
||||||
|
ls -la ~/.local/share/godot/export_templates/${{ env.GODOT_VERSION }}.stable/
|
||||||
|
|
||||||
|
- name: Verify templates cache
|
||||||
|
run: |
|
||||||
|
echo "🔍 Verifying export templates are available:"
|
||||||
|
ls -la ~/.local/share/godot/export_templates/${{ env.GODOT_VERSION }}.stable/
|
||||||
|
|
||||||
|
# Windows build job
|
||||||
|
build-windows:
|
||||||
|
name: Build Windows
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [prepare, setup-templates]
|
||||||
|
if: contains(needs.prepare.outputs.platforms, 'windows')
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Godot
|
||||||
|
uses: chickensoft-games/setup-godot@v1
|
||||||
|
with:
|
||||||
|
version: ${{ env.GODOT_VERSION }}
|
||||||
|
use-dotnet: false
|
||||||
|
|
||||||
|
- name: Restore export templates cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.local/share/godot/export_templates
|
||||||
|
key: godot-templates-${{ env.GODOT_VERSION }}
|
||||||
|
restore-keys: |
|
||||||
|
godot-templates-
|
||||||
|
|
||||||
|
- name: Create build directory
|
||||||
|
run: mkdir -p ${{ env.BUILD_DIR }}
|
||||||
|
|
||||||
|
- name: Import project assets
|
||||||
|
run: |
|
||||||
|
echo "📦 Importing project assets..."
|
||||||
|
godot --headless --verbose --editor --quit || true
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
- name: Build Windows executable
|
||||||
|
run: |
|
||||||
|
echo "🏗️ Building Windows executable..."
|
||||||
|
godot --headless --verbose --export-${{ needs.prepare.outputs.build_type }} "Windows Desktop" \
|
||||||
|
${{ env.BUILD_DIR }}/skelly-windows-${{ needs.prepare.outputs.version }}.exe
|
||||||
|
|
||||||
|
# Verify build output
|
||||||
|
if [[ -f "${{ env.BUILD_DIR }}/skelly-windows-${{ needs.prepare.outputs.version }}.exe" ]]; then
|
||||||
|
echo "✅ Windows build successful"
|
||||||
|
ls -la ${{ env.BUILD_DIR }}/
|
||||||
|
else
|
||||||
|
echo "❌ Windows build failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Upload Windows build
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ needs.prepare.outputs.artifact_name }}-windows
|
||||||
|
path: ${{ env.BUILD_DIR }}/skelly-windows-${{ needs.prepare.outputs.version }}.exe
|
||||||
|
retention-days: 7
|
||||||
|
compression-level: 0
|
||||||
|
|
||||||
|
# Linux build job
|
||||||
|
build-linux:
|
||||||
|
name: Build Linux
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [prepare, setup-templates]
|
||||||
|
if: contains(needs.prepare.outputs.platforms, 'linux')
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Godot
|
||||||
|
uses: chickensoft-games/setup-godot@v1
|
||||||
|
with:
|
||||||
|
version: ${{ env.GODOT_VERSION }}
|
||||||
|
use-dotnet: false
|
||||||
|
|
||||||
|
- name: Restore export templates cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.local/share/godot/export_templates
|
||||||
|
key: godot-templates-${{ env.GODOT_VERSION }}
|
||||||
|
restore-keys: |
|
||||||
|
godot-templates-
|
||||||
|
|
||||||
|
- name: Create build directory
|
||||||
|
run: mkdir -p ${{ env.BUILD_DIR }}
|
||||||
|
|
||||||
|
- name: Import project assets
|
||||||
|
run: |
|
||||||
|
echo "📦 Importing project assets..."
|
||||||
|
godot --headless --verbose --editor --quit || true
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
- name: Build Linux executable
|
||||||
|
run: |
|
||||||
|
echo "🏗️ Building Linux executable..."
|
||||||
|
godot --headless --verbose --export-${{ needs.prepare.outputs.build_type }} "Linux" \
|
||||||
|
${{ env.BUILD_DIR }}/skelly-linux-${{ needs.prepare.outputs.version }}.x86_64
|
||||||
|
|
||||||
|
# Make executable
|
||||||
|
chmod +x ${{ env.BUILD_DIR }}/skelly-linux-${{ needs.prepare.outputs.version }}.x86_64
|
||||||
|
|
||||||
|
# Verify build output
|
||||||
|
if [[ -f "${{ env.BUILD_DIR }}/skelly-linux-${{ needs.prepare.outputs.version }}.x86_64" ]]; then
|
||||||
|
echo "✅ Linux build successful"
|
||||||
|
ls -la ${{ env.BUILD_DIR }}/
|
||||||
|
else
|
||||||
|
echo "❌ Linux build failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Upload Linux build
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ needs.prepare.outputs.artifact_name }}-linux
|
||||||
|
path: ${{ env.BUILD_DIR }}/skelly-linux-${{ needs.prepare.outputs.version }}.x86_64
|
||||||
|
retention-days: 7
|
||||||
|
compression-level: 0
|
||||||
|
|
||||||
|
# macOS build job
|
||||||
|
build-macos:
|
||||||
|
name: Build macOS
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [prepare, setup-templates]
|
||||||
|
if: contains(needs.prepare.outputs.platforms, 'macos')
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Godot
|
||||||
|
uses: chickensoft-games/setup-godot@v1
|
||||||
|
with:
|
||||||
|
version: ${{ env.GODOT_VERSION }}
|
||||||
|
use-dotnet: false
|
||||||
|
|
||||||
|
- name: Restore export templates cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.local/share/godot/export_templates
|
||||||
|
key: godot-templates-${{ env.GODOT_VERSION }}
|
||||||
|
restore-keys: |
|
||||||
|
godot-templates-
|
||||||
|
|
||||||
|
- name: Create build directory
|
||||||
|
run: mkdir -p ${{ env.BUILD_DIR }}
|
||||||
|
|
||||||
|
- name: Import project assets
|
||||||
|
run: |
|
||||||
|
echo "📦 Importing project assets..."
|
||||||
|
godot --headless --verbose --editor --quit || true
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
- name: Build macOS application
|
||||||
|
run: |
|
||||||
|
echo "🏗️ Building macOS application..."
|
||||||
|
godot --headless --verbose --export-${{ needs.prepare.outputs.build_type }} "macOS" \
|
||||||
|
${{ env.BUILD_DIR }}/skelly-macos-${{ needs.prepare.outputs.version }}.zip
|
||||||
|
|
||||||
|
# Verify build output
|
||||||
|
if [[ -f "${{ env.BUILD_DIR }}/skelly-macos-${{ needs.prepare.outputs.version }}.zip" ]]; then
|
||||||
|
echo "✅ macOS build successful"
|
||||||
|
ls -la ${{ env.BUILD_DIR }}/
|
||||||
|
else
|
||||||
|
echo "❌ macOS build failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Upload macOS build
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ needs.prepare.outputs.artifact_name }}-macos
|
||||||
|
path: ${{ env.BUILD_DIR }}/skelly-macos-${{ needs.prepare.outputs.version }}.zip
|
||||||
|
retention-days: 7
|
||||||
|
compression-level: 0
|
||||||
|
|
||||||
|
# Android build job
|
||||||
|
build-android:
|
||||||
|
name: Build Android
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [prepare, setup-templates]
|
||||||
|
if: contains(needs.prepare.outputs.platforms, 'android')
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: '17'
|
||||||
|
|
||||||
|
- name: Setup Android SDK
|
||||||
|
uses: android-actions/setup-android@v3
|
||||||
|
with:
|
||||||
|
api-level: 33
|
||||||
|
build-tools: 33.0.0
|
||||||
|
|
||||||
|
- name: Setup Godot
|
||||||
|
uses: chickensoft-games/setup-godot@v1
|
||||||
|
with:
|
||||||
|
version: ${{ env.GODOT_VERSION }}
|
||||||
|
use-dotnet: false
|
||||||
|
|
||||||
|
- name: Restore export templates cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.local/share/godot/export_templates
|
||||||
|
key: godot-templates-${{ env.GODOT_VERSION }}
|
||||||
|
restore-keys: |
|
||||||
|
godot-templates-
|
||||||
|
|
||||||
|
- name: Create build directory
|
||||||
|
run: mkdir -p ${{ env.BUILD_DIR }}
|
||||||
|
|
||||||
|
- name: Import project assets
|
||||||
|
run: |
|
||||||
|
echo "📦 Importing project assets..."
|
||||||
|
godot --headless --verbose --editor --quit || true
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
- name: Build Android APK
|
||||||
|
run: |
|
||||||
|
echo "🏗️ Building Android APK..."
|
||||||
|
|
||||||
|
# Set ANDROID_HOME if not already set
|
||||||
|
export ANDROID_HOME=${ANDROID_HOME:-$ANDROID_SDK_ROOT}
|
||||||
|
|
||||||
|
godot --headless --verbose --export-${{ needs.prepare.outputs.build_type }} "Android" \
|
||||||
|
${{ env.BUILD_DIR }}/skelly-android-${{ needs.prepare.outputs.version }}.apk
|
||||||
|
|
||||||
|
# Verify build output
|
||||||
|
if [[ -f "${{ env.BUILD_DIR }}/skelly-android-${{ needs.prepare.outputs.version }}.apk" ]]; then
|
||||||
|
echo "✅ Android build successful"
|
||||||
|
ls -la ${{ env.BUILD_DIR }}/
|
||||||
|
|
||||||
|
# Show APK info
|
||||||
|
echo "📱 APK Information:"
|
||||||
|
file ${{ env.BUILD_DIR }}/skelly-android-${{ needs.prepare.outputs.version }}.apk
|
||||||
|
else
|
||||||
|
echo "❌ Android build failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Upload Android build
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ${{ needs.prepare.outputs.artifact_name }}-android
|
||||||
|
path: ${{ env.BUILD_DIR }}/skelly-android-${{ needs.prepare.outputs.version }}.apk
|
||||||
|
retention-days: 7
|
||||||
|
compression-level: 0
|
||||||
|
|
||||||
|
# Summary job - creates release summary
|
||||||
|
summary:
|
||||||
|
name: Build Summary
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [prepare, setup-templates, build-windows, build-linux, build-macos, build-android]
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Generate build summary
|
||||||
|
run: |
|
||||||
|
echo "🎮 Build Summary for ${{ needs.prepare.outputs.artifact_name }}"
|
||||||
|
echo "=================================="
|
||||||
|
echo ""
|
||||||
|
echo "📋 Configuration:"
|
||||||
|
echo " Version: ${{ needs.prepare.outputs.version }}"
|
||||||
|
echo " Build Type: ${{ needs.prepare.outputs.build_type }}"
|
||||||
|
echo " Platforms: ${{ needs.prepare.outputs.platforms }}"
|
||||||
|
echo ""
|
||||||
|
echo "📊 Build Results:"
|
||||||
|
|
||||||
|
platforms="${{ needs.prepare.outputs.platforms }}"
|
||||||
|
|
||||||
|
if [[ "$platforms" == *"windows"* ]]; then
|
||||||
|
windows_status="${{ needs.build-windows.result }}"
|
||||||
|
echo " 🪟 Windows: $windows_status"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$platforms" == *"linux"* ]]; then
|
||||||
|
linux_status="${{ needs.build-linux.result }}"
|
||||||
|
echo " 🐧 Linux: $linux_status"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$platforms" == *"macos"* ]]; then
|
||||||
|
macos_status="${{ needs.build-macos.result }}"
|
||||||
|
echo " 🍎 macOS: $macos_status"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$platforms" == *"android"* ]]; then
|
||||||
|
android_status="${{ needs.build-android.result }}"
|
||||||
|
echo " 🤖 Android: $android_status"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "📦 Artifacts are available for 7 days"
|
||||||
|
echo "🔗 Download from: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
|
||||||
|
- name: Check overall build status
|
||||||
|
run: |
|
||||||
|
# Check if any required builds failed
|
||||||
|
platforms="${{ needs.prepare.outputs.platforms }}"
|
||||||
|
failed_builds=()
|
||||||
|
|
||||||
|
if [[ "$platforms" == *"windows"* ]] && [[ "${{ needs.build-windows.result }}" != "success" ]]; then
|
||||||
|
failed_builds+=("Windows")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$platforms" == *"linux"* ]] && [[ "${{ needs.build-linux.result }}" != "success" ]]; then
|
||||||
|
failed_builds+=("Linux")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$platforms" == *"macos"* ]] && [[ "${{ needs.build-macos.result }}" != "success" ]]; then
|
||||||
|
failed_builds+=("macOS")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$platforms" == *"android"* ]] && [[ "${{ needs.build-android.result }}" != "success" ]]; then
|
||||||
|
failed_builds+=("Android")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${#failed_builds[@]} -gt 0 ]]; then
|
||||||
|
echo "❌ Build failed for: ${failed_builds[*]}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "✅ All builds completed successfully!"
|
||||||
|
fi
|
||||||
@@ -84,7 +84,17 @@ jobs:
|
|||||||
id: format
|
id: format
|
||||||
run: |
|
run: |
|
||||||
echo "🎨 Running GDScript formatting..."
|
echo "🎨 Running GDScript formatting..."
|
||||||
python tools/run_development.py --format
|
python tools/run_development.py --format --silent --yaml > format_results.yaml
|
||||||
|
|
||||||
|
- name: Upload formatting results
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: format-results
|
||||||
|
path: |
|
||||||
|
format_results.yaml
|
||||||
|
retention-days: 7
|
||||||
|
compression-level: 0
|
||||||
|
|
||||||
- name: Check for formatting changes
|
- name: Check for formatting changes
|
||||||
id: check-changes
|
id: check-changes
|
||||||
@@ -156,16 +166,17 @@ jobs:
|
|||||||
id: lint
|
id: lint
|
||||||
run: |
|
run: |
|
||||||
echo "🔍 Running GDScript linting..."
|
echo "🔍 Running GDScript linting..."
|
||||||
python tools/run_development.py --lint
|
python tools/run_development.py --lint --silent --yaml > lint_results.yaml
|
||||||
|
|
||||||
- name: Upload linting results
|
- name: Upload linting results
|
||||||
if: failure()
|
if: always()
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: lint-results
|
name: lint-results
|
||||||
path: |
|
path: |
|
||||||
**/*.gd
|
lint_results.yaml
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
compression-level: 0
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: Test Execution
|
name: Test Execution
|
||||||
@@ -201,16 +212,17 @@ jobs:
|
|||||||
id: test
|
id: test
|
||||||
run: |
|
run: |
|
||||||
echo "🧪 Running GDScript tests..."
|
echo "🧪 Running GDScript tests..."
|
||||||
python tools/run_development.py --test
|
python tools/run_development.py --test --silent --yaml > test_results.yaml
|
||||||
|
|
||||||
- name: Upload test results
|
- name: Upload test results
|
||||||
if: failure()
|
if: always()
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: test-results
|
name: test-results
|
||||||
path: |
|
path: |
|
||||||
tests/**/*.gd
|
test_results.yaml
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
compression-level: 0
|
||||||
|
|
||||||
summary:
|
summary:
|
||||||
name: CI Summary
|
name: CI Summary
|
||||||
|
|||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -6,3 +6,8 @@
|
|||||||
*.tmp
|
*.tmp
|
||||||
*.import~
|
*.import~
|
||||||
test_results.txt
|
test_results.txt
|
||||||
|
|
||||||
|
# python
|
||||||
|
|
||||||
|
.venv
|
||||||
|
*.pyc
|
||||||
|
|||||||
@@ -6,4 +6,4 @@
|
|||||||
- Use TDD methodology for development;
|
- Use TDD methodology for development;
|
||||||
- Use static data types;
|
- Use static data types;
|
||||||
- Keep documentation up to date;
|
- Keep documentation up to date;
|
||||||
- Always run gdlint, gdformat and run tests;
|
- Always run tests `./tools/run_development.py --yaml --silent`;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ Guidance for Claude Code (claude.ai/code) when working with this repository.
|
|||||||
- Invalid swaps automatically revert after animation
|
- Invalid swaps automatically revert after animation
|
||||||
- State machine: WAITING → SELECTING → SWAPPING → PROCESSING
|
- State machine: WAITING → SELECTING → SWAPPING → PROCESSING
|
||||||
- Test scripts located in `tests/` directory for system validation
|
- Test scripts located in `tests/` directory for system validation
|
||||||
- Use `test_logging.gd` to validate the logging system functionality
|
- Use `TestLogging.gd` to validate the logging system functionality
|
||||||
|
|
||||||
### Audio Configuration
|
### Audio Configuration
|
||||||
- Music: Located in `assets/audio/music/` directory with loop configuration in AudioManager
|
- Music: Located in `assets/audio/music/` directory with loop configuration in AudioManager
|
||||||
@@ -111,7 +111,7 @@ Guidance for Claude Code (claude.ai/code) when working with this repository.
|
|||||||
- `src/autoloads/SettingsManager.gd` - Settings management with input validation and security
|
- `src/autoloads/SettingsManager.gd` - Settings management with input validation and security
|
||||||
- `src/autoloads/DebugManager.gd` - Debug system integration
|
- `src/autoloads/DebugManager.gd` - Debug system integration
|
||||||
- `scenes/game/game.gd` - Main game scene with modular gameplay system
|
- `scenes/game/game.gd` - Main game scene with modular gameplay system
|
||||||
- `scenes/game/gameplays/match3_gameplay.gd` - Match-3 implementation with input validation
|
- `scenes/game/gameplays/Match3Gameplay.gd` - Match-3 implementation with input validation
|
||||||
- `scenes/game/gameplays/tile.gd` - Instance-based tile behavior without global state
|
- `scenes/game/gameplays/tile.gd` - Instance-based tile behavior without global state
|
||||||
- `scenes/ui/DebugMenuBase.gd` - Unified debug menu base class
|
- `scenes/ui/DebugMenuBase.gd` - Unified debug menu base class
|
||||||
- `scenes/ui/SettingsMenu.gd` - Settings UI with input validation
|
- `scenes/ui/SettingsMenu.gd` - Settings UI with input validation
|
||||||
@@ -123,8 +123,9 @@ Guidance for Claude Code (claude.ai/code) when working with this repository.
|
|||||||
### Before Making Changes
|
### Before Making Changes
|
||||||
1. Check `docs/MAP.md` for architecture
|
1. Check `docs/MAP.md` for architecture
|
||||||
2. Review `docs/CODE_OF_CONDUCT.md` for coding standards
|
2. Review `docs/CODE_OF_CONDUCT.md` for coding standards
|
||||||
3. Understand existing patterns before implementing features
|
3. **Review naming conventions**: See [Naming Convention Quick Reference](CODE_OF_CONDUCT.md#naming-convention-quick-reference) for all file and code naming standards
|
||||||
4. If adding assets, prepare `assets/sources.yaml` documentation
|
4. Understand existing patterns before implementing features
|
||||||
|
5. If adding assets, prepare `assets/sources.yaml` documentation following [asset naming conventions](CODE_OF_CONDUCT.md#5-asset-file-naming)
|
||||||
|
|
||||||
### Testing Changes
|
### Testing Changes
|
||||||
- Run project with F5 in Godot Editor
|
- Run project with F5 in Godot Editor
|
||||||
@@ -132,10 +133,10 @@ Guidance for Claude Code (claude.ai/code) when working with this repository.
|
|||||||
- Verify scene transitions work
|
- Verify scene transitions work
|
||||||
- Check mobile compatibility if UI changes made
|
- Check mobile compatibility if UI changes made
|
||||||
- Use test scripts from `tests/` directory to validate functionality
|
- Use test scripts from `tests/` directory to validate functionality
|
||||||
- Run `test_logging.gd` after logging system changes
|
- Run `TestLogging.gd` after logging system changes
|
||||||
- **Save system testing**: Run save/load test suites after SaveManager changes
|
- **Save system testing**: Run save/load test suites after SaveManager changes
|
||||||
- **Checksum validation**: Test `test_checksum_issue.gd` to verify deterministic checksums
|
- **Checksum validation**: Test `test_checksum_issue.gd` to verify deterministic checksums
|
||||||
- **Migration compatibility**: Run `test_migration_compatibility.gd` for version upgrades
|
- **Migration compatibility**: Run `TestMigrationCompatibility.gd` for version upgrades
|
||||||
|
|
||||||
### Common Implementation Patterns
|
### Common Implementation Patterns
|
||||||
- **Scene transitions**: Use `GameManager.start_game_with_mode()` with built-in validation
|
- **Scene transitions**: Use `GameManager.start_game_with_mode()` with built-in validation
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ Coding standards and development practices for the Skelly project. These guideli
|
|||||||
## GDScript Coding Standards
|
## GDScript Coding Standards
|
||||||
|
|
||||||
### Naming Conventions
|
### Naming Conventions
|
||||||
|
|
||||||
|
> 📋 **Quick Reference**: For complete naming convention details, see the **[Naming Convention Quick Reference](#naming-convention-quick-reference)** section below.
|
||||||
|
|
||||||
```gdscript
|
```gdscript
|
||||||
# Variables and functions: snake_case
|
# Variables and functions: snake_case
|
||||||
var player_health: int = 100
|
var player_health: int = 100
|
||||||
@@ -39,6 +42,11 @@ const TILE_SPACING := 54
|
|||||||
# Classes: PascalCase
|
# Classes: PascalCase
|
||||||
class_name PlayerController
|
class_name PlayerController
|
||||||
|
|
||||||
|
# Scene files (.tscn) and Script files (.gd): PascalCase
|
||||||
|
# MainMenu.tscn, MainMenu.gd
|
||||||
|
# Match3Gameplay.tscn, Match3Gameplay.gd
|
||||||
|
# TestAudioManager.gd (test files)
|
||||||
|
|
||||||
# Signals: past_tense
|
# Signals: past_tense
|
||||||
signal health_changed
|
signal health_changed
|
||||||
signal game_started
|
signal game_started
|
||||||
@@ -100,7 +108,7 @@ func _get_match_line(start: Vector2i, dir: Vector2i) -> Array:
|
|||||||
GameManager.start_match3_game()
|
GameManager.start_match3_game()
|
||||||
|
|
||||||
# ❌ Wrong
|
# ❌ Wrong
|
||||||
get_tree().change_scene_to_file("res://scenes/game.tscn")
|
get_tree().change_scene_to_file("res://scenes/game/Game.tscn")
|
||||||
```
|
```
|
||||||
|
|
||||||
### Autoload Usage
|
### Autoload Usage
|
||||||
@@ -263,6 +271,207 @@ wip
|
|||||||
- Verify debug state persists across scene changes
|
- Verify debug state persists across scene changes
|
||||||
- Check debug code doesn't affect release builds
|
- Check debug code doesn't affect release builds
|
||||||
|
|
||||||
|
## Naming Convention Quick Reference
|
||||||
|
|
||||||
|
> 🎯 **Single Source of Truth**: This section contains all naming conventions for the Skelly project. All other documentation files reference this section to avoid duplication and ensure consistency.
|
||||||
|
|
||||||
|
### 1. GDScript Code Elements
|
||||||
|
|
||||||
|
```gdscript
|
||||||
|
# Variables and functions: snake_case
|
||||||
|
var player_health: int = 100
|
||||||
|
func calculate_damage() -> int:
|
||||||
|
|
||||||
|
# Constants: SCREAMING_SNAKE_CASE
|
||||||
|
const MAX_HEALTH := 100
|
||||||
|
const TILE_SPACING := 54
|
||||||
|
|
||||||
|
# Classes: PascalCase
|
||||||
|
class_name PlayerController
|
||||||
|
|
||||||
|
# Signals: past_tense_with_underscores
|
||||||
|
signal health_changed
|
||||||
|
signal game_started
|
||||||
|
signal match_found
|
||||||
|
|
||||||
|
# Private functions: prefix with underscore
|
||||||
|
func _ready():
|
||||||
|
func _initialize_grid():
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. File Naming Standards
|
||||||
|
|
||||||
|
#### Script and Scene Files
|
||||||
|
```gdscript
|
||||||
|
# ✅ Correct: All .gd and .tscn files use PascalCase
|
||||||
|
MainMenu.tscn / MainMenu.gd
|
||||||
|
Match3Gameplay.tscn / Match3Gameplay.gd
|
||||||
|
ClickomaniaGameplay.tscn / ClickomaniaGameplay.gd
|
||||||
|
ValueStepper.tscn / ValueStepper.gd
|
||||||
|
|
||||||
|
# Test files: PascalCase with "Test" prefix
|
||||||
|
TestAudioManager.gd
|
||||||
|
TestGameManager.gd
|
||||||
|
TestMatch3Gameplay.gd
|
||||||
|
|
||||||
|
# ❌ Wrong: Old snake_case style (being migrated)
|
||||||
|
main_menu.tscn / main_menu.gd
|
||||||
|
TestAudioManager.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules:**
|
||||||
|
- Scene files (.tscn) must match their script file name exactly
|
||||||
|
- All new files must use PascalCase
|
||||||
|
- Test files use "Test" prefix + PascalCase
|
||||||
|
- Autoload scripts follow PascalCase (GameManager.gd, AudioManager.gd)
|
||||||
|
|
||||||
|
### 3. Directory Naming Conventions
|
||||||
|
|
||||||
|
#### Source Code Directories
|
||||||
|
```
|
||||||
|
# Source directories: snake_case
|
||||||
|
src/autoloads/
|
||||||
|
scenes/game/gameplays/
|
||||||
|
scenes/ui/components/
|
||||||
|
tests/helpers/
|
||||||
|
|
||||||
|
# Root directories: lowercase
|
||||||
|
docs/
|
||||||
|
tests/
|
||||||
|
tools/
|
||||||
|
data/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Asset Directories
|
||||||
|
```
|
||||||
|
# Asset directories: kebab-case
|
||||||
|
assets/audio-files/
|
||||||
|
assets/ui-sprites/
|
||||||
|
assets/game-textures/
|
||||||
|
assets/fonts/
|
||||||
|
localization/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Resource and Configuration Files
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Configuration files: lowercase with dots
|
||||||
|
project.godot
|
||||||
|
gdlintrc
|
||||||
|
.gdformatrc
|
||||||
|
.editorconfig
|
||||||
|
export_presets.cfg
|
||||||
|
|
||||||
|
# Godot resource files (.tres): PascalCase
|
||||||
|
data/DefaultBusLayout.tres
|
||||||
|
data/PlayerSaveData.tres
|
||||||
|
scenes/ui/DefaultTheme.tres
|
||||||
|
|
||||||
|
# Asset metadata: kebab-case
|
||||||
|
assets/asset-sources.yaml
|
||||||
|
assets/audio-files/audio-sources.yaml
|
||||||
|
assets/ui-sprites/sprite-sources.yaml
|
||||||
|
|
||||||
|
# Development files: kebab-case
|
||||||
|
requirements.txt
|
||||||
|
development-tools.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Asset File Naming
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Audio files: kebab-case in kebab-case directories
|
||||||
|
assets/audio-files/background-music.ogg
|
||||||
|
assets/audio-files/ui-sounds/button-click.wav
|
||||||
|
assets/audio-files/game-sounds/match-sound.wav
|
||||||
|
|
||||||
|
# Visual assets: kebab-case
|
||||||
|
assets/ui-sprites/main-menu-background.png
|
||||||
|
assets/game-textures/gem-blue.png
|
||||||
|
assets/fonts/main-ui-font.ttf
|
||||||
|
|
||||||
|
# Import settings: match the original file
|
||||||
|
background-music.ogg.import
|
||||||
|
button-click.wav.import
|
||||||
|
```
|
||||||
|
|
||||||
|
**Asset Rules:**
|
||||||
|
- All asset files use kebab-case
|
||||||
|
- Organized in kebab-case directories
|
||||||
|
- Import files automatically match asset names
|
||||||
|
- Document all assets in `asset-sources.yaml`
|
||||||
|
|
||||||
|
### 6. Git Workflow Conventions
|
||||||
|
|
||||||
|
#### Branch Naming
|
||||||
|
```bash
|
||||||
|
# Feature branches: feature/description-with-hyphens
|
||||||
|
feature/new-gameplay-mode
|
||||||
|
feature/settings-ui-improvement
|
||||||
|
feature/audio-system-upgrade
|
||||||
|
|
||||||
|
# Bug fixes: fix/description-with-hyphens
|
||||||
|
fix/tile-positioning-bug
|
||||||
|
fix/save-data-corruption
|
||||||
|
fix/debug-menu-visibility
|
||||||
|
|
||||||
|
# Refactoring: refactor/component-name
|
||||||
|
refactor/match3-input-system
|
||||||
|
refactor/autoload-structure
|
||||||
|
|
||||||
|
# Documentation: docs/section-name
|
||||||
|
docs/code-of-conduct-update
|
||||||
|
docs/api-documentation
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Commit Message Format
|
||||||
|
```bash
|
||||||
|
# Format: <type>: <description>
|
||||||
|
# Examples:
|
||||||
|
feat: add dark mode toggle to settings menu
|
||||||
|
fix: resolve tile swap animation timing issue
|
||||||
|
docs: update naming conventions in code of conduct
|
||||||
|
refactor: migrate print statements to DebugManager
|
||||||
|
test: add comprehensive match3 validation tests
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. Quick Reference Summary
|
||||||
|
|
||||||
|
| File Type | Convention | Example |
|
||||||
|
|-----------|------------|---------|
|
||||||
|
| **GDScript Files** | PascalCase | `MainMenu.gd`, `AudioManager.gd` |
|
||||||
|
| **Scene Files** | PascalCase | `MainMenu.tscn`, `Match3Gameplay.tscn` |
|
||||||
|
| **Test Files** | Test + PascalCase | `TestAudioManager.gd` |
|
||||||
|
| **Variables/Functions** | snake_case | `player_health`, `calculate_damage()` |
|
||||||
|
| **Constants** | SCREAMING_SNAKE_CASE | `MAX_HEALTH`, `TILE_SPACING` |
|
||||||
|
| **Classes** | PascalCase | `class_name PlayerController` |
|
||||||
|
| **Signals** | past_tense | `health_changed`, `game_started` |
|
||||||
|
| **Directories** | snake_case (src) / kebab-case (assets) | `src/autoloads/`, `assets/audio-files/` |
|
||||||
|
| **Assets** | kebab-case | `background-music.ogg`, `gem-blue.png` |
|
||||||
|
| **Config Files** | lowercase.extension | `project.godot`, `.gdformatrc` |
|
||||||
|
| **Branches** | type/kebab-case | `feature/new-gameplay`, `fix/tile-bug` |
|
||||||
|
|
||||||
|
> ✅ **Status**: All major file naming inconsistencies have been resolved. The project now follows consistent PascalCase naming for all .gd and .tscn files.
|
||||||
|
|
||||||
|
### 8. File Renaming Migration Guide
|
||||||
|
|
||||||
|
When renaming files to follow conventions:
|
||||||
|
|
||||||
|
**Step-by-step procedure:**
|
||||||
|
1. **Use Git rename**: `git mv old_file.gd NewFile.gd` (preserves history)
|
||||||
|
2. **Update .tscn references**: Modify script path in scene files
|
||||||
|
3. **Update code references**: Search and replace all `preload()` and `load()` statements
|
||||||
|
4. **Update project.godot**: If file is referenced in autoloads or project settings
|
||||||
|
5. **Update documentation**: Search all .md files for old references
|
||||||
|
6. **Update test files**: Modify any test files that reference the renamed file
|
||||||
|
7. **Run validation**: Execute `gdlint`, `gdformat`, and project tests
|
||||||
|
8. **Verify in editor**: Load scenes in Godot editor to confirm everything works
|
||||||
|
|
||||||
|
**Tools for validation:**
|
||||||
|
- `python tools/run_development.py --test` - Run all tests
|
||||||
|
- `python tools/run_development.py --lint` - Check code quality
|
||||||
|
- `python tools/run_development.py --format` - Ensure consistent formatting
|
||||||
|
|
||||||
## Common Mistakes to Avoid
|
## Common Mistakes to Avoid
|
||||||
|
|
||||||
### Architecture Violations
|
### Architecture Violations
|
||||||
@@ -271,7 +480,7 @@ wip
|
|||||||
get_tree().change_scene_to_file("some_scene.tscn")
|
get_tree().change_scene_to_file("some_scene.tscn")
|
||||||
|
|
||||||
# Don't hardcode paths
|
# Don't hardcode paths
|
||||||
var tile = load("res://scenes/game/gameplays/tile.tscn")
|
var tile = load("res://scenes/game/gameplays/Tile.tscn")
|
||||||
|
|
||||||
# Don't ignore null checks
|
# Don't ignore null checks
|
||||||
var node = get_node("SomeNode")
|
var node = get_node("SomeNode")
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
This document outlines the code quality standards implemented in the Skelly project and provides guidelines for maintaining high-quality, reliable code.
|
This document outlines the code quality standards implemented in the Skelly project and provides guidelines for maintaining high-quality, reliable code.
|
||||||
|
|
||||||
|
> 📋 **Naming Standards**: All code follows the [Naming Convention Quick Reference](CODE_OF_CONDUCT.md#naming-convention-quick-reference) for consistent file, class, and variable naming.
|
||||||
|
|
||||||
## Overview of Improvements
|
## Overview of Improvements
|
||||||
|
|
||||||
A comprehensive code quality improvement was conducted to eliminate critical flaws, improve maintainability, and ensure production-ready reliability. The improvements focus on memory safety, error handling, architecture quality, and input validation.
|
A comprehensive code quality improvement was conducted to eliminate critical flaws, improve maintainability, and ensure production-ready reliability. The improvements focus on memory safety, error handling, architecture quality, and input validation.
|
||||||
@@ -28,7 +30,7 @@ for child in children_to_remove:
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Files Improved:**
|
**Files Improved:**
|
||||||
- `scenes/game/gameplays/match3_gameplay.gd`
|
- `scenes/game/gameplays/Match3Gameplay.gd`
|
||||||
- `scenes/game/gameplays/tile.gd`
|
- `scenes/game/gameplays/tile.gd`
|
||||||
|
|
||||||
### 2. Error Handling & Recovery
|
### 2. Error Handling & Recovery
|
||||||
@@ -111,7 +113,7 @@ static func set_active_gem_pool(gem_indices: Array) -> void:
|
|||||||
|
|
||||||
**Files Improved:**
|
**Files Improved:**
|
||||||
- `scenes/game/gameplays/tile.gd`
|
- `scenes/game/gameplays/tile.gd`
|
||||||
- `scenes/game/gameplays/match3_gameplay.gd`
|
- `scenes/game/gameplays/Match3Gameplay.gd`
|
||||||
|
|
||||||
## 🟡 Code Quality Improvements
|
## 🟡 Code Quality Improvements
|
||||||
|
|
||||||
@@ -173,7 +175,7 @@ func _move_cursor(direction: Vector2i) -> void:
|
|||||||
|
|
||||||
**Files Improved:**
|
**Files Improved:**
|
||||||
- `scenes/ui/SettingsMenu.gd`
|
- `scenes/ui/SettingsMenu.gd`
|
||||||
- `scenes/game/gameplays/match3_gameplay.gd`
|
- `scenes/game/gameplays/Match3Gameplay.gd`
|
||||||
- `src/autoloads/GameManager.gd`
|
- `src/autoloads/GameManager.gd`
|
||||||
|
|
||||||
## Development Standards
|
## Development Standards
|
||||||
|
|||||||
14
docs/MAP.md
14
docs/MAP.md
@@ -3,6 +3,8 @@
|
|||||||
## Overview
|
## Overview
|
||||||
Skelly is a Godot 4.4 game project featuring multiple gameplay modes. The project supports match-3 puzzle gameplay with planned clickomania gameplay through a modular gameplay architecture. It follows a modular structure with clear separation between scenes, autoloads, assets, and data.
|
Skelly is a Godot 4.4 game project featuring multiple gameplay modes. The project supports match-3 puzzle gameplay with planned clickomania gameplay through a modular gameplay architecture. It follows a modular structure with clear separation between scenes, autoloads, assets, and data.
|
||||||
|
|
||||||
|
> 📋 **Naming Conventions**: All file and directory naming follows the standards defined in [Naming Convention Quick Reference](CODE_OF_CONDUCT.md#naming-convention-quick-reference).
|
||||||
|
|
||||||
## Project Root Structure
|
## Project Root Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -150,8 +152,8 @@ The game now uses a modular gameplay architecture where different game modes can
|
|||||||
|
|
||||||
### Current Gameplay Modes
|
### Current Gameplay Modes
|
||||||
|
|
||||||
#### Match-3 Mode (`scenes/game/gameplays/match3_gameplay.tscn`)
|
#### Match-3 Mode (`scenes/game/gameplays/Match3Gameplay.tscn`)
|
||||||
1. **Match3 Controller** (`scenes/game/gameplays/match3_gameplay.gd`)
|
1. **Match3 Controller** (`scenes/game/gameplays/Match3Gameplay.gd`)
|
||||||
- Grid management (8x8 default) with memory-safe node cleanup
|
- Grid management (8x8 default) with memory-safe node cleanup
|
||||||
- Match detection algorithms with bounds checking and validation
|
- Match detection algorithms with bounds checking and validation
|
||||||
- Tile dropping and refilling with signal connections
|
- Tile dropping and refilling with signal connections
|
||||||
@@ -178,7 +180,7 @@ The game now uses a modular gameplay architecture where different game modes can
|
|||||||
- Smooth animations with Tween system
|
- Smooth animations with Tween system
|
||||||
- **Memory Safety**: Resource management and cleanup
|
- **Memory Safety**: Resource management and cleanup
|
||||||
|
|
||||||
#### Clickomania Mode (`scenes/game/gameplays/clickomania_gameplay.tscn`)
|
#### Clickomania Mode (`scenes/game/gameplays/ClickomaniaGameplay.tscn`)
|
||||||
- Planned implementation for clickomania-style gameplay
|
- Planned implementation for clickomania-style gameplay
|
||||||
- Will integrate with same scoring and UI systems as match-3
|
- Will integrate with same scoring and UI systems as match-3
|
||||||
|
|
||||||
@@ -262,9 +264,9 @@ sprites:
|
|||||||
- `MainStrings.ru.translation` - Russian translations
|
- `MainStrings.ru.translation` - Russian translations
|
||||||
|
|
||||||
### Testing & Validation (`tests/`)
|
### Testing & Validation (`tests/`)
|
||||||
- `test_logging.gd` - DebugManager logging system validation
|
- `TestLogging.gd` - DebugManager logging system validation
|
||||||
- **`test_checksum_issue.gd`** - SaveManager checksum validation and deterministic hashing
|
- **`test_checksum_issue.gd`** - SaveManager checksum validation and deterministic hashing
|
||||||
- **`test_migration_compatibility.gd`** - SaveManager version migration and backward compatibility
|
- **`TestMigrationCompatibility.gd`** - SaveManager version migration and backward compatibility
|
||||||
- **`test_save_system_integration.gd`** - Complete save/load workflow integration testing
|
- **`test_save_system_integration.gd`** - Complete save/load workflow integration testing
|
||||||
- **`test_checksum_fix_verification.gd`** - JSON serialization checksum fix verification
|
- **`test_checksum_fix_verification.gd`** - JSON serialization checksum fix verification
|
||||||
- `README.md` - Brief directory overview (see docs/TESTING.md for full guidelines)
|
- `README.md` - Brief directory overview (see docs/TESTING.md for full guidelines)
|
||||||
@@ -296,7 +298,7 @@ GameManager --> main.tscn, game.tscn
|
|||||||
GameManager --> scenes/game/gameplays/*.tscn (via GAMEPLAY_SCENES constant)
|
GameManager --> scenes/game/gameplays/*.tscn (via GAMEPLAY_SCENES constant)
|
||||||
Main --> MainMenu.tscn, SettingsMenu.tscn
|
Main --> MainMenu.tscn, SettingsMenu.tscn
|
||||||
Game --> GameplayContainer (dynamic loading of gameplay scenes)
|
Game --> GameplayContainer (dynamic loading of gameplay scenes)
|
||||||
Game --> scenes/game/gameplays/match3_gameplay.tscn, clickomania_gameplay.tscn
|
Game --> scenes/game/gameplays/Match3Gameplay.tscn, ClickomaniaGameplay.tscn
|
||||||
```
|
```
|
||||||
|
|
||||||
### Asset Dependencies
|
### Asset Dependencies
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ The `tests/` directory contains:
|
|||||||
- Performance benchmarks
|
- Performance benchmarks
|
||||||
- Debugging tools
|
- Debugging tools
|
||||||
|
|
||||||
|
> 📋 **File Naming**: All test files follow the [naming conventions](CODE_OF_CONDUCT.md#2-file-naming-standards) with PascalCase and "Test" prefix (e.g., `TestAudioManager.gd`).
|
||||||
|
|
||||||
## Current Test Files
|
## Current Test Files
|
||||||
|
|
||||||
### `test_logging.gd`
|
### `TestLogging.gd`
|
||||||
Test script for DebugManager logging system.
|
Test script for DebugManager logging system.
|
||||||
|
|
||||||
**Features:**
|
**Features:**
|
||||||
@@ -26,10 +28,10 @@ Test script for DebugManager logging system.
|
|||||||
**Usage:**
|
**Usage:**
|
||||||
```gdscript
|
```gdscript
|
||||||
# Option 1: Add as temporary autoload
|
# Option 1: Add as temporary autoload
|
||||||
# In project.godot, add: tests/test_logging.gd
|
# In project.godot, add: tests/TestLogging.gd
|
||||||
|
|
||||||
# Option 2: Instantiate in a scene
|
# Option 2: Instantiate in a scene
|
||||||
var test_script = preload("res://tests/test_logging.gd").new()
|
var test_script = preload("res://tests/TestLogging.gd").new()
|
||||||
add_child(test_script)
|
add_child(test_script)
|
||||||
|
|
||||||
# Option 3: Run directly from editor
|
# Option 3: Run directly from editor
|
||||||
@@ -49,7 +51,7 @@ Follow these conventions for new test files:
|
|||||||
|
|
||||||
### File Naming
|
### File Naming
|
||||||
- Use descriptive names starting with `test_`
|
- Use descriptive names starting with `test_`
|
||||||
- Example: `test_audio_manager.gd`, `test_scene_transitions.gd`
|
- Example: `TestAudioManager.gd`, `test_scene_transitions.gd`
|
||||||
|
|
||||||
### File Structure
|
### File Structure
|
||||||
```gdscript
|
```gdscript
|
||||||
@@ -104,20 +106,20 @@ func test_error_conditions():
|
|||||||
|
|
||||||
### System Tests
|
### System Tests
|
||||||
Test core autoload managers and global systems:
|
Test core autoload managers and global systems:
|
||||||
- `test_logging.gd` - DebugManager logging system
|
- `TestLogging.gd` - DebugManager logging system
|
||||||
- `test_checksum_issue.gd` - SaveManager checksum validation and deterministic hashing
|
- `test_checksum_issue.gd` - SaveManager checksum validation and deterministic hashing
|
||||||
- `test_migration_compatibility.gd` - SaveManager version migration and backward compatibility
|
- `TestMigrationCompatibility.gd` - SaveManager version migration and backward compatibility
|
||||||
- `test_save_system_integration.gd` - Complete save/load workflow integration testing
|
- `test_save_system_integration.gd` - Complete save/load workflow integration testing
|
||||||
- `test_checksum_fix_verification.gd` - Verification of JSON serialization checksum fixes
|
- `test_checksum_fix_verification.gd` - Verification of JSON serialization checksum fixes
|
||||||
- `test_settings_manager.gd` - SettingsManager security validation, input validation, and error handling
|
- `TestSettingsManager.gd` - SettingsManager security validation, input validation, and error handling
|
||||||
- `test_game_manager.gd` - GameManager scene transitions, race condition protection, and input validation
|
- `TestGameManager.gd` - GameManager scene transitions, race condition protection, and input validation
|
||||||
- `test_audio_manager.gd` - AudioManager functionality, resource loading, and volume management
|
- `TestAudioManager.gd` - AudioManager functionality, resource loading, and volume management
|
||||||
|
|
||||||
### Component Tests
|
### Component Tests
|
||||||
Test individual game components:
|
Test individual game components:
|
||||||
- `test_match3_gameplay.gd` - Match-3 gameplay mechanics, grid management, and match detection
|
- `TestMatch3Gameplay.gd` - Match-3 gameplay mechanics, grid management, and match detection
|
||||||
- `test_tile.gd` - Tile component behavior, visual feedback, and memory safety
|
- `TestTile.gd` - Tile component behavior, visual feedback, and memory safety
|
||||||
- `test_value_stepper.gd` - ValueStepper UI component functionality and settings integration
|
- `TestValueStepper.gd` - ValueStepper UI component functionality and settings integration
|
||||||
|
|
||||||
### Integration Tests
|
### Integration Tests
|
||||||
Test system interactions and workflows:
|
Test system interactions and workflows:
|
||||||
@@ -135,7 +137,7 @@ SaveManager implements security features requiring testing for modifications.
|
|||||||
**Tests**: Checksum generation, JSON serialization consistency, save/load cycles
|
**Tests**: Checksum generation, JSON serialization consistency, save/load cycles
|
||||||
**Usage**: Run after checksum algorithm changes
|
**Usage**: Run after checksum algorithm changes
|
||||||
|
|
||||||
#### **`test_migration_compatibility.gd`** - Version Migration
|
#### **`TestMigrationCompatibility.gd`** - Version Migration
|
||||||
**Tests**: Backward compatibility, missing field addition, data structure normalization
|
**Tests**: Backward compatibility, missing field addition, data structure normalization
|
||||||
**Usage**: Test save format upgrades
|
**Usage**: Test save format upgrades
|
||||||
|
|
||||||
@@ -164,7 +166,7 @@ SaveManager implements security features requiring testing for modifications.
|
|||||||
|
|
||||||
#### **Test Sequence After Modifications**
|
#### **Test Sequence After Modifications**
|
||||||
1. `test_checksum_issue.gd` - Verify checksum consistency
|
1. `test_checksum_issue.gd` - Verify checksum consistency
|
||||||
2. `test_migration_compatibility.gd` - Check version upgrades
|
2. `TestMigrationCompatibility.gd` - Check version upgrades
|
||||||
3. `test_save_system_integration.gd` - Validate workflow
|
3. `test_save_system_integration.gd` - Validate workflow
|
||||||
4. Manual testing with corrupted files
|
4. Manual testing with corrupted files
|
||||||
5. Performance validation
|
5. Performance validation
|
||||||
@@ -182,7 +184,7 @@ godot --headless --script tests/test_checksum_issue.gd
|
|||||||
|
|
||||||
# Run all save system tests
|
# Run all save system tests
|
||||||
godot --headless --script tests/test_checksum_issue.gd
|
godot --headless --script tests/test_checksum_issue.gd
|
||||||
godot --headless --script tests/test_migration_compatibility.gd
|
godot --headless --script tests/TestMigrationCompatibility.gd
|
||||||
godot --headless --script tests/test_save_system_integration.gd
|
godot --headless --script tests/test_save_system_integration.gd
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -200,7 +202,7 @@ For CI/CD integration:
|
|||||||
- name: Run Test Suite
|
- name: Run Test Suite
|
||||||
run: |
|
run: |
|
||||||
godot --headless --script tests/test_checksum_issue.gd
|
godot --headless --script tests/test_checksum_issue.gd
|
||||||
godot --headless --script tests/test_migration_compatibility.gd
|
godot --headless --script tests/TestMigrationCompatibility.gd
|
||||||
# Add other tests as needed
|
# Add other tests as needed
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
394
export_presets.cfg
Normal file
394
export_presets.cfg
Normal file
@@ -0,0 +1,394 @@
|
|||||||
|
[preset.0]
|
||||||
|
|
||||||
|
name="Windows Desktop"
|
||||||
|
platform="Windows Desktop"
|
||||||
|
runnable=true
|
||||||
|
dedicated_server=false
|
||||||
|
custom_features=""
|
||||||
|
export_filter="all_resources"
|
||||||
|
export_files=PackedStringArray()
|
||||||
|
include_filter=""
|
||||||
|
exclude_filter=""
|
||||||
|
export_path="builds/skelly-windows.exe"
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
|
||||||
|
[preset.0.options]
|
||||||
|
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
debug/export_console_wrapper=1
|
||||||
|
binary_format/embed_pck=true
|
||||||
|
texture_format/bptc=true
|
||||||
|
texture_format/s3tc=true
|
||||||
|
texture_format/etc=false
|
||||||
|
texture_format/etc2=false
|
||||||
|
binary_format/architecture="x86_64"
|
||||||
|
codesign/enable=false
|
||||||
|
codesign/identity=""
|
||||||
|
codesign/password=""
|
||||||
|
codesign/timestamp=true
|
||||||
|
codesign/timestamp_server_url=""
|
||||||
|
codesign/digest_algorithm=1
|
||||||
|
codesign/description=""
|
||||||
|
codesign/custom_options=PackedStringArray()
|
||||||
|
application/modify_resources=true
|
||||||
|
application/icon=""
|
||||||
|
application/console_wrapper_icon=""
|
||||||
|
application/icon_interpolation=4
|
||||||
|
application/file_version=""
|
||||||
|
application/product_version=""
|
||||||
|
application/company_name=""
|
||||||
|
application/product_name="Skelly"
|
||||||
|
application/file_description=""
|
||||||
|
application/copyright=""
|
||||||
|
application/trademarks=""
|
||||||
|
application/export_angle=0
|
||||||
|
ssh_remote_deploy/enabled=false
|
||||||
|
ssh_remote_deploy/host="user@host_ip"
|
||||||
|
ssh_remote_deploy/port="22"
|
||||||
|
ssh_remote_deploy/extra_args_ssh=""
|
||||||
|
ssh_remote_deploy/extra_args_scp=""
|
||||||
|
ssh_remote_deploy/run_script=""
|
||||||
|
ssh_remote_deploy/cleanup_script=""
|
||||||
|
|
||||||
|
[preset.1]
|
||||||
|
|
||||||
|
name="Linux"
|
||||||
|
platform="Linux/X11"
|
||||||
|
runnable=true
|
||||||
|
dedicated_server=false
|
||||||
|
custom_features=""
|
||||||
|
export_filter="all_resources"
|
||||||
|
export_files=PackedStringArray()
|
||||||
|
include_filter=""
|
||||||
|
exclude_filter=""
|
||||||
|
export_path="builds/skelly-linux.x86_64"
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
|
||||||
|
[preset.1.options]
|
||||||
|
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
debug/export_console_wrapper=1
|
||||||
|
binary_format/embed_pck=true
|
||||||
|
texture_format/bptc=true
|
||||||
|
texture_format/s3tc=true
|
||||||
|
texture_format/etc=false
|
||||||
|
texture_format/etc2=false
|
||||||
|
binary_format/architecture="x86_64"
|
||||||
|
ssh_remote_deploy/enabled=false
|
||||||
|
ssh_remote_deploy/host="user@host_ip"
|
||||||
|
ssh_remote_deploy/port="22"
|
||||||
|
ssh_remote_deploy/extra_args_ssh=""
|
||||||
|
ssh_remote_deploy/extra_args_scp=""
|
||||||
|
ssh_remote_deploy/run_script=""
|
||||||
|
ssh_remote_deploy/cleanup_script=""
|
||||||
|
|
||||||
|
[preset.2]
|
||||||
|
|
||||||
|
name="macOS"
|
||||||
|
platform="macOS"
|
||||||
|
runnable=true
|
||||||
|
dedicated_server=false
|
||||||
|
custom_features=""
|
||||||
|
export_filter="all_resources"
|
||||||
|
export_files=PackedStringArray()
|
||||||
|
include_filter=""
|
||||||
|
exclude_filter=""
|
||||||
|
export_path="builds/skelly-macos.zip"
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
|
||||||
|
[preset.2.options]
|
||||||
|
|
||||||
|
binary_format/architecture="universal"
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
debug/export_console_wrapper=1
|
||||||
|
application/icon=""
|
||||||
|
application/icon_interpolation=4
|
||||||
|
application/bundle_identifier="com.skelly.game"
|
||||||
|
application/signature=""
|
||||||
|
application/app_category="Games"
|
||||||
|
application/short_version="1.0"
|
||||||
|
application/version="1.0"
|
||||||
|
application/copyright=""
|
||||||
|
application/copyright_localized={}
|
||||||
|
application/min_macos_version="10.12"
|
||||||
|
display/high_res=false
|
||||||
|
xcode/platform_build="14C18"
|
||||||
|
xcode/sdk_version="13.1"
|
||||||
|
xcode/sdk_name="macosx13.1"
|
||||||
|
xcode/sdk_build="22C55"
|
||||||
|
xcode/xcode_version="1420"
|
||||||
|
xcode/xcode_build="14C18"
|
||||||
|
codesign/codesign=1
|
||||||
|
codesign/installer_identity=""
|
||||||
|
codesign/apple_team_id=""
|
||||||
|
codesign/identity=""
|
||||||
|
codesign/entitlements/custom_file=""
|
||||||
|
codesign/entitlements/allow_jit_code_execution=false
|
||||||
|
codesign/entitlements/allow_unsigned_executable_memory=false
|
||||||
|
codesign/entitlements/allow_dyld_environment_variables=false
|
||||||
|
codesign/entitlements/disable_library_validation=false
|
||||||
|
codesign/entitlements/audio_input=false
|
||||||
|
codesign/entitlements/camera=false
|
||||||
|
codesign/entitlements/location=false
|
||||||
|
codesign/entitlements/address_book=false
|
||||||
|
codesign/entitlements/calendars=false
|
||||||
|
codesign/entitlements/photos_library=false
|
||||||
|
codesign/entitlements/apple_events=false
|
||||||
|
codesign/entitlements/debugging=false
|
||||||
|
codesign/entitlements/app_sandbox/enabled=false
|
||||||
|
codesign/entitlements/app_sandbox/network_server=false
|
||||||
|
codesign/entitlements/app_sandbox/network_client=false
|
||||||
|
codesign/entitlements/app_sandbox/device_usb=false
|
||||||
|
codesign/entitlements/app_sandbox/device_bluetooth=false
|
||||||
|
codesign/entitlements/app_sandbox/files_downloads=0
|
||||||
|
codesign/entitlements/app_sandbox/files_pictures=0
|
||||||
|
codesign/entitlements/app_sandbox/files_music=0
|
||||||
|
codesign/entitlements/app_sandbox/files_movies=0
|
||||||
|
codesign/entitlements/app_sandbox/helper_executables=[]
|
||||||
|
notarization/notarization=0
|
||||||
|
privacy/microphone_usage_description=""
|
||||||
|
privacy/microphone_usage_description_localized={}
|
||||||
|
privacy/camera_usage_description=""
|
||||||
|
privacy/camera_usage_description_localized={}
|
||||||
|
privacy/location_usage_description=""
|
||||||
|
privacy/location_usage_description_localized={}
|
||||||
|
privacy/address_book_usage_description=""
|
||||||
|
privacy/address_book_usage_description_localized={}
|
||||||
|
privacy/calendar_usage_description=""
|
||||||
|
privacy/calendar_usage_description_localized={}
|
||||||
|
privacy/photos_library_usage_description=""
|
||||||
|
privacy/photos_library_usage_description_localized={}
|
||||||
|
privacy/desktop_folder_usage_description=""
|
||||||
|
privacy/desktop_folder_usage_description_localized={}
|
||||||
|
privacy/documents_folder_usage_description=""
|
||||||
|
privacy/documents_folder_usage_description_localized={}
|
||||||
|
privacy/downloads_folder_usage_description=""
|
||||||
|
privacy/downloads_folder_usage_description_localized={}
|
||||||
|
privacy/network_volumes_usage_description=""
|
||||||
|
privacy/network_volumes_usage_description_localized={}
|
||||||
|
privacy/removable_volumes_usage_description=""
|
||||||
|
privacy/removable_volumes_usage_description_localized={}
|
||||||
|
ssh_remote_deploy/enabled=false
|
||||||
|
ssh_remote_deploy/host="user@host_ip"
|
||||||
|
ssh_remote_deploy/port="22"
|
||||||
|
ssh_remote_deploy/extra_args_ssh=""
|
||||||
|
ssh_remote_deploy/extra_args_scp=""
|
||||||
|
ssh_remote_deploy/run_script=""
|
||||||
|
ssh_remote_deploy/cleanup_script=""
|
||||||
|
|
||||||
|
[preset.3]
|
||||||
|
|
||||||
|
name="Android"
|
||||||
|
platform="Android"
|
||||||
|
runnable=true
|
||||||
|
dedicated_server=false
|
||||||
|
custom_features=""
|
||||||
|
export_filter="all_resources"
|
||||||
|
export_files=PackedStringArray()
|
||||||
|
include_filter=""
|
||||||
|
exclude_filter=""
|
||||||
|
export_path="builds/skelly-android.apk"
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
|
||||||
|
[preset.3.options]
|
||||||
|
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
gradle_build/use_gradle_build=false
|
||||||
|
gradle_build/export_format=0
|
||||||
|
gradle_build/min_sdk=""
|
||||||
|
gradle_build/target_sdk=""
|
||||||
|
architectures/armeabi-v7a=false
|
||||||
|
architectures/arm64-v8a=true
|
||||||
|
architectures/x86=false
|
||||||
|
architectures/x86_64=false
|
||||||
|
version/code=1
|
||||||
|
version/name="1.0"
|
||||||
|
package/unique_name="com.skelly.game"
|
||||||
|
package/name="Skelly"
|
||||||
|
package/signed=true
|
||||||
|
package/app_category=2
|
||||||
|
package/retain_data_on_uninstall=false
|
||||||
|
package/exclude_from_recents=false
|
||||||
|
launcher_icons/main_192x192=""
|
||||||
|
launcher_icons/adaptive_foreground_432x432=""
|
||||||
|
launcher_icons/adaptive_background_432x432=""
|
||||||
|
graphics/32_bits_framebuffer=true
|
||||||
|
graphics/opengl_debug=false
|
||||||
|
xr_features/xr_mode=0
|
||||||
|
xr_features/hand_tracking=0
|
||||||
|
xr_features/hand_tracking_frequency=0
|
||||||
|
xr_features/passthrough=0
|
||||||
|
screen/immersive_mode=true
|
||||||
|
screen/orientation=0
|
||||||
|
screen/support_small=true
|
||||||
|
screen/support_normal=true
|
||||||
|
screen/support_large=true
|
||||||
|
screen/support_xlarge=true
|
||||||
|
user_data_backup/allow=false
|
||||||
|
command_line/extra_args=""
|
||||||
|
apk_expansion/enable=false
|
||||||
|
apk_expansion/SALT=""
|
||||||
|
apk_expansion/public_key=""
|
||||||
|
permissions/custom_permissions=PackedStringArray()
|
||||||
|
permissions/access_checkin_properties=false
|
||||||
|
permissions/access_coarse_location=false
|
||||||
|
permissions/access_fine_location=false
|
||||||
|
permissions/access_location_extra_commands=false
|
||||||
|
permissions/access_mock_location=false
|
||||||
|
permissions/access_network_state=false
|
||||||
|
permissions/access_surface_flinger=false
|
||||||
|
permissions/access_wifi_state=false
|
||||||
|
permissions/account_manager=false
|
||||||
|
permissions/add_voicemail=false
|
||||||
|
permissions/authenticate_accounts=false
|
||||||
|
permissions/battery_stats=false
|
||||||
|
permissions/bind_accessibility_service=false
|
||||||
|
permissions/bind_appwidget=false
|
||||||
|
permissions/bind_device_admin=false
|
||||||
|
permissions/bind_input_method=false
|
||||||
|
permissions/bind_nfc_service=false
|
||||||
|
permissions/bind_notification_listener_service=false
|
||||||
|
permissions/bind_print_service=false
|
||||||
|
permissions/bind_remoteviews=false
|
||||||
|
permissions/bind_text_service=false
|
||||||
|
permissions/bind_vpn_service=false
|
||||||
|
permissions/bind_wallpaper=false
|
||||||
|
permissions/bluetooth=false
|
||||||
|
permissions/bluetooth_admin=false
|
||||||
|
permissions/bluetooth_privileged=false
|
||||||
|
permissions/brick=false
|
||||||
|
permissions/broadcast_package_removed=false
|
||||||
|
permissions/broadcast_sms=false
|
||||||
|
permissions/broadcast_sticky=false
|
||||||
|
permissions/broadcast_wap_push=false
|
||||||
|
permissions/call_phone=false
|
||||||
|
permissions/call_privileged=false
|
||||||
|
permissions/camera=false
|
||||||
|
permissions/capture_audio_output=false
|
||||||
|
permissions/capture_secure_video_output=false
|
||||||
|
permissions/capture_video_output=false
|
||||||
|
permissions/change_component_enabled_state=false
|
||||||
|
permissions/change_configuration=false
|
||||||
|
permissions/change_network_state=false
|
||||||
|
permissions/change_wifi_multicast_state=false
|
||||||
|
permissions/change_wifi_state=false
|
||||||
|
permissions/clear_app_cache=false
|
||||||
|
permissions/clear_app_user_data=false
|
||||||
|
permissions/control_location_updates=false
|
||||||
|
permissions/delete_cache_files=false
|
||||||
|
permissions/delete_packages=false
|
||||||
|
permissions/device_power=false
|
||||||
|
permissions/diagnostic=false
|
||||||
|
permissions/disable_keyguard=false
|
||||||
|
permissions/dump=false
|
||||||
|
permissions/expand_status_bar=false
|
||||||
|
permissions/factory_test=false
|
||||||
|
permissions/flashlight=false
|
||||||
|
permissions/force_back=false
|
||||||
|
permissions/get_accounts=false
|
||||||
|
permissions/get_package_size=false
|
||||||
|
permissions/get_tasks=false
|
||||||
|
permissions/get_top_activity_info=false
|
||||||
|
permissions/global_search=false
|
||||||
|
permissions/hardware_test=false
|
||||||
|
permissions/inject_events=false
|
||||||
|
permissions/install_location_provider=false
|
||||||
|
permissions/install_packages=false
|
||||||
|
permissions/install_shortcut=false
|
||||||
|
permissions/internal_system_window=false
|
||||||
|
permissions/internet=false
|
||||||
|
permissions/kill_background_processes=false
|
||||||
|
permissions/location_hardware=false
|
||||||
|
permissions/manage_accounts=false
|
||||||
|
permissions/manage_app_tokens=false
|
||||||
|
permissions/manage_documents=false
|
||||||
|
permissions/manage_external_storage=false
|
||||||
|
permissions/master_clear=false
|
||||||
|
permissions/media_content_control=false
|
||||||
|
permissions/modify_audio_settings=false
|
||||||
|
permissions/modify_phone_state=false
|
||||||
|
permissions/mount_format_filesystems=false
|
||||||
|
permissions/mount_unmount_filesystems=false
|
||||||
|
permissions/nfc=false
|
||||||
|
permissions/persistent_activity=false
|
||||||
|
permissions/process_outgoing_calls=false
|
||||||
|
permissions/read_calendar=false
|
||||||
|
permissions/read_call_log=false
|
||||||
|
permissions/read_contacts=false
|
||||||
|
permissions/read_external_storage=false
|
||||||
|
permissions/read_frame_buffer=false
|
||||||
|
permissions/read_history_bookmarks=false
|
||||||
|
permissions/read_input_state=false
|
||||||
|
permissions/read_logs=false
|
||||||
|
permissions/read_phone_state=false
|
||||||
|
permissions/read_profile=false
|
||||||
|
permissions/read_sms=false
|
||||||
|
permissions/read_social_stream=false
|
||||||
|
permissions/read_sync_settings=false
|
||||||
|
permissions/read_sync_stats=false
|
||||||
|
permissions/read_user_dictionary=false
|
||||||
|
permissions/reboot=false
|
||||||
|
permissions/receive_boot_completed=false
|
||||||
|
permissions/receive_mms=false
|
||||||
|
permissions/receive_sms=false
|
||||||
|
permissions/receive_wap_push=false
|
||||||
|
permissions/record_audio=false
|
||||||
|
permissions/reorder_tasks=false
|
||||||
|
permissions/restart_packages=false
|
||||||
|
permissions/send_respond_via_message=false
|
||||||
|
permissions/send_sms=false
|
||||||
|
permissions/set_activity_watcher=false
|
||||||
|
permissions/set_alarm=false
|
||||||
|
permissions/set_always_finish=false
|
||||||
|
permissions/set_animation_scale=false
|
||||||
|
permissions/set_debug_app=false
|
||||||
|
permissions/set_orientation=false
|
||||||
|
permissions/set_pointer_speed=false
|
||||||
|
permissions/set_preferred_applications=false
|
||||||
|
permissions/set_process_limit=false
|
||||||
|
permissions/set_time=false
|
||||||
|
permissions/set_time_zone=false
|
||||||
|
permissions/set_wallpaper=false
|
||||||
|
permissions/set_wallpaper_hints=false
|
||||||
|
permissions/signal_persistent_processes=false
|
||||||
|
permissions/status_bar=false
|
||||||
|
permissions/subscribed_feeds_read=false
|
||||||
|
permissions/subscribed_feeds_write=false
|
||||||
|
permissions/system_alert_window=false
|
||||||
|
permissions/transmit_ir=false
|
||||||
|
permissions/uninstall_shortcut=false
|
||||||
|
permissions/update_device_stats=false
|
||||||
|
permissions/use_credentials=false
|
||||||
|
permissions/use_sip=false
|
||||||
|
permissions/vibrate=false
|
||||||
|
permissions/wake_lock=false
|
||||||
|
permissions/write_apn_settings=false
|
||||||
|
permissions/write_calendar=false
|
||||||
|
permissions/write_call_log=false
|
||||||
|
permissions/write_contacts=false
|
||||||
|
permissions/write_external_storage=false
|
||||||
|
permissions/write_gservices=false
|
||||||
|
permissions/write_history_bookmarks=false
|
||||||
|
permissions/write_profile=false
|
||||||
|
permissions/write_secure_settings=false
|
||||||
|
permissions/write_settings=false
|
||||||
|
permissions/write_sms=false
|
||||||
|
permissions/write_social_stream=false
|
||||||
|
permissions/write_sync_settings=false
|
||||||
|
permissions/write_user_dictionary=false
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
setuptools<81
|
setuptools<81
|
||||||
gdtoolkit==4
|
gdtoolkit==4
|
||||||
|
aiofiles>=23.0.0
|
||||||
|
ruff>=0.1.0
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
const GAMEPLAY_SCENES = {
|
const GAMEPLAY_SCENES = {
|
||||||
"match3": "res://scenes/game/gameplays/match3_gameplay.tscn",
|
"match3": "res://scenes/game/gameplays/Match3Gameplay.tscn",
|
||||||
"clickomania": "res://scenes/game/gameplays/clickomania_gameplay.tscn"
|
"clickomania": "res://scenes/game/gameplays/ClickomaniaGameplay.tscn"
|
||||||
}
|
}
|
||||||
|
|
||||||
var current_gameplay_mode: String
|
var current_gameplay_mode: String
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://dmwkyeq2l7u04"]
|
[gd_scene load_steps=4 format=3 uid="uid://8c2w55brpwmm"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://bs4veuda3h358" path="res://scenes/game/game.gd" id="1_uwrxv"]
|
[ext_resource type="Script" uid="uid://bs4veuda3h358" path="res://scenes/game/game.gd" id="1_uwrxv"]
|
||||||
[ext_resource type="PackedScene" path="res://scenes/ui/DebugToggle.tscn" id="3_debug"]
|
[ext_resource type="PackedScene" path="res://scenes/ui/DebugToggle.tscn" id="3_debug"]
|
||||||
|
|||||||
1
scenes/game/gameplays/ClickomaniaGameplay.gd.uid
Normal file
1
scenes/game/gameplays/ClickomaniaGameplay.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://bkheckv0upd82
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene load_steps=2 format=3 uid="uid://cl7g8v0eh3mam"]
|
[gd_scene load_steps=2 format=3 uid="uid://cl7g8v0eh3mam"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://scenes/game/gameplays/clickomania_gameplay.gd" id="1_script"]
|
[ext_resource type="Script" path="res://scenes/game/gameplays/ClickomaniaGameplay.gd" id="1_script"]
|
||||||
|
|
||||||
[node name="Clickomania" type="Node2D"]
|
[node name="Clickomania" type="Node2D"]
|
||||||
script = ExtResource("1_script")
|
script = ExtResource("1_script")
|
||||||
@@ -4,7 +4,7 @@ extends DebugMenuBase
|
|||||||
func _ready():
|
func _ready():
|
||||||
# Set specific configuration for Match3DebugMenu
|
# Set specific configuration for Match3DebugMenu
|
||||||
log_category = "Match3"
|
log_category = "Match3"
|
||||||
target_script_path = "res://scenes/game/gameplays/match3_gameplay.gd"
|
target_script_path = "res://scenes/game/gameplays/Match3Gameplay.gd"
|
||||||
|
|
||||||
# Call parent's _ready
|
# Call parent's _ready
|
||||||
super()
|
super()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ signal grid_state_loaded(grid_size: Vector2i, tile_types: int)
|
|||||||
## PROCESSING: Detecting matches, clearing tiles, dropping new ones, checking cascades
|
## PROCESSING: Detecting matches, clearing tiles, dropping new ones, checking cascades
|
||||||
enum GameState { WAITING, SELECTING, SWAPPING, PROCESSING }
|
enum GameState { WAITING, SELECTING, SWAPPING, PROCESSING }
|
||||||
|
|
||||||
const TILE_SCENE := preload("res://scenes/game/gameplays/tile.tscn")
|
const TILE_SCENE := preload("res://scenes/game/gameplays/Tile.tscn")
|
||||||
|
|
||||||
# Safety constants
|
# Safety constants
|
||||||
const MAX_GRID_SIZE := 15
|
const MAX_GRID_SIZE := 15
|
||||||
1
scenes/game/gameplays/Match3Gameplay.gd.uid
Normal file
1
scenes/game/gameplays/Match3Gameplay.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://dbbi8ooysxp7f
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[gd_scene load_steps=3 format=3 uid="uid://b4kv7g7kllwgb"]
|
[gd_scene load_steps=3 format=3 uid="uid://b4kv7g7kllwgb"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://o8crf6688lan" path="res://scenes/game/gameplays/match3_gameplay.gd" id="1_mvfdp"]
|
[ext_resource type="Script" uid="uid://o8crf6688lan" path="res://scenes/game/gameplays/Match3Gameplay.gd" id="1_mvfdp"]
|
||||||
[ext_resource type="PackedScene" uid="uid://b76oiwlifikl3" path="res://scenes/game/gameplays/Match3DebugMenu.tscn" id="2_debug_menu"]
|
[ext_resource type="PackedScene" uid="uid://b76oiwlifikl3" path="res://scenes/game/gameplays/Match3DebugMenu.tscn" id="2_debug_menu"]
|
||||||
|
|
||||||
[node name="Match3" type="Node2D"]
|
[node name="Match3" type="Node2D"]
|
||||||
1
scenes/game/gameplays/Match3InputHandler.gd.uid
Normal file
1
scenes/game/gameplays/Match3InputHandler.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://ogm8w7l6bhif
|
||||||
1
scenes/game/gameplays/Match3SaveManager.gd.uid
Normal file
1
scenes/game/gameplays/Match3SaveManager.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://duheejfr6de6x
|
||||||
1
scenes/game/gameplays/Match3Validator.gd.uid
Normal file
1
scenes/game/gameplays/Match3Validator.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://dy3aym6riijct
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://bapywtqdghjqp
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
[gd_scene load_steps=5 format=3 uid="uid://ci2gk11211n0d"]
|
[gd_scene load_steps=5 format=3 uid="uid://bwvq7u0mv5dku"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://rvuchiy0guv3" path="res://scenes/main/Main.gd" id="1_0wfyh"]
|
[ext_resource type="Script" uid="uid://rvuchiy0guv3" path="res://scenes/main/Main.gd" id="1_0wfyh"]
|
||||||
[ext_resource type="PackedScene" uid="uid://gbe1jarrwqsi" path="res://scenes/main/SplashScreen.tscn" id="1_o5qli"]
|
[ext_resource type="PackedScene" uid="uid://gbe1jarrwqsi" path="res://scenes/main/SplashScreen.tscn" id="1_o5qli"]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const MIN_GRID_SIZE := 3
|
|||||||
const MIN_TILE_TYPES := 3
|
const MIN_TILE_TYPES := 3
|
||||||
const SCENE_SEARCH_COOLDOWN := 0.5
|
const SCENE_SEARCH_COOLDOWN := 0.5
|
||||||
|
|
||||||
@export var target_script_path: String = "res://scenes/game/gameplays/match3_gameplay.gd"
|
@export var target_script_path: String = "res://scenes/game/gameplays/Match3Gameplay.gd"
|
||||||
@export var log_category: String = "DebugMenu"
|
@export var log_category: String = "DebugMenu"
|
||||||
|
|
||||||
var match3_scene: Node2D
|
var match3_scene: Node2D
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ For complete testing guidelines, conventions, and usage instructions, see:
|
|||||||
|
|
||||||
## Current Files
|
## Current Files
|
||||||
|
|
||||||
- `test_logging.gd` - Comprehensive logging system validation script
|
- `TestLogging.gd` - Comprehensive logging system validation script
|
||||||
|
|
||||||
## Quick Usage
|
## Quick Usage
|
||||||
|
|
||||||
```gdscript
|
```gdscript
|
||||||
# Add as temporary autoload or run in scene
|
# Add as temporary autoload or run in scene
|
||||||
var test_script = preload("res://tests/test_logging.gd").new()
|
var test_script = preload("res://tests/TestLogging.gd").new()
|
||||||
add_child(test_script)
|
add_child(test_script)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
1
tests/TestAudioManager.gd.uid
Normal file
1
tests/TestAudioManager.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://bloix8dfixjem
|
||||||
1
tests/TestGameManager.gd.uid
Normal file
1
tests/TestGameManager.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://b0ua34ofjdirr
|
||||||
1
tests/TestLogging.gd.uid
Normal file
1
tests/TestLogging.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://brqb7heh3g0ja
|
||||||
@@ -50,7 +50,7 @@ func setup_test_environment():
|
|||||||
TestHelperClass.print_step("Test Environment Setup")
|
TestHelperClass.print_step("Test Environment Setup")
|
||||||
|
|
||||||
# Load Match3 scene
|
# Load Match3 scene
|
||||||
match3_scene = load("res://scenes/game/gameplays/match3_gameplay.tscn")
|
match3_scene = load("res://scenes/game/gameplays/Match3Gameplay.tscn")
|
||||||
TestHelperClass.assert_not_null(match3_scene, "Match3 scene loads successfully")
|
TestHelperClass.assert_not_null(match3_scene, "Match3 scene loads successfully")
|
||||||
|
|
||||||
# Create test viewport for isolated testing
|
# Create test viewport for isolated testing
|
||||||
1
tests/TestMatch3Gameplay.gd.uid
Normal file
1
tests/TestMatch3Gameplay.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cmv4qyq0x0bvv
|
||||||
1
tests/TestMigrationCompatibility.gd.uid
Normal file
1
tests/TestMigrationCompatibility.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://graevpkmrau4
|
||||||
@@ -4,8 +4,8 @@ extends SceneTree
|
|||||||
## This test verifies that mouse input, hover events, and tile selection work correctly
|
## This test verifies that mouse input, hover events, and tile selection work correctly
|
||||||
|
|
||||||
# Preloaded scenes to avoid duplication
|
# Preloaded scenes to avoid duplication
|
||||||
const MATCH3_SCENE = preload("res://scenes/game/gameplays/match3_gameplay.tscn")
|
const MATCH3_SCENE = preload("res://scenes/game/gameplays/Match3Gameplay.tscn")
|
||||||
const TILE_SCENE = preload("res://scenes/game/gameplays/tile.tscn")
|
const TILE_SCENE = preload("res://scenes/game/gameplays/Tile.tscn")
|
||||||
|
|
||||||
|
|
||||||
func _initialize():
|
func _initialize():
|
||||||
@@ -34,12 +34,12 @@ func test_match3_scene_loading():
|
|||||||
print("Testing Match3 scene loading...")
|
print("Testing Match3 scene loading...")
|
||||||
|
|
||||||
if not MATCH3_SCENE:
|
if not MATCH3_SCENE:
|
||||||
print("❌ FAILED: Could not load match3_gameplay.tscn")
|
print("❌ FAILED: Could not load Match3Gameplay.tscn")
|
||||||
return
|
return
|
||||||
|
|
||||||
var match3_instance = MATCH3_SCENE.instantiate()
|
var match3_instance = MATCH3_SCENE.instantiate()
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
print("❌ FAILED: Could not instantiate match3_gameplay scene")
|
print("❌ FAILED: Could not instantiate Match3Gameplay scene")
|
||||||
return
|
return
|
||||||
|
|
||||||
root.add_child(match3_instance)
|
root.add_child(match3_instance)
|
||||||
1
tests/TestMouseSupport.gd.uid
Normal file
1
tests/TestMouseSupport.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://kdrhd734kdel
|
||||||
@@ -151,7 +151,7 @@ func test_critical_scenes():
|
|||||||
"res://scenes/main/main.tscn",
|
"res://scenes/main/main.tscn",
|
||||||
"res://scenes/game/game.tscn",
|
"res://scenes/game/game.tscn",
|
||||||
"res://scenes/ui/MainMenu.tscn",
|
"res://scenes/ui/MainMenu.tscn",
|
||||||
"res://scenes/game/gameplays/match3_gameplay.tscn"
|
"res://scenes/game/gameplays/Match3Gameplay.tscn"
|
||||||
]
|
]
|
||||||
|
|
||||||
for scene_path in critical_scenes:
|
for scene_path in critical_scenes:
|
||||||
1
tests/TestSceneValidation.gd.uid
Normal file
1
tests/TestSceneValidation.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://dco5ddmpe5o74
|
||||||
1
tests/TestSettingsManager.gd.uid
Normal file
1
tests/TestSettingsManager.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://btqloxgb5460v
|
||||||
@@ -50,7 +50,7 @@ func setup_test_environment():
|
|||||||
TestHelperClass.print_step("Test Environment Setup")
|
TestHelperClass.print_step("Test Environment Setup")
|
||||||
|
|
||||||
# Load Tile scene
|
# Load Tile scene
|
||||||
tile_scene = load("res://scenes/game/gameplays/tile.tscn")
|
tile_scene = load("res://scenes/game/gameplays/Tile.tscn")
|
||||||
TestHelperClass.assert_not_null(tile_scene, "Tile scene loads successfully")
|
TestHelperClass.assert_not_null(tile_scene, "Tile scene loads successfully")
|
||||||
|
|
||||||
# Create test viewport for isolated testing
|
# Create test viewport for isolated testing
|
||||||
1
tests/TestTile.gd.uid
Normal file
1
tests/TestTile.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cf6uxd4ewd7n8
|
||||||
1
tests/TestValueStepper.gd.uid
Normal file
1
tests/TestValueStepper.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://copuu5lcw562s
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://bo0vdi2uhl8bm
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://cxoh80im7pak
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://bwygfhgn60iw3
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://b0jpu50jmbt7t
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://cnhiygvadc13
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://gnepq3ww2d0a
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://b6kwoodf4xtfg
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://dopm8ivgucbgd
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://bdn1rf14bqwv4
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://cfofaihfhmh8q
|
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user