Starboss Tech Demo¶
This demo began with the Unity Procedural Boss Demo (Source available here), which our team converted into a multiplayer experience with two different game modes.
The purpose of this technical demo is to show how to take an existing, single player project and convert it to handle a full, multiplayer game cycle. The demo is designed to work with Colyseus version 0.14.7 and Unity version 2020.1.5f1.
Download demo (View source code)
Getting Started¶
Launching a local server¶
You need to install and launch the server from the provided Server directory for this demo to function properly. Simply follow the instructions found underneath “Running the demo server” in the Unity3d section of these docs.
ColyseusSettings ScriptableObject¶
All server settings can be changed via the ColyseusSetting ScriptableObject located here:
If you are running a local server, the default settings should be sufficient, however if you wish to host a server you’ll need to change the Colyseus Server Address and Colyseus Server Port values accordingly.
Playing the Demo¶
Start the player in the scene “StarBossLobby” located at Assets\StarBoss\Scenes\StarBossLobby
. Input your username and create a room to begin. If you cannot reach the room creation screen, confirm your local server is working properly and check the Unity Editor for error logs. If you are successful, the client will load the “Scene_Dev_Environment” scene. When creating a room, you have the option to make a Co-op or a Team Deathmatch room. If you press the Enter key or click the “Start” button within a Co-op room, you’ll “ready up” and the game will begin. If you wait for more players to join on your local server, all players must “ready up” before the game will begin. If you made a Team Deathmatch room, you will need at least 1 more player to join on the other team before you can begin.
Demo Overview¶
Creating and Listing Rooms with Different Game Modes¶
In the overridden CreateRoom
function in StarBossLobbyController.cs
on the client side, you can see where we determine if we're launching a room of type Team Deathmatch or Co-op:
string gameModeLogic = coopToggle.isOn ? "starBossCoop" : "starBossTDM";
roomOptions = new Dictionary<string, object> {{"logic", gameModeLogic }, { "scoreToWin", 3 } };
LoadMainScene(() => { ExampleManager.Instance.CreateNewRoom(selectRoomMenu.RoomCreationName, roomOptions);
On the server side in StarBossRoom.ts
we receive these roomOptions
and use the logic
member to determine which type of room we're going to create:
// Retrieve the custom logic for the room
const customLogic = await this.getCustomLogic(options["logic"]);
if(customLogic == null) logger.debug("NO Custom Logic Set");
try{
if(customLogic != null) {
this.setMetadata({isCoop: options["logic"] == "starBossCoop" });
customLogic.InitializeLogic(this, options);
}
}
catch(error){
logger.error("Error with custom room logic: " + error);
}
In this line:
this.setMetadata({isCoop: options["logic"] == "starBossCoop" });
We set the value for isCoop
in the room's metadata, which we can then use on the client side to display the type of room.
To accomplish this, on the client side we created a Serializable class StarBossRoomMetaData.cs
that contains the isCoop
value. We then use this class within our custom StarBossRoomAvailable
which inherits from ColyseusRoomAvailable
:
[System.Serializable]
public class StarBossRoomAvailable : ColyseusRoomAvailable {
public StarBossRoomMetaData metadata;
}
And then within ExampleManager.cs
we have updated the GetAvailableRooms
function to receive data of type StarBossRoomAvailable
:
public async void GetAvailableRooms() {
StarBossRoomAvailable[] rooms = await client.GetAvailableRooms<StarBossRoomAvailable>(_roomController.roomName);
onRoomsReceived?.Invoke(rooms);
}
We also updated the OnRoomsReceived
delegate call to use StarBossRoomAvailable
. Finally, for every entry we receive, we Instantiate an object with a RoomListItem
component attached and we pass it a reference to the room available. In the DetermineMode
function in RoomListItem.cs
:
bool isCoop = roomRef.metadata.isCoop;
if (isCoop) {
roomName.text = roomRef.roomId;
gameMode.text = "Co-op";
gameMode.color = coopColor;
backgroundImage.color = coopColor;
}
else {
roomName.text = roomRef.roomId;
gameMode.text = "Team Deathmatch";
gameMode.color = deathmatchColor;
backgroundImage.color = deathmatchColor;
}
The final result gives us something like this:
Adjusting the Demo¶
As you play around with this demo, you may want to make some adjustments to better familiarize yourself with what is happening. Below, you’ll learn how to make these minor adjustments.
Team Deathmatch Score to Win¶
The maximum score to win in a Team Deathmatch is currently set to 3 on the client side in the overridden CreateRoom
function in StarBossLobbyController.cs
:
roomOptions = new Dictionary<string, object> {{"logic", gameModeLogic }, { "scoreToWin", 3 } };
LoadMainScene(() => { ExampleManager.Instance.CreateNewRoom(selectRoomMenu.RoomCreationName, roomOptions);
On the server side, we receive these roomOptions
and use them to initialize the game logic. Only if we're initializing a Team Deathmatch room, do we make use of the scoreToWin
option as seen in starBossTDM.js
:
roomRef.tdmScoreToWin = options["scoreToWin"] ? Number(options["scoreToWin"]) : 10;