Class selection tutorial for NeoAxis 2.02 dedicated server 





This is a tutorial on how to create a simple class selection for multiplayer. This is not going to be all pretty, but it will work. This was done with Visual Studio C# 2010 Express and 2.02 Unlimited version of Neoaxis. I think Indie version 1.32 might be enough, but you need access to the Client/Server code.

This tutorial does only work, if you use the dedicated server. Playing and hosting yourself does not work. I might fix this later.

First go ahead and edit the MultiplayerLoginWindow.gui in Resource Editor. Add a new DefaultListBox.gui and give it a name "classes"



Next open you MultiplayerLoginwindows.cs in Visual Studio.

At the start of the class add a new variable, that will hold our list of classes.


Control window;
EditBox editBoxUserName;
EditBox editBoxConnectTo;
Button buttonCreateServer;
Button buttonConnect;
ListBox classes; //this one right here


At the bottom of the OnAttach() method we pick up our GUI listbox from window.controls and add few items to it . Girl and Robot.


classes = (ListBox)window.Controls["classes"];
classes.Items.Add("Girl");
classes.Items.Add("Robot");


SetInfo("", false);

}


At this point you can compile and run your game to test out the multiplayer lobby. There should be a list there now with Girl and Robot.



Now we need to transfer our selected class (Girl or Robot) back to the server. Find the piece of code inside Connect_Click() method where the client starts BegingConnect. We will add a new variable to the call BeginConnect that will send our select class with the connection.


string classtype = ((string)classes.SelectedItem) == null ? "Girl": (string)classes.SelectedItem; //get the class from the GUI list or if none selected go with "Girl"

if( !client.BeginConnect( connectToAddress, port, EngineVersionInformation.Version,
userName, password, out error, classtype ) ) //we added our classtype as a new variable to beginconnect
{
Log.Error( error );
DisposeClient();
return;
}


There will be an error telling us that BeginConnect does not take that many variables. That is fine ,since we are going to change that. In NetworkClient.cs change the BeginConnect() to accept one more variable "string classtype"


public bool BeginConnect( string host, int port, string clientVersion, string loginName,
string password, string uid, out string error, string classtype)


and at the end of the method add classtype to the message that is sent to the server



NetOutgoingMessage message = client.CreateMessage();
message.Write( clientVersion );
message.Write( loginName );
message.Write( password );
message.Write(uid);
message.Write(classtype); //this one here


Add a new variable in Networkclient.cs to hold our classtype


public abstract class NetworkClient : NetworkNode
{
string loginName;
string remoteServerName = "";
string classtype = ""; //this one here


Now lets go to the server class and figure out what to do when we receive that information. Open up NetworkServer.cs and the OnUpdate() method



//receive login name and password
string clientVersion = "";
string loginName = "";
string password = "";
string uid = "";
string classtype = ""; //new variable for class

List<string> remoteServices = new List<string>();
try
{
clientVersion = incomingMessage.ReadString();
loginName = incomingMessage.ReadString();
password = incomingMessage.ReadString();
uid = incomingMessage.ReadString();
classtype = incomingMessage.ReadString(); //read our class selection from the client's message


Inside that same method the server creates a NetworkNode and passes loginname and uid to that node. We add our "classtype" to the constructor


connectedNode = new ConnectedNode( this, incomingMessage.SenderConnection, loginName, uid, classtype );


Now we get an error saying that ConnectedNode does not take 5 parameters. Lets add the last one. Select the "ConnectedNode" and right click. Select option "Go to Definition" and you go straight to the method we need to modify. Add a new variable for our class and a public property called PlayerClass


public sealed class ConnectedNode
{
NetworkNode owner;
NetConnection connection;
internal NetworkConnectionStatuses status = NetworkConnectionStatuses.Disconnected;
StatisticsData statistics;
string loginName;
string classtype; //this here




Change the contructor to accept our class variable


internal ConnectedNode( NetworkNode owner, NetConnection connection, string loginName ,string uid, string classtype)
{
this.owner = owner;
this.connection = connection;
this.loginName = loginName;
this.uid = uid;
this.classtype = classtype; //right here
statistics = new StatisticsData( this );

public string PlayerClass // this new property here
{
get { return this.classtype; }
}
}


Recompile Networking and all other parts of the solution. If you get any errors saying BeginConnect does not take x parameters just go ahead and fix all those by adding an empty string "" as the last parameter. In chat-example it does not matter if your class is empty since it is not used.

Almost there. Just one more change in GameWorld.cs and we have a working class selection for multiplayer

In GameWorld.cs in method ServerOrSingle_CreatePlayerUnit() just modify the start of the method like this


string unitTypeName = player.User.ConnectedNode.PlayerClass as string;

if (unitTypeName != null && !player.Bot)
{

if( GameMap.Instance.PlayerUnitType != null )
unitTypeName = GameMap.Instance.PlayerUnitType.Name;

/*else
unitTypeName = "Girl";//"Rabbit";*/

}
else
unitTypeName = player.Name;



And that is it! Recompile and start the dedicated server (+create & load map). Then start Game.exe and connect