adventure: let a player act from the web, not just read about it

The equip queue proved the reverse pipe works. This gives it verbs that
play the game: pull out of a run from the adventurer page, take today's
bout from the war room.

Its own table and its own poll, not more actions on equip_orders. Every
column of that table is equip vocabulary (item, slot, tier) and these
verbs act on the character rather than on something it is carrying.

Nothing in a request names an adventurer. The session maps to one
localpart and a localpart to one adventurer, so Pete resolves the
character itself and there is no id on the wire to forge.

The panel's copy is kept honest by the verdict: an applied action hides
the offer it has just spent, a refusal puts the button back. Watching it
run is what put that there, along with the strip's layout — gogobee
answers a bout with a whole sentence of damage, which the equip strip's
two-column row squeezed into a column and wrapped the verb.

Claude-Session: https://claude.ai/code/session_012bxpQQJDjC1mTtLN3VVtBQ
This commit is contained in:
prosolis
2026-07-24 18:55:42 -07:00
parent b19ab5eff0
commit 6b0aae9f4a
10 changed files with 1178 additions and 9 deletions
+42 -8
View File
@@ -58,14 +58,46 @@
</div>
</header>
<!-- How to actually join in. The bout is a Matrix command today; saying so
plainly beats a page that shows a fight nobody can tell how to enter. -->
<div class="mt-6 rounded-3xl bg-[color:var(--card)] border-2 border-theme-adventure/30 p-5 shadow-pete">
<p class="text-sm text-[color:var(--ink)]/75">
<span class="font-semibold text-theme-adventure">Taking your bout:</span>
say <code class="rounded bg-[color:var(--ink)]/8 px-1.5 py-0.5 font-mono text-xs">!adventure siege fight</code>
to me in Matrix. One a day, each. Damage counts whether you win the fight or not — turning up is the mechanic.
</p>
<!-- How to actually join in. A signed-in adventurer can do it from here; the
Matrix command stays on the page for everyone else, because it is still
the only door for a visitor who isn't signed in — and the blow-by-blow of
the fight arrives there whichever door you came through. -->
<div id="adv-actions" class="adv-actions mt-6 rounded-3xl bg-[color:var(--card)] border-2 border-theme-adventure/30 p-5 shadow-pete">
{{if .YouOnBoard}}
{{if .YouFought}}
<p class="text-sm text-[color:var(--ink)]/75">
<span class="font-semibold text-theme-adventure">You've taken your bout today.</span>
Come back tomorrow. One fight each, per day, and everyone in the right-hand column below still has theirs.
</p>
{{else}}
{{/* data-offer marks the half of this panel that stops being true the
moment the bout lands. The script hides it on an applied verdict, so
the page can't go on saying "unspent" over a fight that just
happened. */}}
<div data-offer>
<p class="text-sm text-[color:var(--ink)]/75 mb-3">
<span class="font-semibold text-theme-adventure">Your bout is unspent.</span>
Damage counts whether you win the fight or not. Turning up is the mechanic, and the blow-by-blow lands in Matrix.
</p>
<button type="button"
class="adv-action-btn rounded-full bg-theme-adventure text-white px-4 py-1.5 text-sm font-semibold hover:opacity-90 transition"
data-action="siege_join"
data-label="Take your bout"
data-confirm-label="Yes, take my bout"
data-confirm="Take your bout against this boss now? It's the only one you get today, and it costs real HP, though you can't die from it. The damage comes off the pool whether you win or lose.">Take your bout</button>
</div>
{{end}}
{{else}}
<p class="text-sm text-[color:var(--ink)]/75">
<span class="font-semibold text-theme-adventure">Taking your bout:</span>
say <code class="rounded bg-[color:var(--ink)]/8 px-1.5 py-0.5 font-mono text-xs">!adventure siege fight</code>
to me in Matrix. One a day, each. Damage counts whether you win the fight or not; turning up is the mechanic.
</p>
{{end}}
<div id="adv-action-orders-box" class="mt-4 hidden">
<ul id="adv-action-orders" class="space-y-1.5 text-xs"></ul>
</div>
</div>
<!-- The muster. Two columns, and the right-hand one is the point: a bout not
@@ -206,3 +238,5 @@
})();
</script>
{{end}}
{{define "scripts"}}<script src="/static/js/adventure-actions.js" defer></script>{{end}}