{"id":18462687,"url":"https://github.com/extism/game_box","last_synced_at":"2025-09-02T04:10:17.524Z","repository":{"id":64410519,"uuid":"575070802","full_name":"extism/game_box","owner":"extism","description":"Jackbox games like platform where each game is a user generated Extism plug-in ","archived":false,"fork":false,"pushed_at":"2023-06-18T15:36:33.000Z","size":5228,"stargazers_count":35,"open_issues_count":47,"forks_count":2,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-08T07:38:21.391Z","etag":null,"topics":["games","jackbox","jackbox-games","jackbox-tv"],"latest_commit_sha":null,"homepage":"https://gamebox.fly.dev/","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/extism.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2022-12-06T17:32:28.000Z","updated_at":"2024-12-28T09:49:16.000Z","dependencies_parsed_at":"2025-04-08T07:45:43.400Z","dependency_job_id":null,"html_url":"https://github.com/extism/game_box","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/extism/game_box","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/extism%2Fgame_box","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/extism%2Fgame_box/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/extism%2Fgame_box/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/extism%2Fgame_box/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/extism","download_url":"https://codeload.github.com/extism/game_box/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/extism%2Fgame_box/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273228229,"owners_count":25067760,"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","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["games","jackbox","jackbox-games","jackbox-tv"],"created_at":"2024-11-06T09:04:03.779Z","updated_at":"2025-09-02T04:10:17.509Z","avatar_url":"https://github.com/extism.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GameBox\n\nThis repo houses GameBox. Details can be found in this 2 part blog post:\n\nhttps://extism.org/blog/extending-fly-io-distributed-game-system-part-1\n\nThis is currently a proof of concept and we are working on making this something we can deploy.\nIf you have Elixir or Phoenix knowledge, we'd love your help! Come join us in [Discord](https://discord.gg/cx3usBCWnc). Stop by the `#elixir-sdk` room.\n\nI've been working on a [tictactoe game in rust](games/tictactoe/) to figure out what the game API will be and how to best integrate with LiveView:\n\n\u003cvideo src=\"https://user-images.githubusercontent.com/185919/206291522-86aed4cf-13b6-4757-a400-4e3c7dafb57f.mp4\"\u003e\u003c/video\u003e\n\nIf you're interested in writing any games, we'd love to have one in another language like Go or Assemblyscript, or Haskell.\n\n## Install\n\n\u003e **Note**: You need rustup installed\n\n```\nmix do deps.get, compile\n```\n\n## Compile games:\n\nI'll have some scripts for this soon. Right now run this:\n\n```sh\ncd games/tictactoe\ncargo build --target wasm32-unknown-unknown\n```\n\n\u003e **Note**: Use `--release` for a smaller build to upload to the prod gamebox site\n\n## Running\n\nYou might need to do this first\n\n```sh\ncd assets\nnpm install\ncd ..\n```\n\nRun with iex so you can manipulate the game state in repl:\n\n```sh\niex -S mix phx.server\n```\n\nOpen game at: http://localhost:4000/\n\n## Game API\n\nCurrently, you need to implement 3 functions to make a game. This will change if we try to add support for different types of games:\n\n```\nget_constraints(void) -\u003e GameConstraints\ninit_game(GameConfig) -\u003e void\nhandle_event(LiveEvent) -\u003e Assigns \nrender(Assigns) -\u003e String\n```\n\n#### `get_constraints(void) -\u003e GameConstraints`\n\nCalled before initializing the game. This gives GameBox some metadata about the constraints of the game. If you do not implement this function it will assume the min and max players are 2.\n\n```rust\n#[derive(Serialize)]\nstruct GameConstraints {\n    min_players: u32,\n    max_players: u32,\n}\n```\n\n#### `init_game(GameConfig) -\u003e void`\n\n`init_game` is called when the players wish to start the game. It should allocate the game state and memory needed.\n`GameConfig` currently looks like this and just receives the players needed to start the game.\n\n```rust\n#[derive(Deserialize)]\nstruct GameConfig {\n    player_ids: Vec\u003cString\u003e,\n}\n```\n\n#### `handle_event(LiveEvent) -\u003e Assigns`\n\n`handle_event` is called each time a liveview event is triggered. The LiveView module, for the most part, proxies any\nliveview events it receives to your game through this function.\n\nThe schema of LiveEvent looks like this right now but will depend on what events your frontend sends:\n\n```rust\n#[derive(Deserialize)]\nstruct CellValue {\n    cell: Option\u003cString\u003e,\n    value: Option\u003cString\u003e,\n}\n\n#[derive(Deserialize)]\nstruct LiveEvent {\n    player_id: String,\n    event_name: String,\n    value: CellValue,\n}\n```\n\nFor example, if you have a button in your app:\n```html\n\u003cbutton phx-click=\"cell-clicked\" phx-value-cell=\"0\" /\u003e\n```\nWhen someone clicks this, the incoming event will be (psuedo-code):\n\n```rust\nLiveEvent {\n    player_id: \"theirname\",\n    event_name: \"cell-clicked\",\n    value: CellValue { value: \"0\"},\n}\n```\n\nIt's up to you to take this event and alter the game state. You should think of your game like a big state machine that receives these events and updates the state until some state transition happens and the rules change. \n\nFrom this function, you can return `Assigns`. Assigns can be whatever type you want it to be. The engine will attach this map to the user's socket and will later be passed back to you in render. Assigns should contain a `version` field which is an incrementing integer. This should be incremented when the game needs to be updated on all sockets. These properties should also only be rendered selectively when you want to change something but version is always needed. We should have a better solution for this in the future.\n\nThis function can also return an error and when it does, that error will be put on the user's socket at `flash[:error]` and render the error no their screen. this is good for validation.\n\n#### `render(Assigns) -\u003e String`\n\n`render` is called each time the game board needs to be rendered. It's called for each user watching or playing the game. You can render the game depending on who is viewing it by attaching metadata to the user's socket with Assigns. The assigns for the user are passed back to you here. For example, you will render the game differently based on whose turn it is and which screen it's being rendered on. You also probably want to render game for non-players without the control elements.\n\n### Reference\n\nCurrently, the [tictactoe game in rust](games/tictactoe/) is the canonical example of a game.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fextism%2Fgame_box","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fextism%2Fgame_box","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fextism%2Fgame_box/lists"}