Commit Graph

8 Commits

Author SHA1 Message Date
daddy 7ecf0d53bd Complete M11 Creator Studio and M12 Trust & Safety for PC5
checkpoint / checkpoint (push) Failing after 3h14m9s
- Creator Studio: Visual behavior & property inspector, GLB model importer, binary persistence
- Trust & Safety: 18+ TOS confirmation (DOB removed), creator guidelines & briefing card on join, in-game reporting HUD
- Test Harness: Add --filter, --skip-backend, --skip-godot to run_checkpoint_tests.py
2026-09-17 23:13:57 +00:00
daddy 6ad91b895c Fix: avatars are capsules in the exe -- use load().instantiate(), not runtime GLTFDocument
checkpoint / checkpoint (push) Successful in 1m47s
Playtest log had the smoking gun:
  WARNING: player.gd: no avatar to show; keeping the placeholder capsule
  ERROR: Parameter "data.tree" is null. at: get_tree

avatar_loader.gd read raw .glb bytes and ran GLTFDocument.append_from_buffer
+ generate_scene() at runtime. In a release export that path produced NO
Skeleton3D (works fine in the editor / headless-from-source), so
load_base_body() returned null and the player fell back to the capsule.
The queue_free() calls in that path also errored (loader runs detached from
any tree).

Fix: load(path).instantiate() the Godot-imported PackedScene (the .scn that
actually ships in the pack, with the skeleton + skin set up by the import
pipeline). The raw-bytes GLTFDocument path stays available for future
user-uploaded models but isn't used for the bundled catalog.

- run_checkpoint_tests.py: also runs the avatar smoke against the EXPORTED
  pack, not just source -- that's what catches release-only resource
  differences. Verified: 14/14 against export/game.pck.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
2026-09-06 00:58:49 +00:00
daddy 54bc763dff Fix backwards controls + the exe's bare-capsule avatar
checkpoint / checkpoint (push) Successful in 1m41s
Two real bugs from the last change, both only visible in a real run:

1. Controls reversed: the third-person SpringArm3D had a 180° Y rotation
   that put the camera IN FRONT of the player looking back -- a mirror, so
   W read as backward and mouse pitch as inverted. SpringArm3D extends its
   child along +Z, not -Z; with no rotation the camera sits behind the
   player (+Z world) and looks -Z straight at them. Verified the vectors
   headless: camera behind, W decreases Z, mouse-up looks up.

2. Bare capsule instead of an avatar in the .exe: avatar_catalog.gd reads
   assets/avatars/catalog.json with FileAccess.open(), but the export used
   `all_resources` + empty include_filter, which does NOT pack plain .json
   files. ensure_catalog() failed -> no loadout -> build_current_avatar()
   returned null -> capsule stayed visible. From source it worked because
   res:// is the real filesystem. Fixed: include_filter="*.json" in both
   export presets (verified catalog.json + the .glb pack are now in the
   exported .pck).

- scripts/verify_export_contents.gd + a checkpoint-runner step: export a
  pack and assert the non-resource runtime files are inside it. This is
  the guard for the "works from source, broken in the .exe" class.

Client-side -- rebuild the exe.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
2026-09-05 23:30:00 +00:00
daddy fb52c4fd08 PC3 Phase 3.3 fix: RATE_LIMIT_ENABLED flag so the smoke suite isn't throttled
Every checkpoint smoke test registers users against one backend from one
client IP, so the per-IP auth limit tripped mid-suite (main_menu_full_flow
-> 2/12). Add RATE_LIMIT_ENABLED (default true); run_checkpoint_tests.py
sets it false for its backend. test_rate_limit.py forces it on in-fixture
so the limiter is still really tested.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
2026-09-05 22:22:52 +00:00
daddy 855311e731 PC3 Phase 3.1: hermetic backend tests + fresh-clone boot check + CI workflow
- backend/tests/conftest.py: pytest_configure brings up an ephemeral
  Postgres via docker compose + runs migrations when DATABASE_URL isn't
  already reachable, and tears it down after. `cd backend && pytest` now
  works from a clean checkout with zero manual setup (72 passed in ~28s);
  no docker and no DB -> the whole suite skips with a clear message instead
  of erroring 60+ times.
- scripts/verify_fresh_clone.sh: exports a pristine tree (git archive, so no
  .godot), imports from scratch, headless-boots the main menu + game scene,
  fails on any SCRIPT ERROR / failed autoload. Catches the stale-class-cache
  class of bug. PASS.
- run_checkpoint_tests.py runs both the 2p multiplayer test and the
  fresh-clone check.
- .forgejo/workflows/checkpoint.yml + docs/ci.md: the CI workflow (runs the
  checkpoint suite on push/PR) and how to enable it -- it needs a Forgejo
  Actions `host` runner registered on the AGP box, a one-time operator step.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
2026-09-05 22:12:49 +00:00
daddy 260b7a38da PC3 Phase 2.2: game-server orchestration + POST /api/worlds/{id}/join
- backend/app/services/game_servers.py: an in-process supervisor. One
  headless Godot dedicated-server process per world, keyed by world_id,
  spawned on demand from the join endpoint, port-allocated from a
  configured range, with a background reaper that kills a world's server
  once its status file reports 0 players for the idle timeout. Off by
  default (GAME_SERVERS_ENABLED); the checkpoint/playtest launcher enables it.
- POST /api/worlds/{id}/join -> {world_id, host, port}; 404 for
  unknown/hidden worlds, 503 when orchestration is disabled. Auth required.
- main.py lifespan starts/stops the supervisor.
- config.py: GODOT_BIN, GAME_PROJECT_DIR, GAME_SERVER_HOST, port range,
  idle timeout.
- tests/test_world_join.py (auth / 404 / visibility / 503) -- suite 72 passed.
- checkpoint runner also runs the 2p multiplayer shell test.

Verified end to end: enabled orchestration, POST /join spawned the Godot
server, a real client connected to the returned address and moved; backend
shutdown reaped the process.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
2026-09-05 22:02:55 +00:00
daddy 587a15a52e PC3: checkpoint runner starts a dedicated server for the network-client smoke
smoke_test_network_client.gd needs a separate `godot scenes/server.tscn`
process on ENet 7777; the runner never started one, so that test has been
failing in every checkpoint run (the only failure in an otherwise-green
suite). Start it just for that test, tear it down after.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
2026-09-05 21:53:05 +00:00
claude-checkpoint-tooling 634b2e39c0 Add test inventory + checkpoint test runner
docs/testing/test_inventory.md: honest, current list of what automated
coverage actually exists (38 backend pytest tests across 2 files, 0 Godot
tests merged yet) and what doesn't (no integration/endpoint tests at all,
no coverage yet for the in-review RS256/moderation work) -- verified
against a genuinely fresh checkout + fresh Postgres, not just read off the
file tree.

scripts/run_checkpoint_tests.py: runs the whole inventory in one shot --
throwaway Postgres, migrations, pytest, then starts the backend server and
runs every scripts/smoke_test_*.gd against it headlessly. Verified working
both with and without a smoke test present (temporarily tested against
PC1's not-yet-merged scripts/api_client.gd + smoke_test_api.gd, removed
before this commit -- that PR carries its own files).

docs/testing/README.md: what running this at a Package Checkpoint review
does and doesn't prove, and how to grow the inventory as real coverage
gets added.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 15:18:49 +00:00