The dead club doubles its staff, and the draw is made where you can see it

Six new opponent families (head coach, stringer, strawberry seller, chair
umpire, spectator, roller man) through the famroll/zsheet route, placed by
hierarchy into an 18-rung ladder; the champion steps up behind them.

THE DRAW: picking the tournament now rolls its own bracket in front of you —
only the final was ever settled — and what lands is what walks on.

Netplay, off Oliver's cellular report: the mid-flight early-decide was missing
its !G.net gate, so the striker judged its own outbound flight and the two
scoreboards drifted a point apart into a court nobody could serve on. The
host's court now rides the room, its scoreboard rides the pretoss stream, and
a called ball rolls to its own halt instead of freezing where the call caught it.

Plus the night court, and somebody in the stand is taking pictures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-15 11:49:19 +02:00
1 parent 4c47295a73
commit 9cc3ac54b3
207 files changed
+632 -81

No files matched your search

+10 -5
View File
@@ -161,15 +161,20 @@ class Handler(SimpleHTTPRequestHandler):
code = ''.join(random.choice(WS_ALPHABET) for _ in range(4))
ROOMS[code] = [me]
me['room'] = code
# the host's ONE decision rides the room: classic tennis or the death match. The
# start message carries it to both phones, so the joiner never has to be asked.
# the host's decisions ride the room: classic tennis or the death match, and WHICH
# COURT. The start message carries both to both phones, so the joiner is never
# asked — and never ends up playing the same rally on a different surface.
me['death'] = 'death=1' in self.path
me['court'] = re.sub(r'[^a-z]', '', self.path.split('court=')[1].split('&')[0]
if 'court=' in self.path else '')[:12]
if len(ROOMS) > 200: # a lobby is two people; 200 stale rooms is a flood
ROOMS.pop(next(iter(ROOMS)))
if me['peer']: # paired: the host serves first, on both scoreboards
death = 'true' if me['peer'].get('death') else 'false'
ws_send(me['peer'], '{"t":"start","side":"A","death":%s}' % death)
ws_send(me, '{"t":"start","side":"B","death":%s}' % death)
host = me['peer'] # ...and the host's picks are what both phones get
for who, side in ((host, 'A'), (me, 'B')):
ws_send(who, json.dumps({'t': 'start', 'side': side,
'death': bool(host.get('death')),
'court': host.get('court') or ''}))
else:
ws_send(me, json.dumps({'t': 'room', 'code': me['room']}))
try: