Repository navigation
Hall: live trailer screens, spatial cabinet sound, warm marquees and a Hall of Fame - #63
Merged
Merged
Conversation
The screen of the cabinet nearest the visitor (two on a desktop, one on a phone or in economy), when it is in front of them and faces them, plays the game's trailer, silent and looping, in place of its poster, and goes back to the poster when they walk away. None plays under reduced motion, while a game is open or the page is hidden, or with ?trailers=0. Clips are hall_assets/clips/<slug>.mp4 (384x216, 15 fps, H.264, no sound, faststart; 29 clips, 1.4 MB in all), re-encoded from danielstephenson.dev's trailers by tools/make_hall_clips.py and served same-origin, since that host sends no CORS header and a cross-origin video would taint the canvas. Hall assets now answer single byte ranges (206/416), which Safari needs to play a video. Frames reach the texture asynchronously through VideoFrame copyTo where available (no stall of the hall's frame), else a small canvas. drafted by Claude on behalf of Daniel Stephenson Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LYNeumobh3ySHVuHYQNDaR
With Sound on, the nearest cabinets (three; two on a phone or in economy) each play a short chiptune phrase of their own, synthesised with WebAudio like the hum (no audio files). The phrase is made up from the game's slug, so it is the same every visit, and flavoured by the game: a tak text adventure gets a slow minor triangle-wave figure, a Halloween game a minor one, the rest a brighter pulse, bell or bass arpeggio; two bars on, two off. Each loop is placed where its cabinet stands: louder near (a soft inverse square, silent past about 11 m), panned to its side as the visitor turns, and quieter and low-passed from behind the cabinet. The loops share the hum's switch (the Sound button and the "Arcade hum" setting) and pause with it while a game is open or the page is hidden. drafted by Claude on behalf of Daniel Stephenson Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LYNeumobh3ySHVuHYQNDaR
… board The marquees of the most played games glow a little warmer (redder and brighter, with an amber glow above): plays as a share of the most played, likes from arcade-social's public /v1/likes/counts weighing in as there come to be more of them (up to a third, in full from 30 likes in all). Only the top end warms; the middle of the field is unchanged, and a filtered hall's dark cabinets stay dark. A Hall of Fame board hangs on the wall right of the door, across from the counter (layout.json room.fame): each game's leaderboards' best score (player, game, board, value; at most six, most played games first) and the games whose boards nobody has topped yet, drawn into one texture. It reads arcade-social's public board routes without credentials, three at a time, a moment after the hall loads, and keeps the public result in sessionStorage for ten minutes. Without arcade-social (the <meta name="arcade-social"> and connect-src that arcade PR #59 adds) or when it is down, the board says the scores are resting and the marquees go by plays alone. drafted by Claude on behalf of Daniel Stephenson Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LYNeumobh3ySHVuHYQNDaR
Each video frame drawn to a screen is a texture upload (and its mipmaps); on a phone or in the economy tier the screen now takes ten of the clip's fifteen frames a second. drafted by Claude on behalf of Daniel Stephenson Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LYNeumobh3ySHVuHYQNDaR
Both sides appended tests to the end of tests/test_hall.py; both kept. With #59 the page names arcade-social and allows it in connect-src, so the Hall of Fame board and the likes' warmth work without the check's shim. drafted by Claude on behalf of Daniel Stephenson Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LYNeumobh3ySHVuHYQNDaR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the walkable hall feel alive: the nearest screens play their game's trailer, each nearby cabinet plays a soft attract loop placed in the room, the most played (and liked) games' marquees glow a little warmer, and a Hall of Fame board by the door lists the best score on each leaderboard. Four commits, each reviewable on its own.
1. Live trailers on the screens (
81aa57f,068387b)?trailers=0.hall_assets/clips/<slug>.mp4, 29 clips, 1.4 MB in all (384x216, 15 fps, H.264, no audio, faststart), re-encoded by the newtools/make_hall_clips.pyfrom danielstephenson.dev/trailers. They are served same-origin, like the posters, because that host sends no CORS header and a cross-origin video would taint the canvas. The CSP needed no change (default-src 'self'covers same-origin media).Accept-Ranges: bytes): Safari plays a video only from a server that does. Compressed variants are never ranged.server.byteRange()is unit-tested.VideoFrame.copyTo({format: "RGBA"})where available, so the hall's frame never stalls on a GPU readback. A synchronous canvasdrawImage/getImageDatawas measured at 70–140 ms per frame under SwiftShader; the async path costs about 3–5 ms per upload. Elsewhere frames go through a small canvas.hall_texturealready updates a same-sized texture in place and regenerates its mipmaps.2. Spatial attract-loop sound (
ff708d9)3. Popularity in the room (
0307d03)/v1/likes/counts, weighted by how many likes exist overall (up to a third, in full from 30 likes in all; with today's 3 likes they barely count). Only the top end warms: today that is env-lib-cpp (0.98), Tidewater (0.29), Beyond Nations (0.13) and FishE (0.05). Dark cabinets in a filtered hall stay dark.layout.jsonroom.fame). It shows each leaderboard's best score (player, game, board, value; at most six, with the most-played games first), plus a "Still open:" line for boards nobody has topped yet. It reads/v1/games/<slug>/boardsand then/v1/boards/<slug>/<board>?limit=1without credentials, three at a time, 2.5 s after load, and keeps the public result insessionStoragefor 10 minutes.Verification
python3 -m pytest: 375 passed, 1 skipped (after merging main). New tests:hall_trailers_test.cjs(screen choice) andhall_fame_test.cjs(warmth, board rows, fetch and cache, service down), plus additions tohall_life_test.cjs(tunes, spatial).layout.jsonnames only clips that exist; the Hall of Fame position.tests/browser/hall_atmosphere_check.cjs, Chromium + SwiftShader; this setup forces economy). Desktop 1024x640, iPhone 13, economy, reduce motion and?trailers=0were all checked with no console errors. The trailer was shown in every profile except reduce motion and?trailers=0, where none plays.Notes for review / integration
<meta name="arcade-social">andconnect-src https://api.<domain>; origin/main (with Hall: likes, top scores and achievements on the cabinet card #59) is merged into this branch and the board and likes were re-checked against it with no shim. Without arcade-social the board reads "Scores are resting" and the marquees go by plays only.tests/test_hall.py(both sides append; keep both).GET /v1/boards/topaggregate in arcade-social would reduce that to one request; it is left as a possible follow-up.drafted by Claude on behalf of Daniel Stephenson
🤖 Generated with Claude Code