-
Notifications
You must be signed in to change notification settings - Fork 2
Getting Started
This page will guide you through the steps you can take to start working on your game and back-end server.
- Create a new folder in your project asset's root, and name it MyGame
- Create two more folders within MyGame, called Scripts and Scenes
Barebones/Demos
folder, you can delete it. It contains the outcome of this tutorial.
To make things faster, a pre-made scene is provided within the asset, and it's located at Barebones/MasterFramework/Scenes -> MainEmpty
. When you work on your game, you're not forced to use this scene, but it's very convenient to make a copy of it and customize it the way you want.
Open the scene, hit File > Save Scene As
, name it MyMain and save it to MyGame/Scenes
If you hit "Play" in the editor, you should see something like this at the bottom right:
It means that Master and Spawner servers are started, and client (you) is connected to master server. You might be wondering "Why and how these servers are started?" Take a look at the hierarchy:
Here's what these objects are there for:
- Barebones - object, used to conveniently separate framework related stuff from the level
- Connection - this object contains a component which connects client to Master Server
- MasterServer - this is a component, which starts the master server. It has an Auto Start In Editor option, which is why it starts automatically when we hit a "play" button in the editor.
- GameServerStarter - contains a component, which starts a game server. It also contains an Auto Start option, but it should be Not Selected in the main screen. Technically, in the editor, when in main screen, it does pretty much nothing. Only when you start server through command line, it picks up necessary arguments provided, and starts a game server.
- SpawnerServer - this script starts a server, which is responsible for spawning new game processes
- ClientConnector - takes care of connecting a player to game server. Depending on your game-joining flow, you might need to write your own connector
ℹ️ If you tried to log in , you probably got an error saying that there's no profile factory. We'll fix this in the next step
When your clients log in to master server, profiles module will try to construct a profile for each of them. Which is more, clients should also be able to construct their own profile, so that they can subscribe to various observable properties.
This means that client and server should share the same logic for creating profiles. Create a new script called MyGameShared in the Scripts folder. and paste the code below:
using UnityEngine;
using Barebones.MasterServer;
public class MyGameShared : MonoBehaviour {
void Awake () {
// Let the module know which factory to use
ProfilesModule.SetFactory(ProfileFactory);
}
public static ObservableProfile ProfileFactory(string username)
{
// Create a profile and add coins property to it
var profile = new ObservableProfile(username);
profile.AddProperty(new ObservableInt(MyProfileKeys.Coins, 10));
return profile;
}
}
public class MyProfileKeys
{
public const int Coins = 0;
}
This component simply sets a profiles factory (which is a simple method) when it's awakened. Our profile factory simply adds one property, called coins, and sets its default value to 10. Check out player profiles section of the documentation for more info on the matter.
This script should be added to your main screen and, later, to every other screen of your game (mainly to make debugging easier). In this example, it's added to component named Shared
To guide you through game scene setup, we'll be using a small game, made with uNET, called MiniGame. You can find it at Barebones/Demos/MiniGame
.
MiniGame represents a regular uNET game, where you host server and connect to it via NetworkManagerHUD.
ℹ️ If you're not familiar with uNET, I recommend you go through a tutorial in the official unity's manual
General steps to setting up a game scene are as follows:
- Add game server object (IGameServer) - it should handle receiving passes from clients, disconnecting players that are not allowed and etc.
- Add server starter script - this should be a script that reads command line arguments and starts the game server accordingly (example:
GameServerStarter.cs
) - Add connector script - a script that connects client to game server, when client opens the scene. (example:
UnetConnector.cs
) - Add MasterServer prefab - this is not necessary, but recommended for faster development. It will start master server automatically, so that you don't need to.
Open the MiniGame scene, hit File > Save Scene As
, and Save to to your scenes as you did with the main scene. In this example, we'll call it MyGame
Our game server is only valid when it implements IGameServer
interface. If you're using uNET HLAPI, general implementation is already written for you in script UnetGameServer.cs
, this is what we'll be using to set things up faster.
-
Create a new script in
MyGame/Scripts
, and call it MyGameServer.cs -
Make sure your newly created class extends
UnetGameServer
. To do that, you'll need to implement two methods:OnServerUserJoined
andOnServerUserLeft
. These methods are called when authenticated user joins and leaves a game. -
Call
MiniNetworkManager.SpawnPlayer(client.Connection, client.Username, "knife")
in theOnServerUserJoined
. As you might have guessed, this will spawn player's character when player successfully joins the game. OnServerUserJoined is called when the player has officially joined the game.Here's what your script should look like:
using Barebones.MasterServer;
public class MyGameServer : UnetGameServer {
/// <summary>
/// Called, when authenticated user sends a valid access token
/// </summary>
/// <param name="client"></param>
protected override void OnServerUserJoined(UnetClient client)
{
MiniNetworkManager.SpawnPlayer(client.Connection, client.Username, "knife");
}
protected override void OnServerUserLeft(UnetClient client)
{
}
}
```
-
Create a new object in the root of the hierarchy and name it Networking
-
Create a new empty game object as a child of **Networking **object and call it GameServer
-
Attach a newly created component to it.
-
Add the MyGameShared component (the one you created earlier) to the scene as you did in the main scene.
At this point, if you try to run the game, it will behave as it did earlier, except for a thrown error, which says that there's no EventfulNetworkManager in the scene, that's expected, and will be fixed in the next step
We now need to replace the standard NetworkManager with EventfulNetworkManager. It is pretty much the same as the regular NetworkManager, but instead of forcing you to override methods, it triggers events, to which other components can subscribe. MyGameServer component we've created earlier is one of those subscribers.
-
Select
NetworkManager
object in the hierarchy, click Add Component button, and addEventfulNetworkManager
. Now there will be two network managers. -
Remove the
MiniNetworkManager
component by right clicking and selectingRemove component
-
Add the MiniPlayer and Coin prefabs to the list of spawnables (you can find prefabs at
Barebones/MiniGame/Resources/Prefabs
):
General steps for client to join a game are as follow:
- Connect to Master
- Log in
- Retrieve access key
- Send access key to game server
When you are developing your game, you probably want to test every iteration of changes as fast as possible. Normally you'd have to start the server, build a client, connect and login with the client and etc, just to get into the game.
If you're using **uNET **for your games networking, there are a few scripts and prefabs that can automate this process for you, so navigate to Barebones/MasterFramework/Prefabs
- Add MasterServer to scene. This script will automatically start master server when you hit "play" button in the editor
- Add GameServerStarter prefab to the Networking object - it will automatically start your game server (after master server starts)
- Add UnetConnector prefab to the Networking object- it has a flag, called Auto Join If Host, which, as the name suggests, will try to automatically join the game, by first connecting to master and logging in.
- Add Hud prefab in the UI folder to the Canvas object in the hierarchy. It will help you see if the servers were started successfully.
After adding these prefabs, here's what your scene hierarchy should look like:
✅ At this point, if you start the game in editor, Master server should start first, then game server, and after that - a user should join the game. This should be confirmed in your hud:
ℹ️ It's highly recommended that you take a look at how GameServerStarter
and UnetConnector
scripts work, especially if you're not using uNET, or if you're aiming for a custom flow of events. These scripts will give you a general idea of how you can setup your own development process
Even though we have added a coins property to the our custom profile, we never actually used it. To do that, we have to first retrieve the profile, read the value we want, and update it when user picks up a coin.
To do that, open the MyGameServer
script, and modify OnServerUserJoined
method like this:
/// <summary>
/// Called, when authenticated user sends a valid access token
/// </summary>
/// <param name="client"></param>
protected override void OnServerUserJoined(UnetClient client)
{
// Retrieve a profile first
ProfilesModule.GetProfile(client.Username, MasterConnection, profile =>
{
if (profile == null)
{
// We failed to retrieve players profile, let's disconnect him
DisconnectPlayer(client.Username);
return;
}
// Get coins property
var coinsProperty = profile.GetProperty<ObservableInt>(MyProfileKeys.Coins);
// Spawn player (the same method we used earlier)
var player = MiniNetworkManager.SpawnPlayer(client.Connection, client.Username, "knife");
player.Coins = coinsProperty.Value;
// Subscribe to the coins change listener.
// It will be invoked on server, when client picks up a coin.
player.OnCoinsChanged += () =>
{
// Update clients profile by setting a different coins value
coinsProperty.Set(player.Coins);
};
});
}
Build the game with two of your scenes, make sure that main scene is first.
When you're in your game scene, hit "Play" in the editor. As before, it should start master and game servers automatically. You should be able to start the client you just built, and connect to the game.