When starting the dev server, use background mode:
astro dev --background
Manage the background server with astro dev stop, astro dev status, and astro dev logs.
Full documentation: https://docs.astro.build
Consult these guides before working on related tasks:
- Adding pages, dynamic routes, or middleware
- Working with Astro components
- Using React, Vue, Svelte, or other framework components
- Adding or managing content
- Adding styles or using Tailwind
- Supporting multiple languages
Grist is the source of truth for prizes; the code holds no prize list or media paths (src/data/prizes.ts only has types and tier rates). Don't add prizes there, and never commit the Grist doc id (the repo is public).
- The page is staff-only: it asks for the NOC staff password (
NET_ADMIN_TOKEN, same as/noc→ Staff;/gacha/?admin=<password>also works and is remembered). - With the password it loads the reward list from the NOC server (
/api/gacha/prizes), which reads the Grist Prize table live (doc id in its env). Draws, stock and the pull log live on the NOC server (/api/gacha/pull,/log,DELETE /api/gacha= reset); they are not written back to Grist. - Media is read straight from the media server (
https://82-26-104-114.sslip.io:8445/gacha/<id>/…,/gacha/shared/…). Nothing is pulled into the repo. - Stage mode is the default.
?demo=1adds the rehearsal controls (skip video, forced demo item, per-item stock list). - Popular-vote guarantee, on a team's first pull: 1st place gets at least one T1, 2nd-3rd at least one T2 or better (the last card is redrawn if needed). The NOC server reads the ranking from the voting app's
/api/obsboard and keeps the last snapshot, because that board goes empty once the vote session is completed.
Add or change a prize's media (no git changes expected):
- Upload a folder
<id>/to~/shtx-media/www/gacha/on the media server (organizers have SSH access). Image only:image.jpg(the product photo, background removed, on white). Full reveal: alsoreveal.mp4(15 s for T1, 8 s for T2),show.mp4(10 s loop),music.mp3(25 s / 18 s, drop at the hand-off),meta.json({"flash": <ms of the reveal's own white flash>}). - In the Grist Prize row set
Image link=…/gacha/<id>/image.jpgand, for a reveal,Video link=…/gacha/<id>/reveal.mp4. Name (DisplayName, orItemwhen it is empty), tier (Final Prize Tier) and stock (Reward amount) come from the same row;Rejectedrows are skipped. - Reload
/gacha.git statusshould stay clean; if it doesn't, the change belongs in Grist or on the media server instead.