87 Commits

Author SHA1 Message Date
richard 91d88cd5c7 Bump version to 0.5.0
CI / Decide whether to run (push) Has been cancelled
CI / Lint & headless tests (push) Has been cancelled
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MXBNaEBmrYDSMcv4NgUWtV
2026-09-10 16:44:04 +03:00
richard 6dff45c659 Add thank-you ending screen and a run timer
CI / Decide whether to run (push) Has been cancelled
CI / Lint & headless tests (push) Has been cancelled
Defeating the bear (the run's final boss) now plays a dedicated
"Thank You For Playing" clip on the completion screen instead of the
generic bull-win video, with the run's finish time shown in place of
the usual "Bull Won!" title.

A run clock also starts when the player enters the arena (the run's
first fight), shown top-left on desktop only, and freezes the instant
the bear falls. Re-entering the arena after finishing a run restarts
the clock instead of leaving it stuck on the previous run's time.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MXBNaEBmrYDSMcv4NgUWtV
2026-09-10 16:28:57 +03:00
siim 2fd41f4f69 bull follow light
CI / Decide whether to run (push) Has been cancelled
CI / Lint & headless tests (push) Has been cancelled
2026-09-08 19:15:14 +03:00
richard a147527e91 Remove dead code: the map system and editor cruft
CI / Decide whether to run (push) Has been cancelled
CI / Lint & headless tests (push) Has been cancelled
Delete the unused Slay-the-Spire map screen (superseded by the lobby hub),
leftover editor autosave *.tmp scenes, and a stray reference-link file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CCyaJPTHCH9EDthpf4A5Sj
2026-09-08 14:56:22 +03:00
richard 09d4a60f43 Reorganize into role-based folders and consolidate art
Move every script and scene into role-based directories (actors/, systems/, ui/,
levels/, props/) and all raw art under art/ (grouped by role, snake_case,
Extract-Textures GLBs), dropping Blender version-suffix noise. Filenames are
snake_case (PascalCase reserved for class_name) to avoid case-insensitive
filesystem aliasing on the web/macOS targets. Routes the bull's hits through the
typed DamageEvent pipeline and wires the bull's abilities to the Fx library.
Updates CLAUDE.md's folder-layout overview to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CCyaJPTHCH9EDthpf4A5Sj
2026-09-08 14:56:22 +03:00
richard c0a022fed4 Add scene-authored FX library and bull ability effects
An Fx autoload + one_shot_effect base so every effect is an inspector-editable
.tscn (the systems/fx/ authoring dir): blood/slam/spark/flash primitives and the
bull's kick/dash/slam/roll + movement effects (bull_*.tscn), fired via
Fx.spawn() / Fx.attach(). Plus a preview gallery + smoke test, and
bull_impact_fx.gd for the coded, non-particle slam rings + kick flash-pop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CCyaJPTHCH9EDthpf4A5Sj
2026-09-08 14:56:01 +03:00
richard 9458085abb Add typed DamageEvent hit pipeline
A typed DamageEvent contract (systems/combat/damage_event.gd) as a single
entry point for every attacker, plus a characterization test locking the bull's
damage reception. Attacker/receiver wiring rides along with the moved actor
scripts in the reorg commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CCyaJPTHCH9EDthpf4A5Sj
2026-09-08 14:55:46 +03:00
richard 565c132848 Add CI pipeline and reusable test harness
A Gitea Actions workflow (.gitea/workflows/ci.yml) running the headless test
suite on push, plus shared test scaffolding: seeded-RNG / approx / tally helpers
(test_helpers.gd), a harness self-test, and a resolution + pseudo-locale
UI-layout robustness guard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CCyaJPTHCH9EDthpf4A5Sj
2026-09-08 14:55:38 +03:00
richard 400ae24f92 Remove the persistent blood-decal system
Strip only the floor/wall blood-splat decals added in 981ebf1, keeping the
older death-spray, spear-wound spurt, and "Blood & Gore" toggle:

- Delete blood_decals.gd + shader, the Gore autoload (gore.gd), and
  tests/blood_decals_test.gd
- Drop the Gore autoload and the Blood DP section
- Remove all Gore.splat() call sites (matador.gd, bear.gd, player.gd);
  the _blood_burst spray and _spawn_blood spurt stay
- game_shell no longer spawns a per-level decal pool
- Update level_switch test + run_tests.sh accordingly

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmG3mQGVXZUPDVapmdbWZ1
2026-09-04 22:41:00 +03:00
richard 79ea5bb2be Bump version to 0.4.0
The in-game version banner (GameVersion.full) reads config/version from
project.godot; it had lagged at 0.2.0 behind the 0.3.0 tag.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EznnY8rH2dXhtono1kwsXg
2026-09-04 14:19:19 +03:00
richard 981ebf1910 Add blood decals, gore, mobile HUD, web start gate + touch/perf tests
Remove tools/fstest.html scratch page used to probe browser
fullscreen/orientation APIs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EznnY8rH2dXhtono1kwsXg
2026-09-04 14:07:57 +03:00
siim 01d6ecf475 go to bear level fix and vibration of controller when gate is opening 2026-09-03 18:20:19 +03:00
siim 931ddf0eeb can turn "gamepad_vibration" on and off in debug mode 2026-09-03 18:04:58 +03:00
siim 50073b2574 controller vibrate when taking damage 2026-09-03 17:53:44 +03:00
siim 07f8a71f2c torches light animation 2026-09-03 07:53:55 +03:00
richard 34dc5b026e Lobby barrel-smash reward + roll/slam barrel destruction
Bull's boulder roll now homes on and ploughs through lobby barrels, and
the slam shockwave bursts them within its radius. HUD tallies barrels on
load and fires a confetti "WOooOoW!" + two gold bonus HP pips when the
last one breaks; gates open from run state as fights are cleared.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-03 01:38:57 +03:00
richard 5c1e881a53 Combat overhaul: charge/gore, bear ram, matador taunt reactions
Bull charge damage:
- Tunnel-proof swept detection (prev→now segment) for matador gore and bear
  ram, so a 66 m/s dash no longer skips clean over the thin HitArea.
- Horns-first cone (bull_gore_arc): running into an enemy only wounds it when
  charging roughly at it, not a sideways brush.
- Dash is a committed lunge: bypasses the horns cone AND the survival roll, so a
  dash connect is a guaranteed kill. Cruise charges keep a speed-scaled roll
  (mat_charge_pierce). Roll ability defers to its own pop (is_rolling guard).

Bear:
- Horns-first swept ram detection (edge-triggered: one charge = one wound);
  a tunnelling or point-blank charge now lands where body_entered wouldn't.
- Overhead smash lane extends faster (0.1s) and further (20 m).
- Leap slam launches the bull from anywhere in the circle (ring_frac 0).
- Removed stray-quote syntax errors that broke the script.

Matador:
- Collider-driven stab (BladeHitbox) with recovery beat + taunt-after-hit so it
  stops machine-gunning the bull.
- A taunting matador answers a charge: spear from range, sword up close.

Spear projectile masks the BULL layer so throws connect.

Tests: matador_charge/stab/spear/taunt_react, bear_ram/hitbox/fx (+ unified
_fake_bull stand-in). Trimmed verbose comments.

Note: bear claw-emitter/death work is still WIP (3 bear_boss_test failures).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-03 01:01:42 +03:00
siim 4efc6763f0 lobby little tweak 2026-09-01 21:34:02 +03:00
siim 76d4fee33c Lobby level gates trigger areas 2026-09-01 21:22:16 +03:00
siim 271be0b26b + torches 2026-09-01 08:58:56 +03:00
siim 98c6f1285a underground_lobby 2026-08-31 21:52:13 +03:00
siim 4d66df8c7e bear long range slam. and not rotating while attacking animore. but dash and movement damage not working now 2026-08-29 09:30:03 +03:00
siim 41f18cb5d6 bear fx v2 2026-08-28 21:43:59 +03:00
siim 6b6a926715 bear_fx 2026-08-28 20:23:13 +03:00
siim dae7ec06da barrel materials 2026-08-28 19:43:09 +03:00
siim 1eb06876e9 breakable barrels 2026-08-28 19:02:19 +03:00
richard 1021a07b04 Put dead matadors on a corpse collision layer
A killed matador's ragdoll shared the WORLD layer with the bull, so the
bull collided with the bodies and spazzed out on them. Give corpses a
dedicated CORPSE layer masked to itself, and tag the ground/walls with
CORPSE too (at level load, so it also reaches colliders baked into the
instanced GLB arenas). The corpse still rests on the arena, but the bull
— which only masks WORLD — passes straight through the bodies.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-27 23:27:10 +03:00
richard c365f76d80 Merge remote-tracking branch 'origin/main' 2026-08-27 21:34:23 +03:00
richard 32ac46f840 lobby cam 2026-08-27 21:34:18 +03:00
siim bd10d1789b bear max hp 30 2026-08-27 21:30:48 +03:00
siim 170d8ff3f1 siim timmimised väiksed 2026-08-27 21:15:36 +03:00
siim 550bf2c5ad adjustable wave size with debug parameter "mat_wave_size" 2026-08-27 20:36:00 +03:00
siim 02f3e283de landing. don't bounce! 2026-08-27 08:30:03 +03:00
siim 9123574947 crowd billbord placement + mat sword run fix 2026-08-26 22:32:30 +03:00
siim aadf59d2d0 lobby collisions 2026-08-26 21:09:41 +03:00
richard d57c3dc2a2 Merge remote-tracking branch 'origin/main' 2026-08-26 20:38:14 +03:00
richard 09ae6bfbf4 lobby level 2026-08-26 20:38:07 +03:00
richard 40c1b8e680 debug param save works, bull/bear hitbox 2026-08-26 20:37:50 +03:00
siim a1c77fed5e Update debug_params.gd 2026-08-26 20:02:23 +03:00
siim 1a8af92d88 matador attack fix 2026-08-26 19:53:43 +03:00
siim 8166a6c18e Merge branch 'main' of https://git.richard.work/siim/Bullosseum 2026-08-26 19:41:35 +03:00
siim 46d6dda325 capsule 2026-08-26 19:41:23 +03:00
richard fc9348551d fix sword holster 2026-08-26 19:18:52 +03:00
richard c4a19c7443 crowd markers, unsheathed sword correct 2026-08-26 19:13:39 +03:00
siim 95c4c0ddf9 BEAR ARENA UPDATE 2026-08-26 19:12:27 +03:00
siim 6a4f104655 bear arena model updeit 2026-08-26 18:30:09 +03:00
siim d4b67888d7 controller zoom with right stick 2026-08-26 18:12:12 +03:00
siim b177e0aee3 matadors dont come inside the player anymore with sword attack. also got rid of matador.gd dublicate.. that i made for testing animation 2026-08-26 08:39:40 +03:00
siim 2a6f4c0f7b bear_FX 2026-08-25 21:58:43 +03:00
siim 32d0c58f5c bear_ Call method track testing with spears 2026-08-25 08:49:44 +03:00
siim 251002ea7c bull and bear flashing red when take damage 2026-08-25 08:04:39 +03:00
siim 986496097f arena cleanup 2026-08-24 18:45:03 +03:00
siim d976deeb6a arena cleanup+tex modification 2026-08-24 18:41:34 +03:00
siim d632670092 +death animation bear 2026-08-24 08:36:48 +03:00
siim e1899e49f4 level lobby 2026-08-23 23:40:28 +03:00
siim 6f5f9e6bba ps1 filter tuun 2026-08-23 22:26:58 +03:00
siim 91cd027a98 adj 2026-08-23 22:05:57 +03:00
siim ef2fb24969 cooldowns increase 2026-08-23 21:39:19 +03:00
siim 4c75776c70 debug_param_cooldown adjusts 2026-08-23 21:28:19 +03:00
siim 7688084b7e spear update 2026-08-23 21:15:25 +03:00
richard ccc92f201f mobile support tweaks 2026-08-23 20:32:52 +03:00
richard 008650a87e Merge remote-tracking branch 'origin/main' 2026-08-23 17:34:05 +03:00
richard b9e3147519 Bear, level selector (to be removed), new matador spawn, new bear level, saving config updates source files 2026-08-23 17:33:47 +03:00
richard cdba320cbc bear 2026-08-23 17:33:32 +03:00
richard ee7b1617c1 Bear, level selector (to be removed), new matador spawn, new bear level, saving config updates source files 2026-08-23 17:33:15 +03:00
richard d749485126 Map screen version 2026-08-23 13:16:04 +03:00
richard 45427b7070 Merge remote-tracking branch 'origin/main' 2026-08-23 12:37:35 +03:00
richard d514435dd8 touch controls and hud 2026-08-23 12:37:30 +03:00
siim 3eb9fa50f3 +bear boss 2026-08-23 11:18:45 +03:00
siim aee900c009 bear boss, aga broken 2026-08-21 18:23:30 +03:00
siim 4cf714f516 Update spear.glb 2026-08-17 23:49:29 +03:00
siim b78736a1f4 icon update 2026-08-10 04:43:48 +03:00
siim 212263c858 credits tuun 2026-08-10 03:53:17 +03:00
siim 8c4eeb0861 cooldowns? 2026-08-10 03:30:53 +03:00
siim 95def2d527 loading text + fullscreen default 2026-08-10 01:04:57 +03:00
siim 9a43a9ff8b icon 2026-08-09 23:58:01 +03:00
siim 7238cbf49e death anim speed .8 2026-08-09 23:19:23 +03:00
siim 44c667f097 collision scale 2026-08-09 23:15:43 +03:00
siim 3cd347d420 walk anim, death anim ja loading screen 2026-08-09 23:05:55 +03:00
richard 6414b2e7cc uids 2026-08-09 19:40:39 +03:00
richard 56593c58cf Release 0.2.0: device-aware controls, spear, settings, shaders
Show touch controls only on touch platforms and keyboard hints only on
desktop, via a shared Controls.use_touch_ui() gate (is_touchscreen_available
is unreliable with emulate_touch_from_mouse). Bumps version to 0.2.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-09 19:39:37 +03:00
richard ce6f3d7075 Deployment script update 2026-08-09 15:26:01 +03:00
siim a74182255b light tim 2026-08-08 11:47:36 +03:00
siim ebf5046461 credits 2026-07-30 20:21:10 +03:00
richard 271de1b045 ps1 filter variables, crowds 2026-07-30 15:12:22 +03:00
richard 3defc9da95 UI theme 2026-07-30 13:52:50 +03:00
richard ff75dacfb6 New screens, new hud, new intro menu, some UI element changes 2026-07-30 13:52:39 +03:00
407 changed files with 14658 additions and 9187 deletions
+1 -1
View File
@@ -2,4 +2,4 @@ disable:
- class-definitions-order - class-definitions-order
- no-else-return - no-else-return
max-line-length: 120 max-line-length: 120
max-file-lines: 1200 max-file-lines: 3000
+139
View File
@@ -0,0 +1,139 @@
name: CI
# Gitea Actions is GitHub-Actions-compatible: drop this in .gitea/workflows/, enable Actions on the
# repo ([actions] ENABLED=true in app.ini, Gitea >= 1.19) and register an act_runner — it then runs
# on every push / PR. Godot and gdtoolkit are installed with plain shell steps (not the chickensoft
# setup-godot action), because a self-hosted runner usually can't reach the GitHub action registry
# (unless DEFAULT_ACTIONS_URL is set to proxy github.com). Only actions/checkout and upload-artifact
# remain as external actions — both ship with Gitea's default proxy; if yours is offline, mirror them
# into your instance.
#
# It also runs once a day (schedule) as a safety net over main's tip. The `guard` job skips that daily
# run when the commit already passed — so an idle main isn't re-tested, but a commit whose push-time
# run was missed/skipped still gets verified. schedule needs Gitea >= 1.21; workflow_dispatch (the
# manual "Run workflow" button) needs >= 1.23; from 1.23 the cron is evaluated in UTC.
on:
push:
pull_request:
workflow_dispatch:
schedule:
- cron: "0 4 * * *" # 04:00 UTC daily
# statuses:write lets the test job stamp a `ci/headless` commit status the guard reads back.
permissions:
contents: read
statuses: write
env:
# The Godot build the team runs (godot --version -> 4.7.beta.custom_build.417cd33bf). Pin this to a
# PUBLISHED build from https://github.com/godotengine/godot-builds/releases. If you run a custom
# build with no public binary, host the linux headless zip where the runner can reach it and set
# GODOT_URL to that (it overrides the constructed URL below).
GODOT_VERSION: "4.7-beta1"
GODOT_URL: ""
jobs:
# On push/PR this passes straight through. On the daily schedule it asks the API whether main's tip
# already carries a successful `ci/headless` status (stamped by an earlier run) and, if so, tells the
# test job to skip — that's the "don't re-test a commit that already ran" rule.
guard:
name: Decide whether to run
runs-on: ubuntu-latest
outputs:
run: ${{ steps.decide.outputs.run }}
steps:
- name: Check for an existing pass on this commit
id: decide
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -u
if [ "${{ github.event_name }}" != "schedule" ]; then
echo "event=${{ github.event_name }} -> run"
echo "run=true" >> "$GITHUB_OUTPUT"
exit 0
fi
api="${{ github.api_url }}"; [ -n "$api" ] || api="${{ github.server_url }}/api/v1"
curl -sfL -H "Authorization: token ${GITEA_TOKEN}" \
"$api/repos/${{ github.repository }}/commits/${{ github.sha }}/statuses?limit=100" \
-o /tmp/statuses.json || echo '[]' > /tmp/statuses.json
python3 - <<'PY'
import json, os
try:
data = json.load(open("/tmp/statuses.json"))
except Exception:
data = []
items = data.get("statuses", data) if isinstance(data, dict) else data
done = any(
s.get("context") == "ci/headless" and (s.get("state") or s.get("status")) == "success"
for s in (items or [])
)
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write("run=%s\n" % ("false" if done else "true"))
print("commit already passed ci/headless -> skip" if done else "no prior pass -> run")
PY
test:
name: Lint & headless tests
runs-on: ubuntu-latest # must match a label your act_runner registered with
needs: guard
if: ${{ needs.guard.outputs.run == 'true' }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Godot ${{ env.GODOT_VERSION }}
run: |
set -eux
url="${GODOT_URL:-https://github.com/godotengine/godot-builds/releases/download/${GODOT_VERSION}/Godot_v${GODOT_VERSION}_linux.x86_64.zip}"
curl -fL "$url" -o /tmp/godot.zip
unzip -o /tmp/godot.zip -d /tmp/godot
install -m 755 /tmp/godot/Godot_v*_linux.x86_64 /usr/local/bin/godot
godot --version
- name: Install gdlint (gdtoolkit)
# A venv sidesteps PEP-668 "externally managed" pip on recent runner images; putting its bin on
# GITHUB_PATH lets run_tests.sh call bare `gdlint` in later steps.
run: |
set -eux
python3 -m venv /tmp/venv
/tmp/venv/bin/pip install "gdtoolkit==4.*"
echo "/tmp/venv/bin" >> "$GITHUB_PATH"
# A cold .godot cache (CI always starts cold) needs two import passes: the first imports base
# assets, the second resolves scenes that depend on them (the .fbx/.glb -> .scn imports). One pass
# leaves those unresolved and the headless tests fail to load them. Warnings exit non-zero.
- name: Import resources
run: |
godot --headless --import || true
godot --headless --import || true
- name: gdlint
run: gdlint actors systems ui props levels tests
- name: Headless tests
env:
GODOT: godot
run: bash run_tests.sh --no-gameplay
# Stamp the commit so the daily guard recognizes it as already tested. Best-effort: a fork PR whose
# token can't write statuses just skips this (the build still passes).
- name: Mark commit as tested
if: success()
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
api="${{ github.api_url }}"; [ -n "$api" ] || api="${{ github.server_url }}/api/v1"
curl -sfL -X POST -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" \
"$api/repos/${{ github.repository }}/statuses/${{ github.sha }}" \
-d '{"context":"ci/headless","state":"success","description":"headless suite green"}' \
>/dev/null || echo "could not post commit status (token lacks statuses:write?)"
- name: Upload test output on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-output
path: tests/output/
if-no-files-found: ignore
+6 -2
View File
@@ -2,13 +2,17 @@
.godot/ .godot/
/android/ /android/
# Godot editor autosave scratch files (e.g. Bear.tscn12015901897.tmp)
*.tmp
# JetBrains IDE — contains absolute paths (Godot binary, SDK dirs), varies per user # JetBrains IDE — contains absolute paths (Godot binary, SDK dirs), varies per user
.idea/ .idea/
# Blender render previews (generated by render_anim_preview.py) # Blender render previews (generated by render_anim_preview.py)
Blender/preview/ art/blender/preview/
Blender/*.blend1 # Blender auto-save backups (.blend1, .blend2, … — Blender rewrites these on every save)
art/blender/*.blend[0-9]
# Test output (generated screenshots, frame strips) # Test output (generated screenshots, frame strips)
tests/output/ tests/output/
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bu3eevt6f31vy"
path="res://.godot/imported/intro_seq_0001.png-d13407f069897f5b8302350ea06caad2.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0001.png"
dest_files=["res://.godot/imported/intro_seq_0001.png-d13407f069897f5b8302350ea06caad2.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cv0386ujbone6"
path="res://.godot/imported/intro_seq_0002.png-7d720fee04fce498d05e156084b3ef90.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0002.png"
dest_files=["res://.godot/imported/intro_seq_0002.png-7d720fee04fce498d05e156084b3ef90.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bpagtmd32idd0"
path="res://.godot/imported/intro_seq_0003.png-ae551e25a09b19cb262685550214d751.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0003.png"
dest_files=["res://.godot/imported/intro_seq_0003.png-ae551e25a09b19cb262685550214d751.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b6rdw1pvnq4cj"
path="res://.godot/imported/intro_seq_0004.png-9977a1ecdd9ddac47ca83665f2c41e57.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0004.png"
dest_files=["res://.godot/imported/intro_seq_0004.png-9977a1ecdd9ddac47ca83665f2c41e57.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bwhtngfrq8ao7"
path="res://.godot/imported/intro_seq_0005.png-492c659aed88c33763898b51cdecde09.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0005.png"
dest_files=["res://.godot/imported/intro_seq_0005.png-492c659aed88c33763898b51cdecde09.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d4c6etc2k8o5b"
path="res://.godot/imported/intro_seq_0006.png-754b5919bb8ea2d96bfce5d29bfa03af.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0006.png"
dest_files=["res://.godot/imported/intro_seq_0006.png-754b5919bb8ea2d96bfce5d29bfa03af.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://buw18qc3wanyf"
path="res://.godot/imported/intro_seq_0007.png-5924916944ea882df411d192e1106616.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0007.png"
dest_files=["res://.godot/imported/intro_seq_0007.png-5924916944ea882df411d192e1106616.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://rqsffoxigmul"
path="res://.godot/imported/intro_seq_0008.png-cc0a32cbed495eedfc84f56240d77d70.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0008.png"
dest_files=["res://.godot/imported/intro_seq_0008.png-cc0a32cbed495eedfc84f56240d77d70.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dgqqdvsv087dq"
path="res://.godot/imported/intro_seq_0009.png-9477102b81fd9f557f19c0091825e489.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0009.png"
dest_files=["res://.godot/imported/intro_seq_0009.png-9477102b81fd9f557f19c0091825e489.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dx1eu7pdngt2b"
path="res://.godot/imported/intro_seq_0010.png-d159843ba1107baa767e0f568ebe5164.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0010.png"
dest_files=["res://.godot/imported/intro_seq_0010.png-d159843ba1107baa767e0f568ebe5164.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://hrpawt4pm8vw"
path="res://.godot/imported/intro_seq_0011.png-da361e3c03d7c9e37aafa9a94fce40aa.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0011.png"
dest_files=["res://.godot/imported/intro_seq_0011.png-da361e3c03d7c9e37aafa9a94fce40aa.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cwxwxuq1qvq1s"
path="res://.godot/imported/intro_seq_0012.png-994091f05e3fffd9558b9c023b1e8959.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0012.png"
dest_files=["res://.godot/imported/intro_seq_0012.png-994091f05e3fffd9558b9c023b1e8959.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dcatel76pvhaf"
path="res://.godot/imported/intro_seq_0013.png-4f4f9ef778d5ed3a8f18e94c837f6258.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0013.png"
dest_files=["res://.godot/imported/intro_seq_0013.png-4f4f9ef778d5ed3a8f18e94c837f6258.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://x8eewdg65qgr"
path="res://.godot/imported/intro_seq_0014.png-f8346c8267324ffe151c42113f79700d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0014.png"
dest_files=["res://.godot/imported/intro_seq_0014.png-f8346c8267324ffe151c42113f79700d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c0pwx26aill3t"
path="res://.godot/imported/intro_seq_0016.png-ad89023f08798b251f84156b0d00d183.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0016.png"
dest_files=["res://.godot/imported/intro_seq_0016.png-ad89023f08798b251f84156b0d00d183.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b8mbxrarmnu70"
path="res://.godot/imported/intro_seq_0017.png-5bba2681811780a47d9cb4b03c476a91.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0017.png"
dest_files=["res://.godot/imported/intro_seq_0017.png-5bba2681811780a47d9cb4b03c476a91.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bmgpk0egfy66u"
path="res://.godot/imported/intro_seq_0018.png-b04a1bd60a6eb8446f8a91aca3abae15.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0018.png"
dest_files=["res://.godot/imported/intro_seq_0018.png-b04a1bd60a6eb8446f8a91aca3abae15.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dt41tdv4ameam"
path="res://.godot/imported/intro_seq_0019.png-e64a687201179a236907ea9ab3080cbd.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0019.png"
dest_files=["res://.godot/imported/intro_seq_0019.png-e64a687201179a236907ea9ab3080cbd.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dqdytcgsacjxc"
path="res://.godot/imported/intro_seq_0020.png-94a72e7452125cc098d4df663548b117.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0020.png"
dest_files=["res://.godot/imported/intro_seq_0020.png-94a72e7452125cc098d4df663548b117.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d3u6yoiw4anm0"
path="res://.godot/imported/intro_seq_0021.png-e41ed967859539364420056b92742e4b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0021.png"
dest_files=["res://.godot/imported/intro_seq_0021.png-e41ed967859539364420056b92742e4b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cl2ni7jmhpdj6"
path="res://.godot/imported/intro_seq_0022.png-147d9f81538df8bcb3842e1b12917298.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0022.png"
dest_files=["res://.godot/imported/intro_seq_0022.png-147d9f81538df8bcb3842e1b12917298.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bx77btneo2n5o"
path="res://.godot/imported/intro_seq_0023.png-d79bc8b0b5339953b97138b03091c590.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0023.png"
dest_files=["res://.godot/imported/intro_seq_0023.png-d79bc8b0b5339953b97138b03091c590.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b5uwi1h64dqek"
path="res://.godot/imported/intro_seq_0024.png-4ae491dbd3e8b33a50bf2e9fc7c44e36.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0024.png"
dest_files=["res://.godot/imported/intro_seq_0024.png-4ae491dbd3e8b33a50bf2e9fc7c44e36.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://uv6nf2cgqjyy"
path="res://.godot/imported/intro_seq_0025.png-99f570fe058fb7903ce72e35a3c938f8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0025.png"
dest_files=["res://.godot/imported/intro_seq_0025.png-99f570fe058fb7903ce72e35a3c938f8.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://fh7m5y5j336x"
path="res://.godot/imported/intro_seq_0026.png-5bb48d75704d345d874831e5f6a2b446.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0026.png"
dest_files=["res://.godot/imported/intro_seq_0026.png-5bb48d75704d345d874831e5f6a2b446.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dfmr5syqlie06"
path="res://.godot/imported/intro_seq_0027.png-436ad22542c38673365c1700684b8278.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0027.png"
dest_files=["res://.godot/imported/intro_seq_0027.png-436ad22542c38673365c1700684b8278.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bx71y7cf6lsse"
path="res://.godot/imported/intro_seq_0028.png-250f5531a5db7406a3d95fa6f5a4b753.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0028.png"
dest_files=["res://.godot/imported/intro_seq_0028.png-250f5531a5db7406a3d95fa6f5a4b753.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://r8vet7ghanp1"
path="res://.godot/imported/intro_seq_0029.png-deaafc16edf139dfe84ed9c86c1fc7ef.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0029.png"
dest_files=["res://.godot/imported/intro_seq_0029.png-deaafc16edf139dfe84ed9c86c1fc7ef.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://4b8irulowbbv"
path="res://.godot/imported/intro_seq_0030.png-5860e05ac89ecb6e2036d6a84ee44e4e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0030.png"
dest_files=["res://.godot/imported/intro_seq_0030.png-5860e05ac89ecb6e2036d6a84ee44e4e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cvf5isldc65n4"
path="res://.godot/imported/intro_seq_0031.png-927f6fff06201f79eaf5ced54934d825.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0031.png"
dest_files=["res://.godot/imported/intro_seq_0031.png-927f6fff06201f79eaf5ced54934d825.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d4j88tyqprs2d"
path="res://.godot/imported/intro_seq_0032.png-fb16b2b570af97548a9a76fe074d0679.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0032.png"
dest_files=["res://.godot/imported/intro_seq_0032.png-fb16b2b570af97548a9a76fe074d0679.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b1k4bojvgeksu"
path="res://.godot/imported/intro_seq_0033.png-46cbba009bcd114946dc61b4952e390f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0033.png"
dest_files=["res://.godot/imported/intro_seq_0033.png-46cbba009bcd114946dc61b4952e390f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 MiB

@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://7cyyof1476yl"
path="res://.godot/imported/intro_seq_0034.png-e9bc2dbf0d75b6ff302c4cc0bfef8e97.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Animations/Intro_sequence/intro_seq_0034.png"
dest_files=["res://.godot/imported/intro_seq_0034.png-e9bc2dbf0d75b6ff302c4cc0bfef8e97.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
-7
View File
@@ -1,7 +0,0 @@
extends Node3D
func _ready() -> void:
var anim := get_node_or_null(^"AnimationPlayer") as AnimationPlayer
if anim:
anim.play(&"Juubeldab")
-1
View File
@@ -1 +0,0 @@
uid://wj6tgh8nb0ka
-5
View File
@@ -1,5 +0,0 @@
extends Node3D
func _ready() -> void:
$AnimationPlayer.play("ArmatureAction")
-1
View File
@@ -1 +0,0 @@
uid://gt3kfchac3m3
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
-5
View File
@@ -1,5 +0,0 @@
extends Node3D
func _ready() -> void:
$AnimationPlayer.play("Taunt")
-1
View File
@@ -1 +0,0 @@
uid://bn3xwnlktwdlf
-38
View File
@@ -1,38 +0,0 @@
[gd_scene format=3 uid="uid://bl6jlbq1dpkc"]
[ext_resource type="PackedScene" uid="uid://eu2lqjhowj4t" path="res://Assets/Matador.glb" id="1_m7x6l"]
[ext_resource type="Script" uid="uid://dpoq87w5pvqa" path="res://matador_2.gd" id="2_mftd2"]
[node name="matador2" unique_id=1179710042 instance=ExtResource("1_m7x6l")]
script = ExtResource("2_mftd2")
[node name="Skeleton3D" parent="Armature" parent_id_path=PackedInt32Array(1269629432) index="0" unique_id=978366810]
bones/0/position = Vector3(0.056660548, 0.6424767, -0.0167365)
bones/0/rotation = Quaternion(0.080643006, 0, 0, 0.996743)
bones/1/rotation = Quaternion(0.083861314, 0, 0, 0.9964774)
bones/3/rotation = Quaternion(0.04833339, 0.5302496, -0.71466804, 0.4535955)
bones/4/rotation = Quaternion(0.031473875, -0.17018215, -0.15981929, 0.97185665)
bones/5/rotation = Quaternion(0.6747468, -0.021427644, -0.06245957, 0.7350895)
bones/6/rotation = Quaternion(3.1828083e-08, -9.5969504e-08, -0.0587008, 0.99827564)
bones/7/rotation = Quaternion(0.1907551, 0.20328633, 0.7258648, 0.6288143)
bones/8/rotation = Quaternion(0.16639966, -0.05474137, 0.010937729, 0.984477)
bones/9/rotation = Quaternion(0.5914298, 0.005839911, -0.041949864, 0.8052435)
bones/10/rotation = Quaternion(2.3105285e-08, 1.0152064e-07, 0.05870079, 0.99827564)
bones/11/rotation = Quaternion(0.39202613, 0.47060952, 0.5799399, 0.53713316)
bones/12/rotation = Quaternion(0.62021786, 0.40894383, 0.44191495, 0.5027981)
bones/13/rotation = Quaternion(-0.11584477, 0.0021730124, 0.6343679, 0.7642989)
bones/14/rotation = Quaternion(0.1454883, 0.14013468, -0.7254941, 0.65791625)
bones/15/rotation = Quaternion(0.71668345, 0.065085255, -0.6923973, -0.05210323)
bones/16/rotation = Quaternion(-0.10161893, -0.0019664483, -0.65947086, 0.7448275)
bones/17/rotation = Quaternion(0.06964938, -0.042099692, 0.74388325, 0.6633358)
bones/18/rotation = Quaternion(0.5305965, -0.28927496, 0.76720744, -0.21489602)
bones/19/position = Vector3(0.16341288, 0.31487355, 0.3966543)
bones/20/position = Vector3(0.22012731, 0.38421977, 0.95168185)
bones/21/position = Vector3(-0.09492579, 0.40446192, -0.46390092)
bones/21/rotation = Quaternion(0.7216726, 0.064735115, -0.6891729, 0.0062273443)
bones/22/position = Vector3(-0.22012731, 0.38421977, 0.95168185)
bones/23/position = Vector3(-0.0382514, 1.7423625, 0.0026792884)
bones/23/rotation = Quaternion(0.8626007, 0.0068245474, -0.099159576, -0.49602506)
bones/23/scale = Vector3(0.6647317, 1.001677, 1.0066445)
bones/24/rotation = Quaternion(-0.007878712, 8.3020435e-09, -0.0023950166, 0.9999661)
bones/25/rotation = Quaternion(5.5870206e-09, 5.5879354e-09, -2.0518176e-09, 1)
-12
View File
@@ -1,12 +0,0 @@
extends Node3D
@onready var animation_player: AnimationPlayer = $AnimationPlayer
func _ready():
animation_player.play("Taunt")
animation_player.animation_finished.connect(_on_animation_finished)
func _on_animation_finished(anim_name):
if anim_name == "Taunt":
animation_player.play("Taunt")
-1
View File
@@ -1 +0,0 @@
uid://dycnoiadljbb1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
uid://ymaeifakqovf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+74 -15
View File
@@ -10,21 +10,64 @@ I am a **Godot 4.6+ expert**. I follow current best practices for GDScript, scen
## Project structure ## Project structure
Files are grouped by **role**, not by type. Scripts and scenes are `snake_case`;
`PascalCase` is reserved for `class_name` identifiers (this avoids case-insensitive
filesystem aliasing on the web/macOS targets).
```
actors/{player,matador,bear}/ the three characters (script + scene together)
systems/combat/ hitbox.gd, damage_event.gd, physics_layers.gd
systems/fx/ Fx autoload + effect scenes (Siim's authoring dir)
systems/input/ controls_manager.gd, touch_controls.gd
systems/debug/ debug_params.gd (DP), debug_draw.gd, console.gd
systems/render/ rigid_skin.gd, ps1_filter (post-process)
systems/crowd/ billboard audience
systems/config/ settings.gd (Settings autoload)
ui/ hud, mobile_hud, main_menu, ui_theme/fonts, overlays
props/ barrels, torch
levels/ game_shell.tscn + level modules
tools/ tests/ editor/bake scripts, headless tests
art/ all raw art, grouped by role (snake_case):
characters/ levels/ weapons/ bull/matador/bear, arena/lobby geometry, spear/sword
fx/ anim/ textures/ bear_fx, crowd_clap, baked sheets
ui/ icons/ fonts/ menu art, ability icons, Cinzel fonts
hdri/ materials/ sky HDRIs, shared StandardMaterial3D resources
blender/ Siim's .blend working files (Godot-ignored)
```
| Path | Purpose | | Path | Purpose |
|---|---| |---|---|
| `scene.tscn` | Main scene (arena + player) | | `levels/game_shell.tscn` | The reusable **shell** loaded for every level: player, camera, HUD, PS1 filter, and an empty `LevelRoot`. Its `game_shell.gd` instances the active level's module into `LevelRoot` at runtime |
| `Player.tscn` | Player scene root (`CharacterBody3D`) | | `levels/` | The level system: per-level module scenes plus the code that defines, loads and sequences them (see rows below) |
| `player.gd` | Movement, charge, turning logic | | `levels/game_shell.gd` | Shell controller — on load, frees any current level module and instances `Run.active_level().level_scene` into `LevelRoot`. Swapping the whole subtree (never hiding it) is what keeps one level's meshes/colliders/spawners from leaking into the next |
| `levels/arena_level.tscn` | The arena **level module**: floor + wall colliders, arena meshes, `MatadorSpawner` (with child `Node3D` spawn points placed by the designer), lighting, audience (`PublikNode`). Instanced into the shell's `LevelRoot` |
| `levels/bear_level.tscn` | The Bear's Den **level module**: bear-arena mesh, its own floor collider, lighting, and a `BearSpawner` (`bear_spawn.gd`) that places the bear at center. Instanced into the shell's `LevelRoot` |
| `actors/player/player.tscn` | Player scene root (`CharacterBody3D`) |
| `actors/player/player.gd` | Movement, charge, turning, and abilities (kick/dash/slam/roll). Ability & movement particle FX are **not** built here — they're authored scenes in `systems/fx/` (`bull_*.tscn`), fired via `Fx.spawn()` (one-shots) / `Fx.attach()` (continuous) |
| `actors/player/bull_impact_fx.gd` | Bull's coded, non-particle impact FX (the slam shockwave rings + kick flash-pop — tweened meshes, not CPUParticles3D, so they can't be `systems/fx/` scenes). Created by `player.gd` |
| `actors/player/bull_legs.gd` | Bull body-wobble + tail Verlet-chain simulation. Created by `player.gd` |
| `camera_spring_arm.gd` | Mouse-look pivot (`Node3D` + `SpringArm3D`) | | `camera_spring_arm.gd` | Mouse-look pivot (`Node3D` + `SpringArm3D`) |
| `camera_follow.gd` | Smooth camera follow (`Camera3D`) | | `camera_follow.gd` | Smooth camera follow (`Camera3D`) |
| `matador.gd` | Matador AI (wander / ragdoll state machine) | | `actors/matador/matador.gd` | Matador AI (wander / ragdoll state machine) |
| `matador_spawn.gd` | Spawns N matadors at random arena positions | | `levels/matador_spawn.gd` | Arena spawner — one matador per designer-placed child `Node3D` spawn point (each enters with a jump-roll toward center); falls back to a programmatic spread if no spawn points are present. Also handles the split-on-death hydra logic |
| `debug_params.gd` | Runtime-tunable parameter registry (autoload `DP`) | | `levels/bear_spawn.gd` | Bear-level spawner — instantiates `enemy_scene` at the arena center; emits the same `all_defeated` / `matador_killed` signals as `matador_spawn.gd` |
| `Assets/` | Raw 3D assets (`.glb`, `.fbx`) | | `actors/bear/bear.tscn` / `actors/bear/bear.gd` | Dark-Souls-style bear boss (`CharacterBody3D`). Routine state machine (wind-up → active → recovery) picking telegraphed moves by range band: Double Swipe / Overhead Smash (close), Leap Slam (mid-far), plus Stalk (2-leg walk-in) / Prowl (4-leg lope) positioning. Melee steps in during the swing (`bear_lunge_speed`) + tracks the bull; the leap is frame-synced to JUMP_SMASH so the paws hit ground on the impact frame (`bear_leap_impact_frame`); slams kick up dust + shake. Combos chain, hyper-armour mid-swing + poise (`bear_stagger_cd`), phase 2 enrage under `bear_enrage_frac` HP. Never damages the bull by colliding — only swings/slams. A horns-first bull charge wounds it (`_sweep_bull_ram`: swept prev→now so a tunnelling/point-blank charge still lands, gated by `bear_ram_reach` + `bull_gore_arc`, edge-triggered = one charge per wound). Joins `&"matador"` so bull abilities already hit it. Tuning under the `Bear` DP section |
| `Blender/` | Blender source files, animation scripts, FBX exports | | `actors/bear/bear_attack_hitboxes.tscn` | The bear's attack colliders as a self-contained sub-scene (instanced under `bear_model`): a `LeapSlamHitbox` (Hitbox + cylinder = ground circle) and `SmashHitbox` (Hitbox + box = forward shockwave lane), plus an `AnimationPlayer` whose `leap_slam` / `smash_travel` clips author each collider's size + travel — scrub to tweak, like `Bear_FX`. `actors/bear/bear.gd` only fires the clip, arms the knock-up shaping, and sweeps for overlaps while it runs (see `_setup_attack_hitboxes` / `_start_attack_hitbox`) |
| `Blender/create_matador_anims.py` | Creates walk + idle animations and exports FBX | | `actors/matador/sword.tscn` / `systems/combat/hitbox.gd` | The matador's sword wrapper (glb + editor-tweakable `BladeHitbox`). `systems/combat/hitbox.gd` (`class_name Hitbox`, Area3D) is the shared attack collider: `activate()`/`deactivate()` gate an active window, `sweep()` catches bodies already inside (AoE), and knock-up can ramp by distance (`knock_up_min_dist`/`_max_dist`) for the bear's outer-ring launch / further-hit-flies-higher |
| `Blender/render_anim_preview.py` | Renders animation preview PNGs for visual verification | | `levels/run_state.gd` | Run progression autoload (`Run`) — the lobby hub and which level is being fought, across scene reloads |
| `Blender/preview/` | Output directory for animation preview images | | `levels/level_def.gd` | `LevelDef` resource — a level's name / `scene_path` (always the shell) / `level_scene` (the level module instanced into the shell) / optional `enemy_scene` (arena wave vs. a boss like the bear) |
| `systems/crowd/crowd_marker.gd` | `CrowdMarker` (`@tool Node3D`, `class_name`) — designer drops one per billboard spectator via the editor's Add-Node dialog; picks one of six 60°-spaced facings from the `orientation` dropdown. Draws an editor-only preview (slab + forward arrow, never serialised) and joins the `&"crowd_marker"` group |
| `systems/crowd/crowd_billboards.gd` / `systems/crowd/crowd_billboard.gdshader` | `MultiMeshInstance3D` that harvests every `CrowdMarker` (group `&"crowd_marker"`) into one draw call, using each marker's world position + chosen facing. Front/back sprite sheet baked by `tools/bake_crowd_sheet.gd`; falls back to a generated inward-facing ring when no markers are placed |
| `systems/debug/debug_params.gd` | Runtime-tunable parameter registry (autoload `DP`). Mobile-relevant flags: `force_touch_controls`, `touch_debug` (also enabled on-device with `?debug=1` in the page URL — shows the live profiler overlay in `systems/input/touch_controls.gd`), and `use_rigid_skin` (default **off** — native GPU skinning everywhere now that the 4.7 web templates fixed the Mali/ANGLE invisible-skinning bug; `systems/render/rigid_skin.gd` is a retained opt-in fallback). Rigid-skin is gated through `Controls.rigid_skin_enabled()`, which a page URL param overrides for on-device A/B with no console: `?skin=1` forces the workaround on (for a device where native skinning still fails), `?noskin=1` forces native off. Turning the workaround off also removes its per-spawn SurfaceTool rebuild, which was the arena's matador-spawn lag |
| `systems/input/touch_controls.gd` | On-screen thumb UI for touch/web (`CanvasLayer`, instanced by `ui/hud.gd`, self-gating on `Controls.use_touch_ui()`): a floating left-side joystick feeding the `move_*` actions + a right-side ability cluster, drawn/hit-tested in one IGNORE-filtered Control from raw `_input()`. The joystick self-heals — the latest left-zone touch re-acquires it (`_stick_index`), and a relayout / focus-out / vanished touch resets state so a dropped touchend can't strand a stuck stick. Ability buttons use grown hit-rects + a press flash. `_draw_debug()` (gated on `Controls.debug_overlay()` — DP `touch_debug` or `?debug=1`) is a live on-device profiler reading Godot's `Performance` monitors: FPS/frame-ms with a bottleneck verdict, `process`(main-thread GDScript) vs `physics`(ragdoll/Jolt) ms with 2 s peak-hold, draw calls/objects/primitives, node count, render resolution, and `crossOriginIsolated` — so a lag spike is pinned to CPU-script vs CPU-physics vs GPU-fill instead of guessed |
| `ui/web_start_gate.gd` | Autoload `WebStartGate` — "TAP TO PLAY" panel shown on web+touch before play; the tap drives `Controls.request_fullscreen_landscape()` so the fullscreen/orientation churn happens with no in-flight touch to lose. Re-armable: polls browser fullscreen state and returns if the player leaves it (iPhone Safari can't fullscreen, so it stops nagging once a request never takes) |
| `ui/mobile_hud.gd` | Mobile-only health readouts (`CanvasLayer`, instanced by `ui/hud.gd` only on touch): big bull pip row top-left + a Souls-style bear boss bar top-centre (discovered via group `&"bear"`, tracks `health_changed`). The desktop bottom pip cluster is hidden on touch |
| `ui/orientation_guard.gd` | Autoload `OrientationGuard` — full-screen "rotate your device" prompt shown on touch devices while portrait |
| `art/` | All raw art, grouped by role (`characters/ levels/ weapons/ fx/ anim/ textures/ ui/ icons/ fonts/`). GLBs use **Extract Textures** import, so their embedded textures land beside them (e.g. `art/levels/arena_*.png`) named from the GLB — expected, keep them tracked |
| `art/blender/` | Blender source files, animation scripts, FBX exports (Godot-ignored via `.gdignore`) |
| `art/blender/create_matador_anims.py` | Creates walk + idle animations and exports FBX |
| `art/blender/render_anim_preview.py` | Renders animation preview PNGs for visual verification |
| `art/blender/preview/` | Output directory for animation preview images |
| `tests/` | Headless test scripts (screenshot capture, logic validation) | | `tests/` | Headless test scripts (screenshot capture, logic validation) |
| `addons/rider-plugin/` | JetBrains Rider IDE integration | | `addons/rider-plugin/` | JetBrains Rider IDE integration |
@@ -58,7 +101,7 @@ I am a **Godot 4.6+ expert**. I follow current best practices for GDScript, scen
## Animation & bone conventions ## Animation & bone conventions
### Blender rig (matador_v02) ### Blender rig (matador)
- **Armature bones:** `matador` (root) → `COG` → `chest` → `head`, `collarbone_L/R` → `arm_L/R` → `forearm_L/R` → `hand_L/R`, `leg_L/R` → `shin_L/R` → `foot_L/R` - **Armature bones:** `matador` (root) → `COG` → `chest` → `head`, `collarbone_L/R` → `arm_L/R` → `forearm_L/R` → `hand_L/R`, `leg_L/R` → `shin_L/R` → `foot_L/R`
- **Rotation mode:** All animated bones use **XYZ Euler** (set in `create_matador_anims.py`) - **Rotation mode:** All animated bones use **XYZ Euler** (set in `create_matador_anims.py`)
- **Bone-local axes:** Swing (forward/back) is on **local X**. Arm lowering from T-pose is on **local Y** (positive = left arm down, negative = right arm down). Knee bend is **positive X** (shins only bend backward). - **Bone-local axes:** Swing (forward/back) is on **local X**. Arm lowering from T-pose is on **local Y** (positive = left arm down, negative = right arm down). Knee bend is **positive X** (shins only bend backward).
@@ -76,8 +119,8 @@ After FBX import, animations appear as `Armature|walk` and `Armature|idle` in An
### Verification workflow ### Verification workflow
1. Edit bones/animations in Blender (`create_matador_anims.py`) 1. Edit bones/animations in Blender (`create_matador_anims.py`)
2. Run render preview: `blender --background Blender/matador_v02.blend --python Blender/render_anim_preview.py` 2. Run render preview: `blender --background art/blender/matador.blend --python art/blender/render_anim_preview.py`
3. Inspect PNGs in `Blender/preview/` — check bone orientations **before** exporting to Godot 3. Inspect PNGs in `art/blender/preview/` — check bone orientations **before** exporting to Godot
4. Export FBX (done automatically by `create_matador_anims.py`) 4. Export FBX (done automatically by `create_matador_anims.py`)
5. Re-import in Godot and test in-game 5. Re-import in Godot and test in-game
@@ -88,10 +131,26 @@ After FBX import, animations appear as `Armature|walk` and `Armature|idle` in An
bash run_tests.sh bash run_tests.sh
# Individual tests: # Individual tests:
gdlint *.gd tests/*.gd # GDScript lint (gdtoolkit, installed via uv) gdlint actors systems ui props levels tests # GDScript lint (gdtoolkit, installed via uv)
godot --headless --script tests/logic_test.gd # pure logic, ~2 s godot --headless --script tests/logic_test.gd # pure logic, ~2 s
godot --headless --script tests/harness_selftest.gd # shared test_helpers: seeded RNG + approx + tally, ~1 s
godot --headless --script tests/damage_pipeline_test.gd # bull's hit reception (take_sword_hit + typed receive_damage/DamageEvent), ~3 s
godot --headless --script tests/fx_gallery_test.gd # every registered Fx effect spawns + self-frees, ~2 s
godot --headless --script tests/performance_test.gd # frame-budget regression guard, ~4 s godot --headless --script tests/performance_test.gd # frame-budget regression guard, ~4 s
godot --headless --script tests/ragdoll_perf_test.gd # on-hit spike breakdown: ragdoll build / sim-start / blood / mass hit, ~90 s
godot --headless --script tests/gameplay_test.gd # full scene, bone sanity, ~4 s godot --headless --script tests/gameplay_test.gd # full scene, bone sanity, ~4 s
godot --headless --script tests/level_switch_test.gd # no arena geometry leaks into the bear level, ~2 s
godot --headless --script tests/touch_controls_test.gd # joystick self-heals: relayout/focus-out/vanished-touch never strand a stuck stick, ~2 s
godot --headless --script tests/ui_layout_test.gd # UI layout invariants (no pixels): HUD/menu stay on-screen, text fits, tap targets ≥44px, scroll works — across resolutions + pseudo-locale, ~6 s
godot --headless --script tests/rigid_skin_test.gd # web mesh conversion keeps every material (no bald / recoloured matadors), ~2 s
godot --headless --script tests/bear_boss_test.gd # bear boss moveset: routines, leap landing, hyper-armour, ~10 s
godot --headless --script tests/bear_fx_test.gd # bear attack-FX: each Bear_FX clip pops its mesh + self-hides, ~2 s
godot --headless --script tests/bear_hitbox_test.gd # bear attack colliders: leap launches everywhere (ring_frac slider) + smash lane travel, ~3 s
godot --headless --script tests/bear_ram_test.gd # a horns-first bull charge wounds the bear once; away/wide/slow spared, ~3 s
godot --headless --script tests/matador_stab_test.gd # matador's BladeHitbox thrust gores a stationary bull, and a landed stab breaks it off to taunt (anti-spam), ~2 s
godot --headless --script tests/matador_taunt_react_test.gd # a taunting matador answers a charge: spear from range, sword up close, ignores non-charges, ~2 s
godot --headless --script tests/matador_charge_test.gd # bull's charge is swept (tunnel-proof) so a fast dash still gores; a committed charge pierces the survival roll, ~2 s
godot --headless --script tests/matador_spear_test.gd # thrown spear masks the BULL layer and hits a stationary bull, ~2 s
# Gameplay test with real rendering (inspect frame strip visually): # Gameplay test with real rendering (inspect frame strip visually):
godot --script tests/gameplay_test.gd # opens a window, saves real screenshots godot --script tests/gameplay_test.gd # opens a window, saves real screenshots
Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

-40
View File
@@ -1,40 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dnv8w5h32ck7m"
path="res://.godot/imported/HUD_0002_ability_DASH.png-011f272dda65c06c407720ec201ad92e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://HUD/HUD_0002_ability_DASH.png"
dest_files=["res://.godot/imported/HUD_0002_ability_DASH.png-011f272dda65c06c407720ec201ad92e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Some files were not shown because too many files have changed in this diff Show More