{"id":20277523,"url":"https://github.com/udamir/magx","last_synced_at":"2025-04-11T05:43:41.623Z","repository":{"id":37745683,"uuid":"291145267","full_name":"udamir/magx","owner":"udamir","description":"Multiplayer game server framework","archived":false,"fork":false,"pushed_at":"2022-01-10T23:19:52.000Z","size":1659,"stargazers_count":39,"open_issues_count":1,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T03:42:05.077Z","etag":null,"topics":["game-server","magx","multiplayer","multiplayer-game-server","nodejs","server","websocket"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/udamir.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}},"created_at":"2020-08-28T21:02:03.000Z","updated_at":"2025-01-16T18:25:39.000Z","dependencies_parsed_at":"2022-08-24T16:11:36.761Z","dependency_job_id":null,"html_url":"https://github.com/udamir/magx","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udamir%2Fmagx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udamir%2Fmagx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udamir%2Fmagx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udamir%2Fmagx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/udamir","download_url":"https://codeload.github.com/udamir/magx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248173821,"owners_count":21059594,"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-server","magx","multiplayer","multiplayer-game-server","nodejs","server","websocket"],"created_at":"2024-11-14T13:18:48.192Z","updated_at":"2025-04-11T05:43:41.594Z","avatar_url":"https://github.com/udamir.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MagX\n\n\u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/v/magx\"\u003e \u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/dm/magx?label=npm\"\u003e \u003cimg alt=\"npm type definitions\" src=\"https://img.shields.io/npm/types/magx\"\u003e \u003cimg alt=\"GitHub\" src=\"https://img.shields.io/github/license/udamir/magx\"\u003e\n\nMultiplayer Game Server Framework for Node.js\n\n## What is MagX?\n\nMagx is a Multiplayer Game Server Framework for Node.js: server-authoritative multiplayer approach is supported as well as relayed multiplayer (also known as client-authoritative).\n\nIn server-authoritative multiplayer approach room state maintained on the server and clients are just visual representations of the current game state. Each client can send messages to change room state, these messages can be validated by server and state changes broadcast to room clients. This enables you to build:\n\n1. Asynchronous real-time authoritiative multiplayer: Fast paced realtime multiplayer. Messages are sent to the server, server calculates changes to the environment and players and data is broadcasted to relevant peers. This typically requires a high tick-rate for the gameplay to feel responsive.\n\n2. Active turn-based multiplayer: Like with Stormbound or Clash Royale mobile games where two or more players are connected and are playing a quick turn-based match. Players are expected to respond to turns immediately. The server receives input, validates them and broadcast to players. The expected tick-rate is quite low as rate of message sent and received is low.\n\nTo create Authoritative Multiplayer server you need Flexible State Mangement with change tracking functionality. [MosX](https://github.com/udamir/mosx) is default state managment engine, but you have the freedom and flexibility to choose state managment engine without limitations.\n\nIn relayed multiplayer approach each client is act as the host of reconcile state changes between peers and perform arbitration on ambiguous or malicious messages sent from bad clients. So each client sends all state changes to server and server broadcasted them to otherr clients without inspection. This approach can be very useful for many types of gameplay but may not suitable for gameplay which depends on central state managed by the game server.\n\n## Summary\nMagX provides to you:\n- WebSocket-based communication\n- Simple API in the server-side and client-side.\n- Automatic state synchronization between server and client.\n- Scale vertically or horizontally\n- Fully customizable\n\n## Getting started\n\n### From examples project\n\nThe easiest way to try out MagX is using the [magx-example](https://github.com/udamir/magx/examples) project:\n## Installation\n\n```\ngit clone https://github.com/udamir/magx.git\ncd magx/examples\nnpm install\n```\n\nTo run the MagX server, run ```npm start```\n\n### Build basic Chat server from scratch\n\n1. Install magx package:\n```\nnpm install --save magx\n```\n\n2. Create a simple chat room handler (chatRoom.ts):\n```typescript\nimport { Room, Client } from \"magx\"\n\nexport class ChatRoom extends Room {\n\n  public onMessage(client: Client, type: string, data: any) {\n    console.log(\"ChatRoom received message from\", client.id, \":\", data)\n    this.broadcast(\"messages\", `(${client.id}) ${data}`)\n  }\n  \n  public onJoin(client: Client) {\n    this.broadcast(\"messages\", `${ client.id } joined.`)\n  }\n  \n  public onLeave(client: Client) {\n    this.broadcast(\"messages\", `${ client.id } left.`)\n  }\n  \n  public onClose() {\n    console.log(\"ChatRoom closed!\")\n  }\n}\n```\n\n3. Create MagX server and define chatRoom (index.ts):\n```typescript\nimport * as http from \"http\"\nimport { Server } from \"magx\"\nimport { ChatRoom } from \"./chatRoom\"\n\nconst server = http.createServer()\n\nconst magx = new Server(server)\nmagx.define(\"chat\", ChatRoom)\n\nconst port = process.env.PORT || 3001\nserver.listen(port, () =\u003e {\n  console.log(`Magx server started on http://localhost:${port}`)\n})\n```\n\nChat server is ready!\n\n4. Create basic index.html page and attach magx-client:\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width\" /\u003e\n\n    \u003c!-- magx client --\u003e\n    \u003cscript type=\"text/javascript\" src=\"/magx\"\u003e\u003c/script\u003e\n\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cstrong\u003eMessages\u003c/strong\u003e\u003cbr\u003e\n\n    \u003cform id=\"form\"\u003e\n      \u003cinput type=\"text\" id=\"input\" value=\"\" autofocus/\u003e\n      \u003cinput type=\"submit\" value=\"send\" /\u003e\n    \u003c/form\u003e\n\n    \u003cdiv id=\"messages\"\u003e\u003c/div\u003e\n\n    \u003cscript\u003e\n      // add js code here\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n5. Connect to MagX server, authenticate and join ChatRoom:\n```js\nconst { host, port, protocol } = window.document.location\nvar client = new MagX.Client({ address: host.replace(/:.*/, ''), port, secure: protocol === \"https:\" })\n\nclient.authenticate()\n  .then(() =\u003e client.getRooms(\"chat\"))\n  .then(rooms =\u003e rooms.length ? client.joinRoom(rooms[0].id) : client.createRoom(\"chat\"))\n  .then(room =\u003e {\n    console.log(\"joined\")\n    \n    // listen to messages coming from the server\n    room.onMessage(\"messages\", (message) =\u003e {\n      var p = document.createElement(\"p\");\n      p.innerText = message;\n      document.querySelector(\"#messages\").appendChild(p);\n    })\n    \n    // send message to room on submit\n    document.querySelector(\"#form\").onsubmit = function(e) {\n      e.preventDefault();\n      var input = document.querySelector(\"#input\");\n      console.log(\"input:\", input.value);\n      \n      // send data to room\n      room.send(\"message\", input.value);\n      \n      // clear input\n      input.value = \"\";\n    }\n  })\n```\n\nSimple chat is ready! You can open several tabs, send and recieve messags.\n\n## Documentation\nsoon...\n\n## Status and roadmap\n[Current project status](https://github.com/udamir/magx/wiki)\n\n[When will Magx v1.0 release](https://github.com/udamir/magx/wiki/When-will-Magx-v1.0-release%3F)\n\n## License\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fudamir%2Fmagx.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fudamir%2Fmagx?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fudamir%2Fmagx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fudamir%2Fmagx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fudamir%2Fmagx/lists"}