- Removed separate input box and send button from UI
- Added terminal input handling via onData() event listener
- Users can now type directly in the terminal
- Support for:
- Regular input (echoed in terminal)
- Backspace (with visual feedback)
- Enter key to send command
- Ctrl+C to clear current input
- Removed old keyboard event handlers for input box
- Terminal now has focus by default for seamless input experience
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Removed terminal.clear() calls that were clearing screen on every output
update, letting the game process control the display
- Added letterSpacing: 0 to xterm.js config to disable automatic spacing
adjustments that were creating unwanted span tags
- Improved font family to 'Source Code Pro' for better handling of CJK
characters and monospace alignment
- Added lineHeight adjustment (1.2) for better vertical spacing
- Enabled allowProposedApi for access to additional xterm.js features
- Game process output is now properly displayed without formatting artifacts
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Issues fixed:
- GameProcessServer.readProcessOutput() was using fgets() which could cause
line breaks to be mishandled when reading multiple lines at once
- Changed to use fread() with 8KB buffer for non-blocking I/O
- fread() is better for interactive programs
- Properly handles newlines within chunks
- Doesn't break lines unnecessarily
Frontend improvements:
- Changed sendInput() to use terminal.writeln() instead of write() + write('\n')
- Ensures consistent line ending handling
- Cleaner terminal output
Changes:
1. GameProcessServer.php (readProcessOutput):
- Replaced fgets() loop with fread() loops
- 8192-byte buffer size for optimal performance
- Better handles non-blocking I/O streams
2. web/process.html (sendInput):
- Use terminal.writeln() for user input display
- More consistent with xterm.js behavior
Results:
- Line breaks now display correctly
- Output formatting preserved
- Better handling of rapid output
- No double line breaks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
New simplified approach: WebSocket server spawns bin/game process and forwards I/O
Backend Changes:
- New GameProcessServer class (src/Core/GameProcessServer.php)
- Implements MessageComponentInterface (Ratchet)
- For each WebSocket connection, spawns independent php bin/game process
- Uses proc_open() to manage process I/O pipes
- Reads process STDOUT/STDERR in non-blocking mode
- Writes client input to process STDIN
- Automatic process cleanup on disconnect
- No game code modifications required
- New websocket-process-server.php startup script
- Listens on port 9002
- Simple process forwarder without game-specific logic
- Suitable for any interactive CLI application
Frontend Changes:
- New web/process.html
- Ultra-simple WebSocket frontend for process I/O
- Direct STDIN/STDOUT forwarding
- ANSI color support via xterm.js
- Minimal dependencies, minimal code
- Suitable for any CLI game/application
Architecture Benefits:
✓ Zero game code changes needed
✓ Each user gets independent process (isolation)
✓ Real process STDIO, not emulation
✓ ANSI colors work perfectly
✓ Can run ANY CLI application (not just this game)
✓ Simpler than GameSession-based approach
✓ Easier to deploy and manage
Usage:
1. Start WebSocket server:
php websocket-process-server.php
2. Start HTTP file server (for static files):
php -S 0.0.0.0:8080 web/server.php
3. Open browser:
http://localhost:8080/process.html
Message Protocol:
Client → Server:
{ "type": "input", "input": "command" } - Send stdin to process
{ "type": "ping" } - Heartbeat
Server → Client:
{ "type": "output", "text": "..." } - Process stdout/stderr
{ "type": "system", "message": "..." } - Server messages
{ "type": "error", "message": "..." } - Error messages
{ "type": "pong" } - Heartbeat response
Features:
- Non-blocking I/O reading
- Stream buffering management
- Automatic reconnection support
- 30-second heartbeat for keep-alive
- Process termination on disconnect
- Proper error handling
This is the simplest and most elegant approach for running CLI games on web!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>