···22 domain = "maze.lassul.us";
33 port = 8772;
44in
55-{ self, ... }:
55+{ self, config, ... }:
66{
77 # mazegame: Windows 95 "Maze" screensaver you can play in a browser tab. The
88 # exit is the NixOS snowflake. /watch is a spectator camera that follows a
···1818 services.nginx.virtualHosts.${domain} = {
1919 enableACME = true;
2020 forceSSL = true;
2121+ # nginx hands out the client straight from the store. The game server is a
2222+ # single event loop: every .js it serves during a join burst is time it is
2323+ # not spending on the world tick, and a crowd arriving costs six files
2424+ # each.
2525+ # …the very package the service runs, so the client never lags the server.
2626+ root = config.services.mazegame.package.static;
2727+ locations."/" = {
2828+ index = "index.html";
2929+ tryFiles = "$uri $uri/ =404";
3030+ extraConfig = ''
3131+ # Versions ride in the store path, but the URLs never change, so let
3232+ # the browser revalidate rather than cache a stale client.
3333+ add_header Cache-Control "no-cache";
3434+ '';
3535+ };
3636+ locations."= /play".tryFiles = "/index.html =404";
3737+ locations."= /watch".tryFiles = "/watch.html =404";
3838+2139 # Player and watcher sockets stay open for as long as someone is in the
2240 # maze; players heartbeat every 3s, watchers every 3s, so the default
2341 # 60s read timeout would only bite on a wedged client, but a long window
2442 # keeps idle spectators connected.
2525- locations."/" = {
4343+ locations."/ws/" = {
2644 proxyPass = "http://127.0.0.1:${toString port}";
2745 proxyWebsockets = true;
2846 extraConfig = ''
2947 proxy_read_timeout 1h;
3048 proxy_send_timeout 1h;
3149 '';
5050+ };
5151+ locations."/api/" = {
5252+ proxyPass = "http://127.0.0.1:${toString port}";
3253 };
3354 };
3455}