Made with GPT-6 Astra (high) on ampcode.
  • GDScript 83.6%
  • JavaScript 15.4%
  • HTML 0.7%
  • Shell 0.3%
Find a file
Tyler Brown 272005979f Reserve landscape XP space for held-aim instructions
Temporarily hide the bottom XP badge during touch landscape aim and restore it immediately on release or cancel. Preserve portrait and desktop XP, and render the two-line instruction state.

Amp-Thread-ID: https://ampcode.com/threads/T-01a0b5a5-5be2-76a7-bcc0-8e6c9d6e6f93
Co-authored-by: Amp <amp@ampcode.com>
2026-10-03 01:56:37 +00:00
.agents Build sculpted-fantasy combat prototype with desktop and touch controls 2026-09-18 19:14:14 +00:00
.amp Add authoritative online play, camp social and controls tutorial 2026-10-02 11:15:22 +00:00
assets Align Character Workshop with mobile concept and generated scenery 2026-09-22 19:32:23 +00:00
game Reserve landscape XP space for held-aim instructions 2026-10-03 01:56:37 +00:00
scripts Add authoritative online play, camp social and controls tutorial 2026-10-02 11:15:22 +00:00
server Separate live scene delivery and preserve reconciliation velocity 2026-10-02 21:23:40 +00:00
tests Reserve landscape XP space for held-aim instructions 2026-10-03 01:56:37 +00:00
web Add authoritative online play, camp social and controls tutorial 2026-10-02 11:15:22 +00:00
.gitignore Build sculpted-fantasy combat prototype with desktop and touch controls 2026-09-18 19:14:14 +00:00
AGENTS.md Stop tutorial quest flicker and make desktop basics release-to-cast 2026-10-02 12:57:58 +00:00
export_presets.cfg Add room waves and fullscreen mobile play 2026-09-19 05:33:29 +00:00
package-lock.json Add authoritative online play, camp social and controls tutorial 2026-10-02 11:15:22 +00:00
package.json Render online actors and spell timelines independently of snapshots 2026-10-02 15:44:08 +00:00
project.godot Build sculpted-fantasy combat prototype with desktop and touch controls 2026-09-18 19:14:14 +00:00
README.md Predict own-pawn walking without delaying input or rewinding snapshots 2026-10-02 13:21:18 +00:00

Bramble & Ember

A small Godot action-RPG prototype exploring sculpted fantasy, desktop controls, and touch combat. Working title, original procedural 3D blockout assets.

Play / build

Requires Godot 4.5.1 Standard (GDScript), its web export templates, and Node 22.13+ for the online gateway (built-in SQLite). In a Linux x86-64 Amp orb, .agents/setup installs both (first download is large). Open project.godot in the editor and press F6/F5 to play natively.

npm ci
scripts/build.sh
node server/gateway.mjs

Use an HTTP server, not a file URL. WebGL 2 is required; the web build is single-threaded, so cross-origin isolation headers are not necessary. Native platform exports need the corresponding export templates and platform SDKs; this prototype only configures the web export.

In Amp orbs, run amp orb services ensure to build the web export and start the supervised preview declared in .amp/services.yaml. It prints a Portal URL that works outside the orb. After changing game code, run amp orb service restart garden to rebuild and serve it. The setup script installs dependencies; the service owns building and serving the preview.

Online camp and accounts

The web client automatically connects to the same-origin gateway as a guest. Guests can reach level 10; Account → Register preserves their heroes and unlocks further progression. Login switches to that account's separate roster. Passwords require at least 12 characters; sessions use HttpOnly cookies, and production requires HTTPS. Guest cookies expire after 30 days: lost browser cookies cannot recover an unregistered guest. Register before relying on a save.

The server runs the real Godot rules and owns movement, combat, XP, quest rewards, and SQLite saves. Online menus do not pause the world. Return to a safe place before reading, adjusting gear, or opening People. Each hero's enemies and rewards remain personal; parties do not imply shared combat. Within three units of the campfire, players can see one another, chat, wave/cheer, and invite up to four people into an explicit-consent party. Parties share objectives and locations; all-ready triggers a cosmetic campfire cheer, never a reward or encounter. Mute and invitation privacy last for the connection. Disconnect removes party membership. Trading, reporting/moderation and shared-enemy co-op are not implemented.

Offline characters stay separate and are never silently uploaded. Use ?offline=1, or Account → Play offline, for local saves; native play is offline unless BRAMBLE_SERVER_URL is set. Offline menus still pause combat. A static HTTP server can serve the offline web build with ?offline=1. The first run offers movement, aim, release, cancel, free-basic and resource coaching. Its labelled practice pad costs no spell resources. Skip or explicitly finish to save completion separately from hero progress; Replay controls is available from ready/pause menus.

See server setup and protocol for production origin, persistent storage, limits and account details. The orb is a development preview, not permanent production hosting. Before public launch, add account recovery, moderation, database backups and operational monitoring.

npm test                       # Existing native game regression suites
npm run test:features          # Content/tutorial/markers/social/account UI
npm run test:network           # Real authority/auth/persistence/anti-forgery tests
GAME_URL=http://127.0.0.1:8090 npm run test:online-browser

The online browser test needs a running gateway with disposable data, not a production database: it creates two guests and upgrades one test account. It uses real touch/keyboard input, observes server snapshots, and captures mobile coaching/quest/party states. Chromium emulation is not physical-device QA. Two simultaneous software-rendered contexts saturate this orb's renderer. The test uses a fixed 1000 ms post-key-release pause (QA_POST_KEY_DELAY overrides it); this verifies slow-input functionality, not normal typing responsiveness. Faster sustained typing caused heartbeat disconnects in that constrained run; typing performance needs verification on representative supported hardware.

Install / fullscreen

The web export includes Godot's generated PWA manifest, icons, and service worker. Use scripts/build.sh to export: it also marks the manifest link to send credentials, which authenticated preview portals require even for same-origin manifest requests. Install from an HTTPS browser page for a fullscreen app where the browser/OS supports it. An older home-screen shortcut may need removing and reinstalling to pick up the fullscreen manifest. Ordinary browser play also offers a Fullscreen toggle on the welcome and pause screens; unsupported browsers hide it. Android system gestures can still reveal system UI; iOS behavior differs. Both orientations are supported. Short touch-device landscape uses closer camera framing even with a controller; desktop and portrait framing stay unchanged. The viewport fits within display cutouts rather than placing controls under them. Offline loading works after an online, service-worker-controlled visit caches the game; browser storage eviction or the preview portal's access gate can still require a connection. Offline characters save locally; online heroes require the gateway and save on its database.

Startup checks for updates before launching the engine. A new worker downloads the complete matching game before activation, revalidating HTTP caches; failed or offline checks retain the previous complete build. Already-running games are not forcibly reloaded. If an older cached page lacks this startup check, open update.html on the same preview origin to apply the waiting build, including inside an embedded preview. This never clears IndexedDB or character saves.

Browser QA

With Node.js 22+ and the exported game served on port 8080:

npm ci
npx playwright install chromium # Only needed outside orbs without an installed browser
npm run test:browser

The suite reuses the orb's preinstalled Chromium when available and explicitly selects ?offline=1 to verify the separate local roster. Set GAME_URL to test another server, CHROME_BIN to choose another Chromium, and QA_ARTIFACTS to choose the screenshot directory (default .amp/in/artifacts/exploration). The default suite uses real touch creation, joystick movement, and attack input to reach and claim the first outdoor landmark, then checks durable profile/world reload. A separately labelled native-generated L8 saved-game fixture checks physical door travel and backtracking; it is not proof of organically earning L8 in the browser. Native tests cover the complete graph, one-time rewards, partial encounters, death, transactional save validation, progression, aiming, and projectile collisions. npm run test:browser -- --story checks new touch cosmetics, Marren's introduction, an organically earned Waystone weapon, safe equip/preview, and durable quest/gear reload. Later gathering/exploration/Keeper quest stages use native fixtures, not an organically played browser campaign. npm run test:browser -- --rewards uses labelled L4 and boss-defeated saved fixtures to test inert future slots, L5 pickup/unlock/confirmation, purple XP labels, and physical exit-portal use while supporting enemies remain. It is not an earned boss route. For the Foundry touch/reload checks, generate saved fixtures with godot --headless --path . --script tests/foundry_test.gd -- --fixture, then run node tests/exploration_browser.mjs --foundry. It checks both gear confirmations, both subclass spell choosers, mobile tracker toggling across rotation, outdoor-only arrows, and durable reload using native-generated chapter saves—not an organically played browser campaign. npm run test:kits-browser checks real Wizard onboarding and prepared spells, then labelled level-16 fixtures for spellbook preparation/aiming, animal form toggles, Walking Bastion, mobile layouts, and active-kit IndexedDB reload. tests/browser.mjs retains the earlier arena-specific input/VFX scenarios; its old dungeon-selector routes do not target the new production exploration flow. Mobile Chromium emulation is not a physical Android/iOS device test. Native exports and Safari still require separate QA. After building and serving the export, npm run test:pwa checks the generated manifest/icons, cookie-gated installability (including an unauthenticated negative control), browser installability criteria, fullscreen enter/exit and denial, control visibility/focus, and offline reload. The update regression uses real workers and versioned asset fixtures to reproduce an embedded stale build, verify recovery without changing saved bytes, and reject incomplete updates. Installed-mode and unsupported-API branches are simulated; Android installation/status-bar behavior needs real-device QA.

For repeatable combat pacing comparisons, run godot --headless --path . --script scripts/pacing.gd. It drives two builds with the same targeting/casting policy and full resources at each room, reporting combat time and resolved enemy mechanics. This is a tuning probe, not a human completion-time estimate.

Automated campaign playtesting

npm run test:playtest                  # Agent invariants + report/CLI regression tests
npm run playtest                       # 16 fresh-start runs: four classes, two policies, two seeds
npm run playtest -- --all-subclasses   # 36 runs across all nine subclasses
npm run playtest -- --screenshots      # Also render three diagnostic snapshots; requires a display
npm run playtest -- --baseline /path/to/previous/report.json --fail-on-regression

This agent earns XP and gear from level 1 through the final Foundry quest reward. It walks, casts, uses real interactions, and can rest/retry at legal checkpoints; it never grants resources or teleports. It is an informed engine-level bot, not a human, visual AI, or browser-input test. Cautious dodges exact telegraphs and prioritizes ready skills; basic-only circles enemies and deliberately ignores other skills/tells. Decisions run every 200ms with at most one cast; menus/reading and ultimate hold gestures take no time. Seeds also vary build choices/orbit direction. The route follows quest guidance, not every optional room, and keeps default Wizard preparations and the first learned animal form. Uncast final-bar abilities are reported as coverage gaps. Do not infer equal subclass balance from completion.

Each run writes report.md, report.json, config.json, and engine logs under .amp/in/artifacts/playtests/<timestamp>/ (override with --out NEW_DIRECTORY). Reports record source commit/hash, engine/configuration, progress timelines, casts, resolved enemy mechanics, damage/deaths/rests, combat resource pressure, bounded action history, and valid profile/world snapshots. Optional screenshots reconstruct the final blocked state or lowest-health state; they are not replays, and production saves omit transient spell effects. Rendering never affects measurements.

Signals flag energy that never limits paid casts, frequent mana denial, damage-free routes, incomplete runs, and baseline regressions. Paid attempts count eligible ability checks, not seconds or unique human decisions. Baseline comparisons require matching policy version, engine and configuration; alerts use +20% completion time, increased deaths, newly incomplete routes, or damage above both +25% and +20. These thresholds prompt investigation, not automatic balance changes.

Use --seeds 1,2, --max-seconds 1200, and --max-deaths 3 to change budgets. A 90-second no-progress watchdog catches navigation stalls (and very long fights). Exit 0 means routes completed; exit 1 means an incomplete route or a requested regression gate failed; exit 2 means tooling/configuration failed. Reports survive incomplete runs. Existing output directories with a config are never overwritten. Bump CampaignBot.VERSION in scripts/campaign_bot.gd when changing the policy.

Before tuning combat, run npm test and this probe, compare the same configuration against a retained baseline, and inspect alerts. Continue browser/touch/save QA separately. Human sessions still answer whether aiming feels good, telegraphs read clearly on a phone, progression feels rewarding, and downtime feels boring. No LLM API, paid service, background schedule, or gameplay tuning is part of this harness.

Controls

Action Desktop Touch Controller
Move WASD / arrows Left joystick Left stick / D-pad
Class basic attack Hold left click to aim, release to attack; J repeats Aim slot 1, release (melee can tap) Aim right stick, hold A
Level-2 choice Space; hold/release if aimed Slot 2; drag/release if aimed B; hold/release if aimed
Level-5 choice Hold Q, aim, release Drag slot 3, release Hold X, aim, release
Level-8 choice E; hold/release if aimed Slot 4; drag/release if aimed Y; hold/release if aimed
Subclass spell (level 10) 1; hold/release if aimed Slot 5; drag/release if aimed LB / L1; hold/release if aimed
Ultimate (level 12) Hold 2, release Hold slot 6, release Hold LT / L2, release
Abilities T / button Abilities; yellow Unlock slot for new spells View / Select
Equipment G / Pause → Equipment Pause → Equipment Start → Equipment
Pause Escape / P / button Pause button Start / Menu
Nearby quest, landmark, rest or doorway F / interaction button Interaction button RB / R1

Controllers use Godot's native input support, backed by the browser Gamepad API on the web. Pair the controller with your phone/computer, open the HTTPS game page, and press a controller button with the page focused. Browser/OS/controller compatibility varies; some browsers expose a controller only after that first press. Use D-pad or left stick to navigate menus, A to confirm, and B to return during a run. Prompts use Xbox-style positions: A bottom, B right, X left, Y top (PlayStation: cross, circle, square, triangle). Custom remapping and rumble are not implemented. The right stick aims attacks; releasing it keeps the last aimed direction. Stick deadzones prevent drift. Touch/keyboard/mouse input restores its own prompts, and disconnecting the active controller pauses combat. A controller reconnect does not automatically resume a paused run.

Keyboard menus use arrows/Tab to navigate and Enter to confirm. Space is reserved for slot 2, so a late combat press cannot restart a run at victory.

Mouse position aims attacks at the ground, including while holding an ability key. Ranger arrows and Druid seed/root shots hit the first enemy in a narrow line; they can miss and never snap to the nearest or marked enemy. Without mouse or stick aim, attacks follow facing. Mark still gives Scoutwing its target priority. On touch, hold an ability and drag to aim at the in-world guide, then release once to cast. Ranged shots and ground spells require a drag; returning within 12 pixels of the original touch cancels. Ground-spell drag length controls distance, up to full range at 72 pixels. Melee and mobility can be quick-tapped or dragged; mobility taps follow movement/facing. Self-buffs and Scoutwing stay taps; Seed Turret uses ground targeting to choose its placement. Keyboard/controller directional abilities preview while held and cast on release; Escape, right-click or controller B cancels. Mouse basics aim while left click is held and fire once on release; idle mouse movement shows no combat guide. J and controller A retain hold-fire. Ultimates require a full combat-earned meter and a 0.35-second hold before release. Early release, opening a menu, losing focus, resizing or controller disconnect cancels without spending charge. Aimed ultimates use the same drag guide and return-to-center cancel; self-ultimates cancel when dragged off their button. RB interacts nearby. Amber rings and charge lanes lock before an enemy attacks. Step or rush out. Mint rings mark the mender's healing area; defeat it or interrupt with Ward/Cinder Clap. The Keeper resists these normal-enemy interrupts, preserving its committed warnings. Purple diamond shards display their XP value: 10 XP per normal enemy and 500 XP per boss. XP is awarded once on pickup, never on death, and shards do not heal. Energy regenerates. Opening a menu pauses offline combat only. Fights contain two waves, or three in Bloom Choir, with a two-second breather between waves. The countdown pauses in offline menus only. Health, position, shards, and ability timers carry between waves; new enemies arrive away from the player. Walk to a doorway, then use F, RB / R1, or its interaction button to travel. Ordinary rooms allow retreat during combat; a living boss locks its exits. Killing a boss immediately opens a violet exit portal back outside its dungeon, even while supporting enemies remain. Walk to it and interact to leave. Repeated A presses never advance rooms. Rest explicitly at the Hearth Shrine to restore health/energy once and set your return point there.

Outdoor exploration and connected dungeons

Begin journey starts at Wayfarer Camp in the continuous Wild Garden. Talk to Marren, the fieldkeeper with the lantern, and choose Help Marren to find her missing scout, Ilyra. The opening has three connected outings:

  • Search the abandoned Waystone cart, gather three emberseeds, and light the scout's memory lantern at the Spring to learn where she fled.
  • Read the old oath, choose one keepsake, free the Grove, and defeat Hushroot in the Orchard. The crowned, named mender heals its companions; its existing attack rules and stats are unchanged.
  • Signal Ilyra at the Ridge Beacon and read her message at the Garden Seal. Follow her below, free the Keeper, and return to her at camp for the ending.

The tracker shows the current objective; a yellow edge arrow guides you outdoors only. Quest − / Quest + hides or restores the tracker without hiding the arrow, and keeps that choice when rotating the screen. Pause → Quest reopens the current clue. Deliberately searching or reading a completed objective reveals the next clue, with one Continue action. Level-ups still only highlight available unlocks; killing enemies never opens story menus.

Actionable NPCs show large gold ! offers, gold ? turn-ins, or a mint in-progress diamond, with separate names/state captions. Tavin and Sella offer four optional, ordered nursery/remembrance jobs: A Road That Drinks, What Hushroot Forgot, Warmth Without Hunger, and Names Beneath the Soot. Their 840 total turn-in XP and one Stone Charm are earned once, independently of the main story. Side directions follow doors indoors and route back to the named giver; accepting, evidence and claiming are validated by the same Adventure interactions on the server and offline.

Six landmarks and their defenders total 3360 XP. Three seeds give 60 XP each and the oath gives 360, for 3900 XP / level 8 before the first dungeon. On the story route, the Waystone reaches level 2, the Spring level 4, and the oath level 5 before the Grove/Orchard fights (totals assume collecting XP shards). No repeated kills or farming are required. Entrance level is a recommendation, not a hard lock. This reward pacing is provisional, not a human completion-time estimate. Outdoor enemies acquire targets farther away and sustain pursuit while you kite within firing range. Escaping well beyond pursuit range sends them home without healing.

The outdoor camera pans continuously. Dungeon travel switches between distinct rooms through physical cardinal doorways, with no destination menu or automatic resource refill. Garden's network is:

Outside — Gate Court — Glasshouse (optional branch)
              |
          Rootworks — Hearth Shrine
              |             |
          Bloom Choir ——————┘
              |
         Keeper's Seat

Garden's mandatory rooms and first completion reward bring the story route to 5940 XP / level 10, when subclass selection opens (5400 without the gather/explore objectives). Glasshouse is optional. Foundry's outdoor entrance connects Cinder Landing ↔ Bellows Hall ↔ Ember Well ↔ Chain Gallery ↔ Furnace Heart, with shortcuts from Landing to Well and Bellows to Gallery. After bringing Ilyra home, enter the Foundry or talk to her and choose Follow the ash: read the shipment manifest, close both ash vents, choose armor from the workers' cache, release both root winches, defeat the Warden, and return the living ember for a choice of reforged armament. The furnace opens after releasing the roots. Each objective requires proximity and a cleared room; paired objects can be done in either order. Closing a reward view leaves its choice available on return.

This chapter adds 8500 one-time quest XP, plus 820 XP from the Foundry's existing encounters and pickups. An exact level-10 start reaches level 13 at the quiet Well and level 16 at the finale, without repeating fights. Existing completed Foundry saves can play the new objectives without respawns or duplicate boss XP. Their investigation breadcrumb already counts as complete; returning to Ilyra can start the remaining living-ember objectives without replaying the boss. Both dungeon bosses drop 500 XP. Garden's separate first-completion reward is 1180 XP. Route totals include collecting every shard.

Backtracking freezes partial enemies, statuses, waves, and uncollected XP shards. Defeated enemies and claimed rewards never respawn merely by leaving, dying, or reloading. Doors discard room-bound spell effects but carry your health, energy, and cooldowns. Rest at camp or a shrine to set a checkpoint; death returns you there without resetting the world. Boss completion leaves exploration open.

Worlds are independent per character. Autosaves occur every three gameplay seconds and on rewards, choices, interactions, death, and returning to Characters. Reload opens character selection; choosing the same character resumes its saved world.

Foundry Cinderlings close quickly. Bellows enemies commit hollow blasts: the hatched amber band between two circles is dangerous, including both boundaries; the center and space beyond the outer rim are safe. The warning stays where it was cast. Normal Bellows can be interrupted. The Forge Warden resists interrupts and chains a hollow fire ring into a blast at the same center: the safe center becomes dangerous. Below half health, crossed forge lanes follow before a punish window. Each step has a distinct locked warning; moving after a tell does not move its danger zone.

Enemy and encounter rewards remain at normal ×1; exploration adds one-time objective and Garden completion rewards. Continuous native arena simulation routes pass with fully built level-45 characters using ordinary combat resources. These are build-viability checks, not fresh-character progression or human completion estimates; balance is still provisional.

Character progression

Every load opens character selection. An empty roster offers Create character; saved characters display their level, race and class. Create a separate character to try a different identity: existing class, race and appearance are locked, and levels only change through progression. Unfinished creation is not saved. After selection, the start screen offers Begin journey (or Continue journey) and Characters.

Delete… asks for confirmation, then hides the character from the active roster. Open Deleted characters and choose Restore to recover the same character, including XP, spells, equipment, quests and world progress. Deleted characters are kept indefinitely; there is no automatic expiry or permanent-delete action. For offline heroes this remains local storage, not a backup: clearing browser data also removes deleted characters. Online archive/restore uses stable server-owned hero IDs. The offline touch/save/reload flow is covered by node tests/exploration_browser.mjs --roster against the running web build.

Eligible empty spell slots turn yellow and say Unlock; tap one to choose that slot's spell. Future hotbar slots are inert. Level-ups never open a picker or banner. The corner prompt is reserved for Subclass and Upgrade choices, including immediately after loading an older high-level save. Nothing is preselected: tap one card, read its short description, then use the single bottom Confirm to learn and leave the ability view. The separate six-icon ability overview opens individual descriptions and upgrades.

Level Unlock
1 Free class basic attack
2, 5, 8 Choose one of two new class spells at each milestone
10 Choose a subclass, then its signature spell, element style, or first Wildheart form
12 Choose a subclass ultimate or second Wildheart form
20, 25, 30, 35, 40, 45 Upgrade slots 1 through 6 in order

Milestone choices do not compete for a shared point budget. Most classes have six combat slots; Wildheart uses four. There is no extra universal dodge. On touch, six slots climb the left column, cross the top, and descend the right, placing the ultimate directly beside the basic attack on the bottom row.

The signature now arrives with subclass selection; the ultimate/second form arrives before the later Foundry fights, rather than at the final reward. Existing saves retain XP, selected spells, gear and cooldowns; newly eligible choices are offered without a reset or bonus XP. Upgrade milestones remain unchanged.

Class Core abilities Subclasses
Warrior Slash; Rush/Brace; Arc Wave/Ember Javelin; Bellows/Echo Hammer Hearthblade / Stoneward
Ranger Quillshot; Tumble/Snare; Pinning Shaft/Volley; Tailwind/Scoutwing Windrunner / Farwatch
Druid Seed Snap; Rootstep/Barkskin; Bramble Bed/Spore Burst; Seed Turret/Ripen Thicketkeeper / Bloomcaller / Wildheart
Wizard Free Arcane Bolt; four prepared mixtures; charged ultimate Stormcaller / Voidweaver

Hearthblade adds Cinder Clap and Hearth Unbound for ignition and a moving flame mantle. Stoneward adds Ward and Walking Bastion: a six-second stone-giant transformation that empowers every equipped ability (35% stronger damage/shields, 30% more reach, 25% less energy), with sword shockwaves, a damaging Rush trail, Brace shock, and Javelin splash. Visual size never changes collision. Ember Javelin burns, Bellows bursts outward in fire, and Echo Hammer targets a ground slam rather than repeating Slash's cone. Warrior's base Brace shields for up to 30 seconds, with a 30-second cooldown; damage can consume the shield earlier. Stoneward's separate Ward is unchanged.

Windrunner adds ricocheting quills and Migrating Flight, which adds seeking shots while moving and attacking. Farwatch marks priority targets and releases a delayed piercing Still Horizon shot along its locked aim. Bow and seed hits resolve on projectile contact with enemy bodies. Aimed shots travel along the locked direction without snapping; swept collision follows both projectile and enemy movement. Intentional ricochet bounces and autonomous seeking attacks retain their own targeting.

Thicketkeeper binds foes with Root Knuckle and leaves root zones with Walking Orchard. Bloomcaller places buds for Seed Snap to detonate and casts a delayed Grand Bloom with expanding bursts. Ground fields lock to their cast position. Summons need no pet controls and do not block movement.

The original six subclasses retain two real alternatives at both milestones; existing learned spells remain selected in older saves. Their alternatives are:

Subclass Level 10 alternative Level 12 alternative
Hearthblade Banked Furnace: placed ignition coals Funeral Pyre: delayed burn-consuming eruption
Stoneward Lodestone: pull foes into a chosen area Faultline: forward knockback and Ward-bank discharge
Windrunner Crosswind: pushing, slowing wind fan Quill Cyclone: placed pulling quill pulses
Farwatch Tether Quill: first-hit hooked projectile Watcher's Barrage: three locked-area arrow waves
Thicketkeeper Briar Ring: hollow binding rim Wild Overgrowth: stationary binding damage field
Bloomcaller Nectar Well: healing and damage clearing Equinox Harvest: local bud harvest and energy recovery

Wildheart chooses two of Bear, Cat, Stag and Raven, at levels 10 and 12. Humanoid has Seed Snap, the selected Bramble Bed/Spore Burst, and two form buttons. Animals have three skills (including their free basic attack) plus Leave form: Bear uses Swipe/Hide/Slam; Cat uses Rake/Pounce/Rend; Stag uses Antler/Glade/Thorns; Raven uses Quill/Drift/Tempest. Entering costs 20 energy; leaving is always free, even at zero energy or during movement. Return to humanoid before changing animals. Three shared cooldown lanes prevent switching into fresh copies of skills. Base recovery is 4 energy/second (+0.25 per focus). The level-40/45 upgrades improve the corresponding form's three skills. Inactive humanoid abilities stay saved for other Druid paths but are not offered as Wildheart upgrades.

Wizard prepares four distinct mixtures from Abilities → Prepare mixtures between fights. The basic Arcane Bolt is free. All mixtures cost 80 of 100 mana; regeneration is 7.5 mana/second, unaffected by focus, so the first full-mana cast requires 8 seconds before another mixture. Repeated casting settles near 10.7 seconds. Mixtures have much stronger damage/control/defense; cost upgrades instead extend reach, never reduce the 80-mana cost. Changing prepared spells preserves resources and recipe cooldowns. Fire/Water provide three initial recipes; Earth at level 8 adds recipes and fills the fourth slot. Stormcaller adds Lightning and Voidweaver adds Aether at level 10, giving ten recipes per subclass. Element style choices still customize effects. Level 12 offers Tempest/Thunderlance or Singularity/Eventide; ultimates use charge, not mana. Prepared spells, current animal form, and cooldowns survive travel and saved-game reload.

Ultimates charge during active fighting and from effective damage; charge carries between rooms but resets on death and respec.

Available spell choices highlight their locked slots without forcing a menu. Learn new nodes while paused, including midfight; this does not heal or refill energy and starts the learned ability's cooldown. Build refunds require a safe state; a character's base class and identity cannot be replaced through the ability book.

Rewards now use ×1 XP, including imported saves; there is no multiplier toggle. Previously earned XP is retained. Collected enemy shards, encounter clears, landmarks, and first Garden completion award XP; revisits never duplicate those rewards. Old world saves migrate automatically. Their existing drops grant no additional XP because those enemies already awarded XP on death in the previous rules. XP, levels, class, learned nodes, subclass, appearance, and world state survive death. Offline characters save locally as a roster in user://character.cfg. Older single-character saves import automatically, preserving XP and identity and beginning a fresh outdoor world. Compatible spell choices remain; conflicting or newly level-gated choices reopen under the milestone rules. Old build.cfg talent preferences are left untouched. Offline browser storage can be cleared or unavailable in private browsing; online server saves do not automatically import these local heroes. Godot flushes web saves asynchronously: closing or reloading immediately after a change can lose the most recent update. Browser QA waits for the actual IndexedDB record before checking reload persistence, rather than treating UI feedback as a flush acknowledgment. The normal XP curve is still prototype tuning.

The creator offers Human, Elf and Dwarf, two body presentations, ten hairstyles (including shoulder-length, long, braids, locs, curls and mohawk), five beard choices, three face shapes, five skin tones and six hair colors. The class preview rotates. Creation follows Calling → Look → Name. Visual choices replace cycling buttons; the Face / Hair / Details selector opens from the editor heading. Styles scroll independently of the hero, fixed skin/hair palettes, and Back / Next footer. Drag the hero or use the turn arrows; the top-right menu contains Head zoom and Cancel creation. The dice button randomizes the look. The optional name (up to 24 characters) appears in the roster; older unnamed saves remain valid. Nothing is written until Create character confirms the draft. Dwarves have broader jaws, noses, brows, shoulders and hands; elves have swept pointed ears and slimmer angular features; humans retain rounder ears/proportions. These are cosmetic: appearance never changes collision, reach or combat stats. Older appearances gain default beard/face settings without losing identity. After building and serving the web export, npm run test:creator checks the guided flow, touch scrolling, resizing, naming and save reload in native Godot and Chromium.

Equipment and initial stat rules

Pause → Equipment (or G) shows your actual adventurer and worn gear beside a filterable bag. Tap a worn slot or All / Weapon / Armor / Charm to filter; mint checks mark equipped items and gold marks the selected item. Selection only previews the resulting stat gains and losses. Equip applies and saves the swap; the character preview stays in the current loadout until then.

The bag scrolls independently of the comparison and pinned Equip button. On very short screens, long comparisons can scroll too without hiding Equip. Portrait uses a smaller character preview when comparing; landscape places it beside the bag. Changing gear requires safety, does not refill resources, and never stacks the same item twice. Weapon art follows the class; earned gear adds visible trim and accessories. Close with ×, Escape, or controller B.

Stat Effect
Power +5% outgoing damage per point
Armor 1% damage reduction per point, capped at 60%
Focus +0.25 energy/second per point; no mana recovery bonus for Wizard
Level +2% outgoing damage per level after 1, additive with Power

Damage bonuses apply once to direct hits, damage-over-time and pets. Armor reduces incoming damage before shields. Health remains 100 and enemies do not automatically scale with the player. These values are an initial tuning pass, not final balance.

Warrior, Ranger and non-Wildheart Druid recover 6 energy/second; Wildheart keeps 4 energy/second. All basic attacks remain free, so recovery means choosing which paid skills to save for—not standing still. Wizard keeps 7.5 mana/second and 80-mana mixtures. Costs, cooldowns and damage were not increased in this pass.

Marren's chain awards a Waykeeper Armament (+2 Power), Field Vest (+8 Armor), and a choice of Ember Charm (+2 Focus) or Stone Charm (+8 Armor). Select an option, then Confirm; neither is preselected and confirmation closes the view. The Keeper quest awards a Warden Armament (+4 Power) and Keeper Charm (+2 Power/+2 Focus), giving a choice between protection, sustain and damage. Rewards are owned, not auto-equipped. The Foundry offers Ashweave Mantle (+8 Armor/+4 Focus) or Forgeplate (+18 Armor), then Furnace Edge (+8 Power) or Warden's Grip (+5 Power/+8 Armor). Inventory, equipped slots and quests persist independently for each character. Old profiles receive neutral starter gear; existing discoveries count toward the quest when you talk to Marren, without duplicating XP or respawning enemies. Version-4 journeys persist the keepsake choice and completed homecoming. Older journeys retain all earned gear, XP and discoveries; completed objectives do not pay revised XP again, and players who already earned both charms keep both. Version-5 worlds add the Foundry chapter and initialize only the newly introduced spell cooldowns when importing older worlds; loading never grants rewards. Version-5 profiles store ordered form choices; version-6 worlds add active form and legacy held elements. Version-6 profiles store four prepared Wizard slots; older Wizards receive a legal default loadout. Older saves retain their existing learned spells, gear and cooldowns.

Scope and design checkpoints

  • Now: a continuous outdoor region leading to two connected handcrafted dungeons: the six-room Sunken Garden and five-room Ashen Foundry. Independent persistent worlds, checkpoints, and two-phase bosses. Four classes with nine subclasses, three cosmetic races, and persistent character progression.
  • First content pass: both dungeons share the same walkable footprint and columns, but use distinct scenery, enemy compositions, and boss patterns. Approaching a doorway exposes an explicit travel action; there are no rendered corridors. The missing-scout arc connects the opening landmarks to the Garden; full outdoor-to-boss enjoyment and pacing still need player testing.
  • Not yet: randomized loot affixes, trading/crafting, procedural rooms, audio, a full campaign, or native mobile release packaging.
  • Animal forms, Walking Bastion empowerment, and Wizard mixtures are playable; their numerical balance remains provisional.
  • game/adventure.gd owns exploration and world persistence over game/combat.gd; game/character.gd owns progression and ability definitions. Rendering and input live in game/main.gd; game/sculpt.gd owns reusable 3D pieces; game/hud.gd owns responsive native UI. Both native and web use these same rules.
  • window.__gameState is read-only browser QA telemetry, not a second control path.

All environment and character meshes are original code-generated primitives. The creator composites the live character over assets/creator/forest-stage.webp, a generated forest-and-stone-dais scenery plate made for the selected Workshop design. Characters and hairstyle thumbnails remain live, correctly lit 3D renders. Manrope and Fraunces are bundled under their included SIL Open Font Licenses.