A modern dgamelaunch-style SSH server for hosting terminal-based roguelike games, built with Go.
- 🎮 Host multiple terminal games over SSH
- 🔐 Simple password authentication
- 📟 Full PTY support with resize handling
- 🎨 Beautiful game selection menu using Bubble Tea
- ⚙️ Easy YAML configuration
- 🚀 Minimal dependencies, maximum reliability
- 🔌 Custom net.Listener support for advanced networking
go install github.com/opd-ai/go-gamelaunch/cmd/gamelaunch@latest- Generate a sample configuration and SSH keys:
gamelaunch generate-config --generate-keysOr if you prefer to generate them separately:
gamelaunch generate-config
ssh-keygen -t ed25519 -f host_key_ed25519 -N ''-
Edit
config.yamlto configure your games and users -
Start the server:
gamelaunch- Connect with SSH:
ssh player1@localhost -p 2022The server is configured via YAML file:
server:
address: :2022
host_keys:
- ./host_key_ed25519
auth:
users:
player1: password123
games:
nethack:
name: "NetHack 3.6.6"
command: /usr/games/nethack
args: []
env:
- "NETHACKOPTIONS=color,showexp"The library supports custom net.Listener implementations for advanced networking scenarios:
// TLS listener
tlsListener := tls.NewListener(tcpListener, tlsConfig)
launcher, err := gamelaunch.NewLauncherWithListener("config.yaml", tlsListener)
// Unix socket
listener, err := net.Listen("unix", "/var/run/gamelaunch.sock")
launcher, err := gamelaunch.NewLauncherWithListener("config.yaml", listener)
// Systemd socket activation
listeners, _ := activation.Listeners()
launcher, err := gamelaunch.NewLauncherWithListener("config.yaml", listeners[0])# Use TLS
gamelaunch --tls --tls-cert server.crt --tls-key server.key
# Use Unix socket
gamelaunch --unix-socket /var/run/gamelaunch.sock
# Show usage examples
gamelaunch examples
# Generate configuration with SSH keys
gamelaunch generate-config --generate-keysimport "github.com/opd-ai/go-gamelaunch/pkg/gamelaunch"
// Basic usage
launcher, err := gamelaunch.NewLauncher("config.yaml")
if err != nil {
log.Fatal(err)
}
launcher.Serve()
// With custom listener
listener, err := net.Listen("tcp", ":2022")
launcher, err := gamelaunch.NewLauncherWithListener("config.yaml", listener)
launcher.Serve()
// With options
launcher, err := gamelaunch.NewLauncher("config.yaml",
gamelaunch.WithListener(customListener),
gamelaunch.WithConfig(viperConfig),
)The server leverages several excellent Go libraries:
- gliderlabs/ssh: Provides the SSH server implementation
- creack/pty: Handles pseudo-terminal allocation for games
- charmbracelet/bubbletea: Creates the interactive game selection menu
- spf13/viper: Manages configuration
When a user connects:
- They authenticate with username/password
- A beautiful TUI menu appears to select a game
- The selected game launches with full terminal emulation
- Window resizing is handled automatically
- When the game exits, the connection closes
- Go 1.21 or later
- Games must be installed and accessible on the system
- SSH client with PTY support (all standard clients work)
- Always use strong passwords or consider implementing public key authentication
- Run the server as a non-root user with minimal privileges
- Use TLS for encrypted connections when exposed to the internet
- Consider using a firewall to restrict access
monero:43H3Uqnc9rfEsJjUXZYmam45MbtWmREFSANAWY5hijY4aht8cqYaT2BCNhfBhua5XwNdx9Tb6BEdt4tjUHJDwNW5H7mTiwe