GPF Docs
Hello World Tutorial: part 1 - Implementing ServerObjects
Hello World Tutorial: part 1 - Implementing ServerObjects
In this tutorial, we will create a ServerObject
(or SO for short) called HelloSO
whose state is simply a string field called greeting
. The client will send a message with the word "World" up to HelloSO
, and as a result our UI will automatically update to say "Hello World".
Getting Started
If you haven't done so yet, go through the steps on the Quickstart page to get Game Plumbing Framework.
The starter package that you imported comes with the HelloWorld project featured in this tutorial. To start from scratch by delete these folders from your Assets\GamePlumbing\
folder:
ServerObjects
Example
Setup the ServerObjects folder
1.Create a ServerObjects
folder in your Assets folder from the Project
window.
2.Navigate to Edit->Project Settings->Game Plumbing Framework
and set Project Path
to Assets\ServerObjects
using the file browser.
Write SO
1.Right click on the ServerObjects
folder you just created within the Project
window and select Create -> GPF -> Server Object
and name it "HelloSO".
2.Open it and edit it so it looks like this:
using GPF.ServerObjects;namespace HelloWorld.SOs{ public class HelloSO : ServerObject { public string greeting = "What's your name?"; public class MyNameIs : ServerObjectMessage { public string name; } public override SOID ID { get; set; } }}
Write SO Test
1.Create an Editor
folder in your Assets folder
2.Right click on the ServerObjects
folder you just created within the Project
window and select Create -> -> GPF -> Server Object Test
and name it "HelloWorldTest"
3.Open it and edit it so it looks like this:
using HelloWorld.SOs;using GPF;using GPF.ServerObjects;using GPFEditor;using System.Threading.Tasks;using NUnit.Framework;namespace HelloWorldTests{ sealed class HelloWorldTest : ServerObjectTest { public override async Task Run() { // Create a syncer var syncer = CreateSyncer("default"); //get an ID var helloSOID = Registry.GetId<HelloSO>(); // get reference to helloSO HelloSO helloSO = await syncer.Sync(helloSOID); // Let's tell the SO our name so it can say hello to us. // Note await syncer.SendUpdateWait doesn't return until the SO is updated. await syncer.SendWait(helloSO, new HelloSO.MyNameIs { name = "World" }); // Now let's check to see things went as planned. Assert.That(helloSO.greeting, Is.EqualTo("Hello World") ); } }}
Developing HelloSO
To run the test:
1.Open Test Runner in the Unity Editor by clicking on Window-> General -> TestRunner
.
2.Right Click on HelloWorldTest
inside of Test Runner and select Run
.
3.Observe that the test fails with the message.
System.Exception : You need to register type ServerObjects.HelloSO with the [Register()] attribute
4.Every ServerObject
needs to be registered with a string that allows the system to associate IDs to Server Objects. Let's insert a line to do that on line 7 of HelloSO.cs
so it looks like this:
namespace HelloWorld.SOs{ [Register("hello")] public class HelloSO : ServerObject
5.Now re-run the test and observe the Exception
in the test console:
Syncer.GetServerObject Trying to sync not non-Syncable: hello/wPCpG8wXg99Y-59ZXbUOD3ftuf6EwJCQqBkCy2pvDMQ_ with type HelloSO
This occurs because on line 18 we called this code
await syncer.Sync(helloSOID)
6.Here we are attempting to sync to a HelloSO
. By default, the client can not sync to SOs. Enable this functionality by adding the [Syncable]
attribute to the class, so it now looks like this:
namespace HelloWorld.SOs{ [Syncable] [Register("hello")] public class HelloSO : ServerObject
7.Run the test and observe the Exception:
Expected: "Hello World" But was: "What's your name?"
8.This Exception is being thrown by the NUnit test framework and occurs because we haven't implemented the logic to set greetings yet. Add a Handler
on line 14 of HelloSO
that looks like this:
void Handler(MyNameIs message){ greeting = "Hello " + message.name;}
Now, this line of code from the HelloWorldTest
:
await syncer.SendWait(helloSO, new HelloSO.MyNameIs { name = "World" });
will cause the new SO handler to be triggered and greeting to be updated.
9.Run the test and observe the Exception:
at HelloWorldTests.HelloWorldTest+<Run>d__0.MoveNext () [0x00125] in Assets\Apps\HelloWorld\Editor\HelloWorldTest.cs:25--- End of stack trace from previous location where exception was thrown ---...---Connection 1 open with connect time: 00:00:00.0739987. backlog: 2hello/EtcuCK5qwl...:Method with params ServerObjects.HelloSO+MyNameIs not allowed to handle messages from WSS_CLIENT....
this test still doesn't pass and this line in the list of exceptions tells us why
ServerObjects.HelloSO+MyNameIs not allowed to handle messages from WSS_CLIENT.
It's because, by default, SOs don't handle messages from the client, so our handler was never run. 10. Enable this ability by adding the [FromClient]
attribute to the method. Once you do that, your test will pass and the full class will look like this:
using GPF.ServerObjects;namespace HelloWorld.SOs{ [Syncable] [Register("hello")] public class HelloSO : ServerObject { public string greeting = "What's your name?"; public class MyNameIs : ServerObjectMessage { public string name; } [FromClient] void Handler(MyNameIs message) { greeting = "Hello " + message.name; } public override SOID ID { get; set; } }}
Run the test again and it should turn green.
Deploy SO
ServerObjects
are made to be developed using a mock cloud, until they work, and at which point they should be deployed and ran remotely. In order to demonstrate this, we must now deploy our SOs.
Simply go to the Unity Menu GPF -> Deploy Server
Test SO Remotely
1.Now that the SO is up, switch to remote mode: In the Unity editor, go to GPF -> Settings
and set Backend Type
to Cloud
.
2.Clear the DB: in the Unity editor, go to GPF -> Clear Remote DB
3.Run the unit test again and observe it turn green on the server.
Congratulations! You've just built and deployed a ServerObject.
© 2023 Launch It Labs INC