You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Posted by Claude (Opus 4.8), an LLM by Anthropic, at andy5995's direction. This is a feasibility sketch and design prompt, not a committed plan; the assessment below is my analysis, not something built or tested.
Idea
A text-based Dealer's Choice client that runs as a multi-node BBS door. The sysop runs the existing headless server; each caller who opens the door launches a text client that connects to it and plays at a terminal. Multiple callers = multiple door instances against the one server.
Why it's a good architectural fit
Dealer's Choice is already a client-server game where the game rules, wire protocol, and networking live in an SDL-free core, and a headless client that speaks the full protocol already exists (the bot). A door is essentially "the bot, but driven by a human at a terminal instead of AI logic." That means:
The server, the wire protocol, and the game rules need no changes — the server treats another connection identically whether it's the GUI client, a bot, or a text client.
Multi-node falls out for free: N door processes to one server is the same as N GUI clients today.
The new work is additive and low-risk to the rest of the codebase — a new client binary alongside the existing GUI and bot, not a change to any of them.
So the hard half (protocol, framing, rules, sockets) is already done and proven headless. What's left is a presentation/input layer plus the BBS door plumbing.
Language: C, reusing the existing core
The door would be written in C, linking the same SDL-free core the bot uses — so it reuses the protocol, framing, auth, and the tcpme socket layer with no reimplementation. A Go door (reusing an existing Go door harness) was considered, but it would mean maintaining a second implementation of the wire protocol in lockstep with the C server on every protocol change; C keeps a single authoritative protocol. It also helps that tcpme already does raw Winsock, which makes the Windows side of the door I/O (below) straightforward rather than the hard part.
What the door would need (the new part)
An ANSI / CP437 renderer for the table. CP437 is a natural fit — the card-suit glyphs are built-in characters, so cards render without any font handling.
Raw terminal keyboard input plus a small event loop that multiplexes two channels: the DC server socket (game-state pushes) and the caller's terminal I/O. This is the classic single-threaded door shape — no new concurrency.
BBS door plumbing: parse the dropfile for the caller's handle, node, time left, and — importantly — the I/O method. Modern doors use one of two transports, and the door should support both behind a small session abstraction:
stdio — the BBS pipes the caller through the door's standard in/out;
socket — the BBS hands the door an already-connected socket (Synchronet's COM0:SOCKETn, Mystic's telnet mode), passed in the dropfile. DOOR32.SYS is the primary dropfile here — it encodes the I/O method and the socket handle cleanly; DOOR.SYS is a common fallback.
On Windows, the socket transport means adopting the BBS's inherited socket handle and doing raw Winsock recv/send on it — which is exactly what tcpme already does, so the door can lean on the existing layer instead of hand-rolling it.
Reference implementation to port from:Immortal Barons, a working BBS door (written in Go) by andy5995, has already solved the fiddly door-side plumbing: DOOR32.SYS + DOOR.SYS parsing (field positions cross-checked against Synchronet's source) and stdio/socket session backends, including the Windows inherited-socket case (a BBS's foreign socket can't be adopted by Go's net.FileConn, so it does raw blocking WSARecv/WSASend on the handle — the C door sidesteps that entirely via tcpme). Different language, so it's a design blueprint rather than reusable code, but the hard parts are worked out there.
Open questions for discussion
CP437 vs UTF-8 for the presentation, and how to handle nicks that don't fit the chosen encoding.
How much of the GUI's presentation to mirror vs. a deliberately minimal table view (hands, pot, whose turn, available actions, action-timer countdown).
Carrier-drop / reconnect handling. A door dropping carrier exercises the server's client-disconnect path harder than the GUI typically does, so this idea and any disconnect-robustness work are worth considering together.
A sensible first step, if this is pursued, would be a throwaway proof-of-concept: a bare stdio client that connects, prints game state as plain text, and sends one action — enough to shake out the socket/terminal multiplexing and the disconnect behaviour before any ANSI art.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Idea
A text-based Dealer's Choice client that runs as a multi-node BBS door. The sysop runs the existing headless server; each caller who opens the door launches a text client that connects to it and plays at a terminal. Multiple callers = multiple door instances against the one server.
Why it's a good architectural fit
Dealer's Choice is already a client-server game where the game rules, wire protocol, and networking live in an SDL-free core, and a headless client that speaks the full protocol already exists (the bot). A door is essentially "the bot, but driven by a human at a terminal instead of AI logic." That means:
So the hard half (protocol, framing, rules, sockets) is already done and proven headless. What's left is a presentation/input layer plus the BBS door plumbing.
Language: C, reusing the existing core
The door would be written in C, linking the same SDL-free core the bot uses — so it reuses the protocol, framing, auth, and the
tcpmesocket layer with no reimplementation. A Go door (reusing an existing Go door harness) was considered, but it would mean maintaining a second implementation of the wire protocol in lockstep with the C server on every protocol change; C keeps a single authoritative protocol. It also helps thattcpmealready does raw Winsock, which makes the Windows side of the door I/O (below) straightforward rather than the hard part.What the door would need (the new part)
An ANSI / CP437 renderer for the table. CP437 is a natural fit — the card-suit glyphs are built-in characters, so cards render without any font handling.
Raw terminal keyboard input plus a small event loop that multiplexes two channels: the DC server socket (game-state pushes) and the caller's terminal I/O. This is the classic single-threaded door shape — no new concurrency.
BBS door plumbing: parse the dropfile for the caller's handle, node, time left, and — importantly — the I/O method. Modern doors use one of two transports, and the door should support both behind a small session abstraction:
COM0:SOCKETn, Mystic's telnet mode), passed in the dropfile. DOOR32.SYS is the primary dropfile here — it encodes the I/O method and the socket handle cleanly; DOOR.SYS is a common fallback.On Windows, the socket transport means adopting the BBS's inherited socket handle and doing raw Winsock recv/send on it — which is exactly what
tcpmealready does, so the door can lean on the existing layer instead of hand-rolling it.Reference implementation to port from: Immortal Barons, a working BBS door (written in Go) by andy5995, has already solved the fiddly door-side plumbing: DOOR32.SYS + DOOR.SYS parsing (field positions cross-checked against Synchronet's source) and stdio/socket session backends, including the Windows inherited-socket case (a BBS's foreign socket can't be adopted by Go's
net.FileConn, so it does raw blockingWSARecv/WSASendon the handle — the C door sidesteps that entirely viatcpme). Different language, so it's a design blueprint rather than reusable code, but the hard parts are worked out there.Open questions for discussion
A sensible first step, if this is pursued, would be a throwaway proof-of-concept: a bare stdio client that connects, prints game state as plain text, and sends one action — enough to shake out the socket/terminal multiplexing and the disconnect behaviour before any ANSI art.
All reactions