Thursday, June 3, 2027
Building a Simple Spaceship Game Server with Altruist
Posted by

Introduction: Building a Multiplayer Spaceship Server with Altruist
Developing a multiplayer spaceship server can be a fun and rewarding project. With the Altruist framework, building such games becomes significantly easier thanks to its built-in support for managing players, game rooms, and movement mechanics. In this blog post, we will show you how to build a simple spaceship server using the Altruist GamePortal and ForwardMovementPortal to handle player connections, movement, and room management.
Project Overview
The game is built using Altruist's GamePortal and ForwardMovementPortal. The GamePortal is responsible for managing player connections, room assignments, and game session cleanup, while the ForwardMovementPortal allows players to move their spaceship within the game environment.
Here’s a breakdown of the process:
- GamePortal: Manages player connections, disconnections, and room assignments.
- ForwardMovementPortal: Handles player movement, such as rotating and moving up within the game.
- Setup: Map these portals using the Altruist setup API to create the necessary endpoints and run the game server.
Key Features and Implementation
1. Altruist Game Portal
The AltruistGamePortal<TPlayerEntity>
class is at the heart of your game's multiplayer management. It handles player connections, assigns them to rooms, and cleans up inactive sessions.
Available Events
- handshake: Used to obtain basic information such as your client id and available rooms from the server.
- join-game: Allows a player to join an available game session.
- leave-game: Removes a player from the game session.
- Session Cleanup: Automatically cleans inactive sessions periodically.
public class SpaceshipGamePortal : AltruistGamePortal<Spaceship> {
public SimpleGamePortal(IPortalContext context, ILoggerFactory loggerFactory) : base(context, loggerFactory)
{
}
}
The GamePortal automatically manages game sessions and player connections. By extending this class, you can create your own game portal tailored to the game logic of your choice.
2. Altruist Forward Movement Portal
For handling movement, Altruist provides the ForwardMovementPortal, which enables players to move their ships in the game world.
public class SpaceshipMovementPortal : ForwardMovementPortal<Spaceship> {
public SpaceshipMovementPortal(IPortalContext context, ILoggerFactory loggerFactory) : base(context, loggerFactory)
{
}
}
The ForwardMovementPortal handles the movement input for the player’s spaceship, including actions like rotating, moving up, or engaging turbo speed.
3. Setting Up the Game Server
With both the GamePortal and ForwardMovementPortal defined, we can now configure and map them to endpoints in the Altruist setup. This step makes the necessary WebSocket endpoints available for the client to connect to the game and send movement commands.
Altruist Setup
In your AltruistBuilder setup, you map the portals to the appropriate endpoints. For example:
AltruistBuilder.Create(args)
.WithWebsocket(setup => setup
.MapPortal<SpaceshipGamePortal>("/game")
.MapPortal<SpaceshipMovementPortal>("/game")
)
.WebApp() // for websockets we need a WebApp
.StartServer();
dotnet run
4. Example Usage
Once the server is running and the portals are mapped, clients can connect to the game and start sending movement commands.
Join Game Request
To join the game, the client sends a WebSocket message with the player's username.
Request Payload:
{
"event": "join-game",
"name": "Player1"
}
Note:
Optionally, if you wish to place a player in a specific room, or world position:
{
"event": "join-game",
"name": "Player1",
"room": "room_id" // optional, altuist provides a default room for each player
"position": [132, 148] // optional, by default the player is placed at (0,0)
}
To handle the response, the client should be prepared for two types of packets:
- A
SuccessPacket
sent specifically to your client. - A
SyncPacket
containing the newly joined player entity, which is broadcast to all relevant clients.
1. Success Packet
This packet confirms that the player has successfully joined the game.
{
"header": {
"timestamp": "generated_timestamp",
"receiver": "your_client_id",
"sender": "server"
},
"type": "SuccessPacket",
"status": "success",
"message": "Player Player1 joined room 123"
}
2. Sync Packet
This packet contains the updated game state, including the new player's position and other relevant properties.
{
"header": {
"timestamp": "generated_timestamp",
"receiver": "your_client_id",
"sender": "server"
},
"type": "SyncPacket",
"data": {
"position": [30, 45]
// ... other changed properties
}
}
Note:
Use the "receiver"
field in the "header"
to identify whether the packet is meant for your client. If it's a SyncPacket
, ensure you either spawn or update the player in the game world accordingly.
Expected Response (Failure):
{
"header": {
"timestamp": "generated_timestamp",
"receiver": "your_client_id",
"sender": "server"
},
"type": "JoinFailedPacket",
"status": "error",
"message": "Username is required!"
}
Sync Movement Request
For moving the spaceship, the client sends WebSocket messages to the /game endpoint. Here’s how to move up or rotate the spaceship:
Move Up Request:
{
"event": "move",
"moveUp": true
}
Example Rotate Left Request:
{
"event": "move",
"rotateLeft": true
}
The movement service provided by the framework handles the rest, ensuring the spaceship's position is updated in the game world. Once a player's position is updated (synced) each client should be prepared for accepting the sync.
Expected Sync Response
{
"header": {
"timestamp": "generated_timestamp",
"receiver": "your_client_id",
"sender": "server"
},
"type": "SyncPacket",
"data": {
"position": [30, 45],
// ... other changed properties
}
}
Conclusion: Simplifying Game Development with Altruist
With Altruist, building a multiplayer spaceship server becomes an easy task. By leveraging the GamePortal and ForwardMovementPortal, developers can quickly create and manage game rooms, handle player connections, and implement smooth player movement—all with minimal code.
Check out the full implementation on GitHub and explore how these portals can help you create a variety of multiplayer games with ease.