Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
90f2b82
Update .gitignore
ikostan Apr 19, 2026
85d572e
Update .gitignore
ikostan Apr 19, 2026
0365ec9
Update run_pipeline.sh
ikostan Apr 19, 2026
371d6bc
README updates
ikostan Apr 19, 2026
c3b3b09
Update run_pipeline.sh
ikostan Apr 19, 2026
25e21bf
Update run_gdunit4_unit_tests.sh
ikostan Apr 19, 2026
aff443f
Refactor Phase 3: Migrate Core and Manager scripts #526
ikostan Apr 19, 2026
1995f5a
Install GUT before running it and use the configured test directory.
ikostan Apr 19, 2026
f9e5307
Refactor Phase 3: Migrate Core and Manager scripts #526
ikostan Apr 19, 2026
9364109
1. Invalid RUN keyword (Line 54) — Dockerfile syntax in a bash script
ikostan Apr 19, 2026
464db5c
2. -gdir=res://test -ginclude_subdirs=true still present (Line 62)
ikostan Apr 19, 2026
49fa33c
Update test_audio_manager.gd
ikostan Apr 19, 2026
bb19177
Update run_pipeline.sh
ikostan Apr 21, 2026
ea06ea7
install the tool during the Docker build stage so it is "baked in" to…
ikostan Apr 21, 2026
171e27d
Update run_pipeline.sh
ikostan Apr 21, 2026
67535c9
Update run_pipeline.sh
ikostan Apr 21, 2026
41c04bc
Remove or wire PW_TIMEOUT into the pytest command.
ikostan Apr 21, 2026
c8e2cc6
Update Platforms_for_Web_Deployment_Guide.md
ikostan Apr 21, 2026
983955a
Update Platforms_for_Web_Deployment_Guide.md
ikostan Apr 21, 2026
8228fbd
issue (bug_risk): Clarify timeout units to match pytest-timeout expec…
ikostan Apr 21, 2026
0aa098b
suggestion (performance): Avoid downloading and unpacking GUT on ever…
ikostan Apr 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ artifacts/main_menu.png
v8_coverage_*.json
tests/refactor/__pycache__/
report.html
scan_project.py
project_structure.txt
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ source code to users. For closed-source commercial alternatives without
these GPL requirements, a separate license is available upon request.

### Key Terms

- **Open Source**: You can view, modify, and distribute the code freely,
as long as derivatives remain under GPLv3.
- **Commercial Use**: Allowed under GPLv3 (with source code obligations
Expand Down Expand Up @@ -253,18 +254,21 @@ Milestone 12 focused on making the game more navigable and responsive
to user input devices:

### Input Remapping

- Conflict detection dialog when assigning existing bindings
- Per-device last input selection persists between sessions
- Critical control warnings if actions are unbound
- Remap menu accessible from all relevant UI paths

### Menu Navigation

- Keyboard + gamepad (D-Pad) support for all menu flows
- Guaranteed core navigation actions remain bound
- Focus restoration when leaving submenus (Audio → Options → Main)
- Modifier key respect (Ctrl/Shift/Alt/Meta) in remapping UI

### Audio Settings Controls

- Use keyboard/gamepad accept action for sliders and toggles
- Focus highlighting for better visual feedback
- Unified UI interactions without relying on the mouse
Expand All @@ -273,18 +277,18 @@ to user input devices:
synchronization.

### Godot Resource Migration

- Replaced hard-coded globals with a `GameSettingsResource`
- Easier inspector-based editing and persistence
- Safer loading with fallback on corrupted configs

### Known Limitations

* Some complex menu flows may still rely on the mouse until additional
- Some complex menu flows may still rely on the mouse until additional
focus neighbors are defined.
* Modifier-aware remapping requires explicit key+modifier press for
- Modifier-aware remapping requires explicit key+modifier press for
unique bindings.


Track progress via [Milestones](https://github.com/ikostan/SkyLockAssault/milestones).

---
Expand Down
10 changes: 5 additions & 5 deletions files/docs/Development_Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ When adding a new setting:
4. No Manual Saves: Do not call save functions directly from the UI; changing the
resource value is sufficient to trigger a save.

#### The technical documentation for the "Working with Game Settings" section.
#### The technical documentation for the "Working with Game Settings" section

This documentation explicitly defines the signal signature and the specific
files responsible for the **Observer Pattern** architecture.
Expand All @@ -112,10 +112,10 @@ and a centralized observer handles persistence and logging.
When connecting a UI element or a new system to the settings resource,
use the following signature:

* **Signal Name**: `setting_changed`
* **Parameters**:
* `setting_name`: **String** (The name of the property that changed, e.g., "difficulty")
* `new_value`: **Variant** (The newly assigned, clamped value)
- **Signal Name**: `setting_changed`
- **Parameters**:
- `setting_name`: **String** (The name of the property that changed, e.g., "difficulty")
- `new_value`: **Variant** (The newly assigned, clamped value)

#### 2. Core Files Reference

Expand Down
23 changes: 12 additions & 11 deletions files/docs/Platforms_for_Web_Deployment_Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ We're building **SkyLockAssault** — a totally free-to-play browser
game in **Godot v4.5** on **Windows 10 64-bit**. This is our learning
journey into game dev, so we're keeping everything practical,
low-friction, and focused on **automatic deploys** via GitHub Actions

+ CI/CD where possible.

This `.md` file is your living playbook. Update it as you go (e.g. mark
Expand All @@ -19,11 +20,11 @@ new platforms as "Deployed: ✅ Yes").

## Why Web Platforms for a Free F2P Godot Game?

- **Zero cost to publish** (no Steam $100 fee)
- **Instant browser play** (Godot WebGL export = one ZIP)
- **High traffic** for casual games like SkyLockAssault
- **Ad revenue or donations** without forcing monetization
- **GitHub Actions** = push → auto-deploy (your dream workflow)
+ **Zero cost to publish** (no Steam $100 fee)
+ **Instant browser play** (Godot WebGL export = one ZIP)
+ **High traffic** for casual games like SkyLockAssault
+ **Ad revenue or donations** without forcing monetization
+ **GitHub Actions** = push → auto-deploy (your dream workflow)

---

Expand Down Expand Up @@ -75,9 +76,9 @@ but it's maintenance work.

## Automation Strategy

- 100% Auto: itch.io, Poki, Viverse, Game Jolt
- Playwright Auto: iDev.games, GameMonetize (easiest)
- Manual + Occasional: CrazyGames, Y8, GameDistribution, GamePix, Newgrounds,
+ 100% Auto: itch.io, Poki, Viverse, Game Jolt
+ Playwright Auto: iDev.games, GameMonetize (easiest)
+ Manual + Occasional: CrazyGames, Y8, GameDistribution, GamePix, Newgrounds,
SoftGames

---
Expand All @@ -92,12 +93,12 @@ but it's maintenance work.

### Phase 2: Semi-Auto Bonus (Playwright)

- **iDev.games** + **GameMonetize** (easiest forms)
- Update every 2–4 weeks via one shared script
+ **iDev.games** + **GameMonetize** (easiest forms)
+ Update every 2–4 weeks via one shared script

### Phase 3: Manual Once + Occasional Updates

- CrazyGames, Y8, GameDistribution, GamePix, Newgrounds, SoftGames, Game Jolt
+ CrazyGames, Y8, GameDistribution, GamePix, Newgrounds, SoftGames, Game Jolt

**Goal:** Push to `main` → 10+ platforms updated automatically.

Expand Down
4 changes: 2 additions & 2 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ general/default_playback_type.web=0

[autoload]

Globals="*res://scripts/globals.gd"
Settings="*res://scripts/settings.gd"
Globals="*res://scripts/core/globals.gd"
Settings="*res://scripts/core/settings.gd"
AudioConstants="*res://scripts/audio_constants.gd"
AudioManager="*res://scripts/audio_manager.gd"
AudioWebBridge="*res://scripts/audio_web_bridge.gd"
Expand Down
File renamed without changes.
33 changes: 15 additions & 18 deletions run_pipeline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
PROJECT_DIR="/project"
EXPORT_DIR="$PROJECT_DIR/export/web_thread_off"
SERVER_PORT=8080
PW_TIMEOUT=10000 # Default timeout in ms; adjustable
PW_TIMEOUT=10000
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Outdated

# Function to check if a step failed
check_exit() {
Expand All @@ -27,7 +27,9 @@ check_exit "GDScript Lint"

# 2. Markdown Lint
echo "Running Markdown Lint..."
markdownlint-cli2 "**/*.md" --config .markdownlint-cli2.yaml --fix
# --yes: skips the interactive install prompt
# !venv/**: prevents the linter from scanning your virtual environment
npx --yes markdownlint-cli2@0.12.1 "**/*.md" "!venv/**" --config .markdownlint-cli2.yaml --fix
check_exit "Markdown Lint"

# 3. YAML Lint
Expand All @@ -36,8 +38,8 @@ yamllint -c .yamllint.yaml .github/workflows/*.yml
check_exit "YAML Lint"

# 4. Godot Unit Tests (GDUnit4 v6)
echo "Downloading GDUnit4 if needed (already in image, but ensure project addons)..."
cp -r /project/addons/gdUnit4 $PROJECT_DIR/addons/ || true # Copy if not present
echo "Ensuring GDUnit4 addons are present..."
cp -r /project/addons/gdUnit4 $PROJECT_DIR/addons/ || true
Comment thread
ikostan marked this conversation as resolved.
Outdated

echo "Importing Resources..."
godot --headless --path $PROJECT_DIR --import --quit
Expand All @@ -47,42 +49,41 @@ echo "Running GDUnit4 Tests..."
godot --headless --path $PROJECT_DIR -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd --verbose --ignoreHeadlessMode --add res://test
check_exit "GDUnit4 Tests"

# Upload reports (simulate artifact upload by copying to a reports dir)
# 5. GUT Unit Tests
echo "Running GUT Unit Tests..."
godot --headless --verbose --path $PROJECT_DIR -s res://addons/gut/gut_cmdln.gd -gconfig=res://.gutconfig.json -gdir=res://test -ginclude_subdirs=true -gexit
check_exit "GUT Unit Tests"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

mkdir -p $PROJECT_DIR/reports
cp -r reports/** $PROJECT_DIR/reports || true

# 5. Browser Functional Tests
# 6. Browser Functional Tests
echo "Exporting Godot Project to Web..."
mkdir -p $EXPORT_DIR

# Simulate firebelley/godot-export action: Run Godot export to HTML5
godot --headless --path $PROJECT_DIR --export-release "Web_thread_off" $EXPORT_DIR/index.html
check_exit "Godot Web Export"

# Start web server in background
python3 -m http.server $SERVER_PORT --directory $EXPORT_DIR &
SERVER_PID=$!

# Wait for server to be ready
for i in {1..20}; do
if curl -f http://localhost:$SERVER_PORT/index.html >/dev/null 2>&1; then
echo "Web server ready"
break
fi
sleep 1
done

if [ $i -eq 20 ]; then
Comment thread
ikostan marked this conversation as resolved.
Outdated
echo "Web server failed to start"
kill $SERVER_PID
exit 1
fi

# Run Playwright tests
echo "Running Playwright Browser Tests..."
pytest tests/ --ignore=tests/refactor -v --junitxml=$PROJECT_DIR/report.xml
check_exit "Playwright Tests"

# Generate test report summary
if [ -f $PROJECT_DIR/report.xml ]; then
total=$(xmllint --xpath 'count(//testcase)' $PROJECT_DIR/report.xml)
failures=$(xmllint --xpath 'count(//testcase/failure)' $PROJECT_DIR/report.xml)
Expand All @@ -95,17 +96,13 @@ if [ -f $PROJECT_DIR/report.xml ]; then
echo "- Failed: $failures"
echo "- Errors: $errors"
echo "- Skipped: $skipped"
else
echo "No report.xml found—tests may not have run."
fi

# Cleanup: Stop server
kill $SERVER_PID

# Simulate artifact uploads (copy to host via mounted volume)
mkdir -p $PROJECT_DIR/artifacts
cp $PROJECT_DIR/report.xml $PROJECT_DIR/artifacts/ || true
cp main_menu.png $PROJECT_DIR/artifacts/ || true # If screenshot exists
cp main_menu.png $PROJECT_DIR/artifacts/ || true
cp -r $PROJECT_DIR/reports $PROJECT_DIR/artifacts/gdunit-reports || true

echo "Pipeline completed successfully!"
echo "Pipeline completed successfully!"
2 changes: 1 addition & 1 deletion scenes/main_scene.tscn
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[gd_scene load_steps=83 format=3 uid="uid://nnnc0qhx07i8"]

[ext_resource type="Script" uid="uid://ctm7qg12s2swt" path="res://scripts/main_scene.gd" id="1_7ykc4"]
[ext_resource type="Script" uid="uid://ctm7qg12s2swt" path="res://scripts/core/main_scene.gd" id="1_7ykc4"]
[ext_resource type="PackedScene" uid="uid://cb4n4cqkuddqg" path="res://scenes/pause_menu.tscn" id="1_w2twt"]
[ext_resource type="Texture2D" uid="uid://ce63ga8f5mua7" path="res://files/trees/tree_01.png" id="2_fm3ay"]
[ext_resource type="FontFile" uid="uid://borwvgqdgawbj" path="res://files/fonts/EMPIREST.TTF" id="2_pu3yx"]
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion test/gdunit4/test_globals.gd
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var test_path: String = "user://test_globals.cfg" # Temp for isolation

func before_test() -> void:
# Instantiate the script
globals = auto_free(load("res://scripts/globals.gd").new())
globals = auto_free(load("res://scripts/core/globals.gd").new())

# FIX: Manually initialize the settings resource
# because _ready() hasn't run yet.
Expand Down
Loading