00Executive summary
What The Way is, in one screen.
The Way is a single-page WebGL experience that tells Christ's life across seven chapters — In the Beginning, the Manger, the Baptism, the Ministry, the Last Supper, the Cross, the Resurrection. Each chapter is a hand-built 3D scene (PlayCanvas) with its own camera framing, fog mood, ambient colour, particle systems, and a three-bus soundtrack. The player scrolls; scroll position drives chapter progression on rails.
01Status & open decisions
| Item | State | Detail |
|---|---|---|
| Renders clean (0 errors) | DONE | PlayCanvas 2.x migration fixes applied across all 7 chapters |
| Live deploy | DONE | the-way.pages.dev (Cloudflare Pages) |
| Backed up to GitHub | DONE | CosmicAndrew/the-way @ main |
| Code-split bundle | DONE | playcanvas / react / vendor chunks |
| 3-bus audio + save/restore | DONE | narration·score·ambience; localStorage |
| Audio asset files | PENDING — you | 21 mp3s (3 buses × 7 chapters) not yet produced |
| CrazyGames submission | PENDING — you | needs dev account + cover art + QA pass |
| Open-exploration pivot | DECISION | scope & engine choice — see §7 / §9 |
— Current state · the full architecture —
02Stack & build
| Dependency | Version | Role |
|---|---|---|
| playcanvas | ^2.18.1 | WebGL 3D engine — all rendering |
| react / react-dom | ^19.2.6 | UI shell (overlays, HUD) |
| vite | ^8.0.0 | build + dev server (target esnext) |
| gsap | ^3.15.0 | overlay fade transitions |
| howler | ^2.2.4 | Web Audio — 3-bus soundtrack |
| tailwindcss | ^4.3.0 | utility CSS (HUD styling) |
Boot: index.html loads the CrazyGames SDK v3 + fonts → src/main.jsx mounts React → src/App.jsx creates the PlayCanvas Application (FILLMODE_FILL_WINDOW, RESOLUTION_AUTO), instantiates AudioManager + SceneManager, and wires the SDK lifecycle (loadingStart→loadingStop→gameplayStart/Stop).
03Chapter data core game data
Each chapter = a scripture, a camera framing, a fog mood, an ambient colour, and a soundtrack. Source: src/data/chapters.js.
| # | Scene | Scripture | Ref | Camera pos → lookAt | Fog |
|---|---|---|---|---|---|
| 0 | In the Beginning | "In the beginning was the Word…" | John 1:1 | (0,0,30)→(0,0,-20) | none |
| 1 | The Manger | "For unto you is born this day…" | Luke 2:11 | (0,3,15)→(0,.5,-5) | linear 10–60 |
| 2 | The Baptism | "This is my beloved Son…" | Matt 3:17 | (0,2,12)→(0,-.5,-5) | linear 15–80 |
| 3 | The Ministry | "Blessed are the poor in spirit…" | Matt 5:3 | (0,8,25)→(0,0,-10) | linear 20–100 |
| 4 | The Last Supper | "A new commandment I give…" | John 13:34 | (0,2.5,10)→(0,1,-3) | linear 5–30 |
| 5 | The Cross | "For God so loved the world…" | John 3:16 | (0,3,20)→(0,1,-5) | exp 0.003 |
| 6 | The Resurrection | "I am he that liveth, and was dead…" | Rev 1:18 | (0,2,12)→(0,2,-5) | none |
Full ambient colours, fog colours and density values are in the Parameters appendix.
04Engine & particle systems
SceneManager lazy-loads 7 chapter builders, keeps one Entity root each (enabled on activation), and drives a LERP camera (CameraController, speed 0.025, FOV 55°, far 200).
Per-chapter scene construction
| Chapter | Builds |
|---|---|
| 1 · Beginning | Starfield (800 pts, 60px radius) + nebula dust (30 planes) |
| 2 · Manger | Ground, stable (box+roof), manger, star light (omni 2.5), ambient glow |
| 3 · Baptism | Water plane (ripple shader), dove particles, dir+fill lights, 12 rocks |
| 4 · Ministry | Heightfield terrain (sinusoid+radial), crowd (300), sun (dir 2.0) |
| 5 · Last Supper | Table+legs, 7 candles + candle lights (omni 0.6), walls |
| 6 · Cross | Dark ground, 3 crosses, dim red dir light, red rain particles |
| 7 · Resurrection | Tomb panels + rolled stone, resurrection light (omni 8.0) + white glow (4.0) |
Particle emitters
| Emitter | Type | Config |
|---|---|---|
| starfield | custom GL_POINTS mesh | 800 stars · additive · point-size by brightness · rotates |
| dove | ParticleSystem | 40 · sphere emitter r0.3 · life 3s · additive |
| crowd | ParticleSystem | 300 · box 25×2×25 · life 5s · normal blend |
| redRain | ParticleSystem | 500 · box 30×1×20 · life 4s · additive fade |
05Audio — three independent buses
AudioManager (Howler). Each bus lazily creates a Howl per chapter; a missing file fails silently via onloaderror. 800 ms crossfade on chapter change, 400 ms mute fade.
| Bus | Volume | Loop | Source pattern |
|---|---|---|---|
| narration | 0.9 | one-shot | /audio/narration/chapter-N.mp3 |
| score | 0.4 | looped | /audio/score/chapter-N.mp3 |
| ambience | 0.3 | looped | /audio/ambience/chapter-N.mp3 |
public/audio/.06The scroll → chapter mechanic
- A
700vhscroll-spacer = 7 chapters × 100 vh. Scroll position → progress (0–1). useChaptermaps progress → chapter index with a ~7% dead-zone between stops and a 1200 ms transition lock (prevents flashing).useScrollProgresssmooth-lerps 8%/frame and persists the fraction tolocalStorage["the-way:progress"]— restored on return.useReducedMotion: when the OS requests reduced motion, the spacer collapses and chapter is pinned to 0 (static, accessible).
07Build & deploy
| Chunk | Size | Cached separately |
|---|---|---|
| playcanvas-*.js | 1.88 MB | yes — engine rarely changes |
| react-*.js | 190 KB | yes |
| vendor-*.js (gsap+howler) | 106 KB | yes |
| index-*.js (app) | 13.5 KB | changes per deploy |
| Chapter1–7.js | ~2 KB each | lazy, async |
Deployed to Cloudflare Pages → the-way.pages.dev. Source on GitHub CosmicAndrew/the-way @ main. GB course-archive videos are git-ignored (never pushed).
— Direction · where it's going —
08Open exploration proposed
From a timeline you scroll to a world you walk. Design principles drawn from your "Advanced Game Development with AI" course (Godot module + publishing lessons), re-mapped to the web stack.
Today — scroll on rails
- Linear: chapter 0 → 6, one axis
- Fixed scripted camera per scene
- Player is a passenger
- Discovery = scrolling further
Proposed — open world
- Free movement through a continuous space
- Player-controlled camera follows an avatar
- Player is a pilgrim
- Discovery = walking to a station & finding it
Design pattern (translated from the course's Godot lessons → PlayCanvas/web)
| Course lesson (Godot) | Web/PlayCanvas equivalent for The Way |
|---|---|
| Tilemaps & terrains (L15–17) | A walkable 3D ground / path-network connecting the 7 stations as regions of one world |
| Camera system (L14) | Third-person follow camera with boundaries (replaces the scripted LERP rail) |
| Input & movement (L18) | WASD / on-screen joystick avatar control (keyboard + touch for mobile) |
| Collisions / physics layers (L16) | Walkable vs. blocked zones so the pilgrim follows the path, not the void |
| Signals & Area2D triggers (L22) | Proximity triggers at each station → reveal the scripture overlay + play that chapter's audio on arrival |
| AI enemy spawner (L25) | Ambient life — other pilgrims, doves, crowds — populated dynamically, not hand-placed |
| Animated tilemaps (L21) | Environmental motion: water at the Baptism, wind, candlelight — already partly built per chapter |
The key engine question
The course teaches Godot; The Way is built in PlayCanvas (web). Two honest paths:
- Stay PlayCanvas — keep all 7 finished scenes + the live web deploy + CrazyGames-web path. Add an avatar controller, follow camera, collision, and trigger volumes. Lowest waste, fastest to a playable open build.
- Rebuild in Godot — follow the course 1:1, gain its tooling/export targets (web + Play Store + iOS), but discard the existing PlayCanvas scenes. Higher cost, broader platform reach.
09CrazyGames publishing from course L04
The text-rich publishing lesson, distilled to a concrete checklist.
SDK integration
- SDK v3 already loaded in
index.html; lifecycle wired inuseCrazyGames. - Required events: loadingStart/Stop, gameplayStart/Stop ✅ wired.
- Ads to add for monetization: interstitial (between chapters/stations) + rewarded (opt-in unlock, e.g. fast-travel to a station).
- Save progress: use the CrazyGames Data module (our
useCrazyGames.getData/setDataalready bridges to it + localStorage).
Required submission assets
| Asset | Spec |
|---|---|
| Landscape cover | 1920 × 1080 (16:9) |
| Portrait cover | 800 × 1200 (2:3) |
| Square cover | 800 × 800 (1:1) |
| Preview videos | landscape + portrait gameplay capture |
| Text | category, tags, description, controls |
| Orientation | portrait / landscape / both |
QA gates (where most games fail)
- No ads on startup or during exploration — bad UX is rejected.
- Save system must actually persist (test in their iframe sandbox).
- Must work well in fullscreen + at the declared orientation.
- Test every integrated feature fires before submitting.
10Gaps & decisions for you
| Decision | Options |
|---|---|
| Pivot scope | (a) ship current scroll build to CrazyGames now, pivot later · (b) build the open-exploration version first, then ship |
| Engine | (a) stay PlayCanvas — reuse all 7 scenes, fastest · (b) rebuild in Godot per the course — broader platforms, higher cost |
| World shape | (a) one continuous walkable land linking all 7 · (b) a hub you travel out from to each station |
| Audio | produce 21 mp3s · or ship score-only · or AI-generate (course L27: ElevenLabs/Suno) |
| CrazyGames account | you create the dev account + cover art; I wire SDK ads + QA |
AParameters appendix raw values
Full chapter parameters (ambient + fog)
| # | ambientColor (r,g,b) | fog type | fog color / range / density | audio |
|---|---|---|---|---|
| 0 | 0.02, 0.02, 0.08 | none | — | chapter-1 |
| 1 | 0.08, 0.04, 0.01 | linear | 0.10,0.05,0.02 · 10→60 | chapter-2 |
| 2 | 0.02, 0.06, 0.10 | linear | 0.05,0.10,0.15 · 15→80 | chapter-3 |
| 3 | 0.08, 0.06, 0.04 | linear | 0.12,0.08,0.05 · 20→100 | chapter-4 |
| 4 | 0.10, 0.06, 0.02 | linear | 0.08,0.04,0.01 · 5→30 | chapter-5 |
| 5 | 0.06, 0.01, 0.01 | exponential | 0.02,0,0 · density 0.003 | chapter-6 |
| 6 | 0.30, 0.30, 0.35 | none | — | chapter-7 |
Camera, lighting & timing constants
- Camera: FOV 55° · far clip 200 · clear (0.02,0.02,0.05) · LERP 0.025 · settle tol 0.01
- Transition lock: 1200 ms · scroll lerp: 8%/frame · audio crossfade: 800 ms · mute fade: 400 ms
- Scroll-spacer: 700vh · chapter dead-zone: ~7%
- Bus volumes: narration 0.9 · score 0.4 · ambience 0.3