{"id":20396824,"url":"https://github.com/rj/bevygap","last_synced_at":"2025-09-24T02:31:58.532Z","repository":{"id":258181789,"uuid":"865620490","full_name":"RJ/bevygap","owner":"RJ","description":"Utils to set up edgegap bevy game servers ","archived":false,"fork":false,"pushed_at":"2024-11-14T21:55:04.000Z","size":2288,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-14T22:31:55.875Z","etag":null,"topics":["bevy","edgegap","lightyear","matchmaking","multiplayer"],"latest_commit_sha":null,"homepage":"https://rj.github.io/bevygap/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RJ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-30T20:44:25.000Z","updated_at":"2024-11-14T21:55:07.000Z","dependencies_parsed_at":"2024-11-03T23:17:27.870Z","dependency_job_id":"d4e34d4e-9df7-478d-9bcc-78fab305b29a","html_url":"https://github.com/RJ/bevygap","commit_stats":null,"previous_names":["rj/bevygap"],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RJ%2Fbevygap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RJ%2Fbevygap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RJ%2Fbevygap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RJ%2Fbevygap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RJ","download_url":"https://codeload.github.com/RJ/bevygap/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224727063,"owners_count":17359535,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bevy","edgegap","lightyear","matchmaking","multiplayer"],"created_at":"2024-11-15T04:09:45.160Z","updated_at":"2025-09-24T02:31:53.099Z","avatar_url":"https://github.com/RJ.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bevygap – Multiplayer server management tools\n\nThis is a (WIP) toolkit for running multiplayer game servers on [Edgegap](https://edgegap.com), where the games are\nbuilt with Bevy using the [Lightyear](https://crates.io/crates/lightyear) networking library.\n\nThe goal is to have an easy-to-deploy system either yourself with docker-compose, or in the cloud,\nto use Edgegap to spin up gameservers on demand. \n\nMy testbed for this is [bevygap-spaceships](https://github.com/RJ/bevygap-spaceships) – a modified\nstand-alone version of the `spaceships` example from the Lightyear repo.\n\n# Live Demo\n\nIs the [live demo of bevygap-spaceships](https://game.metabrew.com/bevygap-spaceships/) working? Hopefully!\n\n# Documentation / Quickstart\n\nDocumentation by book: [The Bevygap Book](https://rj.github.io/bevygap/)\n\n`mdbook serve -o book/` if you want to view it locally.\n\n\n## Connection flow\n\n* Game client talks to `bevygap_matchmaker_httpd` via websocket, asking to play, and ultimately expecting a response including a `ConnectToken` and gameserver `ip:port`.\n* This makes a nats request to the matchmaker service\n* An edgegap session is created, which corresponds to a gameserver instance (which may be autodeployed in response to this session creation)\n* Matchmaker generates a Lightyear `ConnectToken`, and associates the token's `ClientId` with the edgegap session ID in NATS KV.\n* Client uses the `ConnectToken` to connect to the gameserver\n* Gameserver maintains a list of active connections in NATS KV, which the matchmaker watches.\n* When a client disconnects, the gameserver removes their entry from `active_connection`, causing the matchmaker to delete the Edgegap session.\n\n## Components\n\n### bevygap_matchmaker\n\nClients wishing to connect to the game make a request to our matchmaker service, which then:\n\n* Creates an Edgegap session (which may trigger a new server deployment)\n* Creates a new Lightyear client id and connect token, associated with the session\n* Stores the token/session mapping in NATS KV\n* Returns the connect token, and gameserver IP and port to the client.\n  (the gameserver ip+port will be a machine controlled by Edgegap, running your game server's docker image)\n* Deletes edgegap sessions when clients disconnect, by watching `active_connections` in NATS KV\n\n### bevygap_matchmaker_httpd\n\nAn http endpoint to make \"i want to play\" requests to the matchmaker.\nThe matchmaker itself only exposes a service to NATS, not http.\n\n### bevygap_client_plugin\n\nA bevy plugin for the game client, to replace the normal lightyear `commands.connect_client()` call.\nThe new `commands.bevygap_connect_client()` function will make a request to the matchmaker, then modify lightyear's config to set the supplied\ngame server socket address and connect token, then call `commands.connect_client()` for you.\n\n### bevygap_server_plugin\n\nA bevy plugin for the gameserver, which loads its deployment context from the edgegap API on boot,\nand connects to our NATS instance in order to lookup session information. \n\n### bevygap_shared\n\nShared code for some protocol and NATS stuff, used between the matchmaker and gameserver.\n\n### nats\n\n[NATS](https://nats.io/) is the shared state and messaging backend between our various components.\n\n### edgegap-client\n\nAutogenerated client for the edgegap API using `openapi-generator`. See `gen-edgegap-client.sh`.\n\n### bevy_nfws\n\na basic bevy websocket client, used to talk to the matchmaker.\n\n## NOTES / TODO\n\nprobably want to prefix all NATS subjects/buckets with the edgegap app name or something, so that\nmultiple apps on edgegap can share the nats instance without conflicts.\n\nshould probably be restricted by the nats creds\n\n# WebTransport custom certificate requirements\n\nhttps://w3c.github.io/webtransport/#dom-webtransportoptions-servercertificatehashes\n\nhttps://w3c.github.io/webtransport/#verify-a-certificate-hash\n\nStrict cert requirements, we autogenerate one on boot and report the digest to the client, so\nas long as the server doesn't stay up for more than 14 days, we're fine.\n\nChrome can't do CORS to http://localhost from http://lan-machine it seems, lan-machine would need to serve https.\nhttps://stackoverflow.com/questions/66534759/cors-error-on-request-to-localhost-dev-server-from-remote-site\n\nAccess to fetch at 'http://127.0.0.1:3000/wannaplay' from origin 'http://lan-machine:8008' has been blocked by CORS policy: The request client is not a secure context and the resource is in more-private address space `local`.\n\n## TODO\n\nadd httpd to ly servers that respond like the MM, generating a cert etc?\nhttpd example from bevy_remote:\nhttps://github.com/bevyengine/bevy/blob/main/crates/bevy_remote/src/http.rs\n\nmove cert gen to LY?\n\nimplement the ConnectionRequestHandler properly to reject invalid connections\n\nmove matchmaker bevy/http bits into matchmaker crate too? flag to run bemw server and mm service in one binary, using a thread for mm?\n\nproto id and ly pkey needed in docker-compose for MM stuff too, perhaps a move to a standard `lightyear.env` file which lightyear itself reads too? could default to sane zeros defaults if missing, for dev.\n\n#### edgegap notes\n\n* env vars limited to 255 bytes. hacky util script added to pass ca_contents as docker runtime arg\n* can't use `latest` tag for container images, it's cached aggressively.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frj%2Fbevygap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frj%2Fbevygap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frj%2Fbevygap/lists"}