{"id":16293032,"url":"https://github.com/kimmobrunfeldt/labyrinth","last_synced_at":"2025-10-03T14:34:46.072Z","repository":{"id":40400653,"uuid":"480981006","full_name":"kimmobrunfeldt/labyrinth","owner":"kimmobrunfeldt","description":"Online version of the Labyrinth board game. The game server runs on the host's browser and networking happens peer-to-peer.","archived":false,"fork":false,"pushed_at":"2022-12-25T10:05:26.000Z","size":40898,"stargazers_count":18,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-17T14:22:03.535Z","etag":null,"topics":["game","labyrinth","peer-to-peer","peerjs","webrtc"],"latest_commit_sha":null,"homepage":"https://labyrinth-boardgame.pages.dev","language":"TypeScript","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/kimmobrunfeldt.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}},"created_at":"2022-04-12T21:39:22.000Z","updated_at":"2025-02-21T20:22:52.000Z","dependencies_parsed_at":"2023-01-30T22:00:48.039Z","dependency_job_id":null,"html_url":"https://github.com/kimmobrunfeldt/labyrinth","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimmobrunfeldt%2Flabyrinth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimmobrunfeldt%2Flabyrinth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimmobrunfeldt%2Flabyrinth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimmobrunfeldt%2Flabyrinth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kimmobrunfeldt","download_url":"https://codeload.github.com/kimmobrunfeldt/labyrinth/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244543752,"owners_count":20469556,"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":["game","labyrinth","peer-to-peer","peerjs","webrtc"],"created_at":"2024-10-10T20:09:47.248Z","updated_at":"2025-10-03T14:34:41.030Z","avatar_url":"https://github.com/kimmobrunfeldt.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Labyrinth\n\nOnline version of the Labyrinth board game. The game server runs\non the host's browser and networking happens peer-to-peer via WebRTC.\n\nPlay at: https://labyrinth-boardgame.pages.dev/\n\n![](docs/hand-holding-phone-mockup.png)\n\n\n\nhttps://user-images.githubusercontent.com/1232405/208707395-7fcd2de7-a077-4243-8c76-f1398ff86db4.mov\n\n![](docs/demo-admin-panel.png)\n\nNote: the game might be very slow on mobile, as it might fallback to a public TURN server. Workaround is to use e.g. a Wifi network.\n\nOptimized for Chrome and iOS Safari. Uses React for the UI. _Clean React code was not the goal.._\n\n## Get started\n\n* `npm i`\n* `npm start`\n* Open http://localhost:4000 and click \"Host game\"\n\n## Developing a bot\n\nSee the [reference bot](src/core/bots/example.ts) for all methods. [Random bot](src/core/bots/random.ts) is a minimal example of a working bot that moves randomly.\n\n1. `cp src/core/bots/example.ts cp src/core/bots/new.ts`\n1. Include the new bot in [src/core/bots/availableBots.ts](src/core/bots/availableBots.ts)\n1. Set bot's name with `export const name ...`\n1. Implement `onMyTurn` at minimum\n\nTips:\n* You can remove yourself from the players and add two bots to spectate their super fast playing.\n* You can automatically spectate and add two random bots like this: http://localhost:4000/?spectate=true\u0026bots=random,random\n* `\u0026botDelay=100ms` query parameter makes bots react faser\n\n## Code architecture\n\n* [Game server](src/core/server/server.ts): isolated piece which could be ran in dedicated-mode somewhere else. The server is controlled by the admin client via JSON RPC _(transported via PeerJS WebRTC data connection)_ protocol. In practice, the browser which creates the server also runs the admin client.\n\n    Server code is split into:\n\n    * [src/core/server/board.ts](src/core/server/board.ts) Game board utility functions.\n    * [src/core/server/game.ts](src/core/server/game.ts) Game logic. Synchronous code.\n    * [src/core/server/server.ts](src/core/server/server.ts) Runs networking and connects it to the core game logic. Asynchronous code.\n\n* [Game client](src/core/client.ts): client for the server. Each client equals one player in the server. Bots are also ran on the host's browser. In the worst scenario, the host is running: the server, admin client (Player 1), bot 1, bot 2, and bot 3 clients.\n\n\n## Communication and WebRTC\n\n* Server is the central controller\n* Server broadcasts state continuously to all clients on state changes\n* [PeerJS](https://peerjs.com/) is used for WebRTC data connection abstraction. Handles [signaling](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Signaling_and_video_calling#the_signaling_server) for you.\n\n   Reconnecting was painful. Opted for a quite forceful object [recycle/dispose pattern](src/utils/recycler.ts).\n\n* [mole-rpc](https://github.com/koorchik/node-mole-rpc) for JSON RPC communication between the game server and clients (two-way communication).\n\n    Mole-RPC is transport agnostic and it was fairly simple to create custom\n    [transporters](src/utils/TransportClient.ts) for PeerJS communication.\n\n* Some messages are multiplexed by the server to all clients. For example the hover position of extra piece is not a server state, but purely a client state.\n\n### Sequence diagram\n\nWhat happens when the game is created. Some aspects are simplified.\n\n![Sequence diagram](docs/game-sequence.drawio.png)\n\n\n## Icon credits\n\nBoard\n\n* Knight Helmet by zidney from NounProject.com\n* Three Candle by Designs by MB from NounProject.com\n* Mouse by Mr Balind from NounProject.com\n* Spider by Kiran Shastry from NounProject.com\n* Unicorn by Bakunetsu Kaito from NounProject.com\n* Dagger by Bonegolem from NounProject.com\n* Diamond by Rank Sol from NounProject.com\n* Bat by BackFake from NounProject.com\n* Treasure by Baboon designs from NounProject.com\n* Ghost by Lero Keller from NounProject.com\n* Ring by Ayub Irawan from NounProject.com\n* Cat by Iris Li from NounProject.com\n* Mermaid by Lars Meiertoberens from NounProject.com\n* Holy Grail by Lars Meiertoberens from NounProject.com\n* Dinosaur by TiRo from NounProject.com\n* Key by Alice Design from NounProject.com\n* Treasure Map by Muhammad Miftakhul Rizky from NounProject.com\n* Cannon by sandra from NounProject.com\n* Crown by Pundimon from NounProject.com\n* Potion by Desti Silvana Ekasari from NounProject.com\n* Owl by DinosoftLab from NounProject.com\n* Lizard by Vectorstall from NounProject.com\n* Book by Juan Pablo Bravo from NounProject.com\n* Bug by SBTS from NounProject.com\n* Bomb by NOVITA ASTRI from NounProject.com\n\nUI\n\n* Caret by olcay kurtulus from NounProject.com\n* Settings by i cons from NounProject.com\n* Play Icon by sureya from NounProject.com\n* Player by nico bayu saputro from NounProject.com\n* Replay by Cuputo from NounProject.com\n* Cross by Joni Ramadhan from NounProject.com\n* Visible by Bluetip Design from NounProject.com\n* Invisible by Bluetip Design from NounProject.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkimmobrunfeldt%2Flabyrinth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkimmobrunfeldt%2Flabyrinth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkimmobrunfeldt%2Flabyrinth/lists"}