{"id":47409587,"url":"https://github.com/feberts/python-game-server","last_synced_at":"2026-04-04T02:01:02.580Z","repository":{"id":319147546,"uuid":"844488665","full_name":"feberts/python-game-server","owner":"feberts","description":"A lightweight server and framework for turn-based multiplayer games","archived":false,"fork":false,"pushed_at":"2026-03-29T16:58:07.000Z","size":921,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-29T19:07:57.724Z","etag":null,"topics":["api","backend","board-games","client","education","educational","framework","game-development","game-framework","game-programming","game-server","games","lightweight","multiplayer","python","round-based","server","simple","tabletop","turn-based"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/feberts.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-08-19T11:16:08.000Z","updated_at":"2026-03-29T16:58:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/feberts/python-game-server","commit_stats":null,"previous_names":["feberts/game-server","feberts/python-game-server"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/feberts/python-game-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feberts%2Fpython-game-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feberts%2Fpython-game-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feberts%2Fpython-game-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feberts%2Fpython-game-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/feberts","download_url":"https://codeload.github.com/feberts/python-game-server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feberts%2Fpython-game-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31384847,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T01:22:39.193Z","status":"online","status_checked_at":"2026-04-04T02:00:07.569Z","response_time":60,"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":["api","backend","board-games","client","education","educational","framework","game-development","game-framework","game-programming","game-server","games","lightweight","multiplayer","python","round-based","server","simple","tabletop","turn-based"],"created_at":"2026-03-20T23:00:19.405Z","updated_at":"2026-04-04T02:01:02.562Z","avatar_url":"https://github.com/feberts.png","language":"Python","readme":"[![](https://github.com/feberts/python-game-server/actions/workflows/test.yml/badge.svg)](https://github.com/feberts/python-game-server/actions/workflows/test.yml)\n[![](https://github.com/feberts/python-game-server/actions/workflows/lint.yml/badge.svg)](https://github.com/feberts/python-game-server/actions/workflows/lint.yml)\n![](https://img.shields.io/badge/OS-Linux_%7C_Win_%7C_Mac-30C452?labelColor=373F46)\n![](https://img.shields.io/badge/Python-blue?logo=python\u0026logoColor=FFCF3E)\n![](https://img.shields.io/badge/License-GPLv3-blue?labelColor=373F46)\n\n# Multiplayer game server\n\nA lightweight server and framework for turn-based multiplayer games.\n\n![](.github/game_server.svg)\n\n## Overview\n\n### Features\n\n- a framework that allows new games to be added easily\n- a uniform yet flexible API for all games\n- multiple parallel game sessions\n  - you can join a specific session\n  - or auto-join the next non-full session\n- an observer mode to watch another client play\n\n### Designed for\n\n- the development of turn-based multiplayer games such as board or card games\n- programming courses in which students implement clients or new games\n\n### Quick start\n\nTo try this project on your machine, start the server (`server/game_server.py`), then run two clients (`client/tictactoe_client.py`) in separate shells. The only requirement is a regular Python installation.\n\n### About this project\n\nThis server was developed for use in a university programming course, where students learn Python as their first programming language and have to work on projects in small groups. Both the framework and the API are designed so that the programming skills acquired during the first term are sufficient to implement new games and clients. However, the use of the server is not limited to educational scenarios.\n\n## Operating the server\n\nTo run the server in a network, edit IP and port in the configuration file (`server/config.py`). If you intend to run the server as a systemd service, you can use the provided unit file as a starting point. Server and API are implemented in plain Python. Only modules from the standard library are used. This makes the server easy to handle.\n\n## Implementing clients\n\nModule `game_server_api` provides an API for communicating with the server. It allows you to\n\n- start or join a game session\n- submit moves\n- retrieve the game state\n- passively observe another player\n- start a new game within the current session\n\nHere is a short demo of the API usage:\n\n```py\nfrom game_server_api import GameServerAPI\n\ngame = GameServerAPI(server='127.0.0.1', port=4711, game='Yahtzee', players=2,\n                     session='mygame') # pass 'auto' to auto-join a session (default)\n\nmy_id = game.join()    # start/join a session - each client is assigned an ID\ngame.move(position=5)  # perform a move - the function accepts keyword arguments (**kwargs)\nstate = game.state()   # returns a dictionary representing the game state, including\n                       # the ID of the current player(s)\n```\n\nThe [API module](client/game_server_api.py) itself is documented in detail. You can also take a look at the demo clients and the [wiki](https://github.com/feberts/python-game-server/wiki).\n\n## Adding new games\n\nAdding a new game is easy. All you have to do is derive from a base class and override its methods:\n\n1. Create a new module in `server/games/`.\n2. Implement a class that is derived from `AbstractGame`.\n3. Override the base class's methods.\n4. Add the new class to the list of games (`server/games_list.py`).\n\nTo make things even easier, you can use the [template](server/games/template.py) (`server/games/template.py`), which is structured like a tutorial.\n\nNo modifications to the API are required when adding new games. It was designed to be compatible with any game. The function to submit a move accepts keyword arguments (`**kwargs`). These are sent to the server, where they are passed to the corresponding function of the game class as a dictionary. The game state is also sent back as a dictionary. This allows for a maximum of flexibility.\n\n## Observer mode\n\nAn observer will receive the same data as the observed player does when retrieving the game state. This can be useful in a number of ways:\n\n- The observer mode can be used to split up the work in a team. One client could be implemented for the user interaction and another one to display the game board.\n- In a similar way, it can be used as a substitute for multithreading, which is usually not taught in a beginner programming course. Suppose you want to implement a chat client that displays incoming messages continuously while allowing the user to write a new message at the same time. To achieve this, two threads of execution could be used. Alternatively, the observer mode can be used to implement separate clients for input and output.\n- It could also be used to visualize the performance of a reinforcement learning agent.\n\n## Contributing\n\nContributions are welcome. Feel free to create a pull request or open an issue.\n\n## License\n\nCopyright (C) 2025, 2026 Fabian Eberts. Licensed under the GPL version 3 (see LICENSE).\n","funding_links":[],"categories":["Examples"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeberts%2Fpython-game-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffeberts%2Fpython-game-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeberts%2Fpython-game-server/lists"}