mercredi 28 décembre 2016

Dedicated Server packaging

Dedicated server packaging


I found that Url in the wiki : https://wiki.unrealengine.com/Dedicated_Server_Guide_(Windows_%26_Linux)

But I don't know it is outdated, or I have particular case, but following this, didn't success for me.
So I will give you my way to do, and few tricks, because some configuration steps are necessary and there is no place aggregating those informations.

In my game, I will have one server per map, because each map must be persistent, and is not upon a player.
So I have to generate one server per map.

Tricks & Settings


If you have already launched your game through commandLine like "ue4editor projectName mapName -server/-game", it is quite simple, because you give in parameters the name of your map.
So in your test, you can go map/through map just changing your command line parameters.

When you generate/package your game, it will fix these setting once per package.
First step, you will have to configure under the editor the maps & modes settings.
In these window, you precise which map the client will start with, and which map the server will start with.


Another trick is about package non ue4 files. I manage some configurations files, or data files (json files) in my game to store dialogs, missions, ..., and these files are open by C++ code.
So Ue4editor didn't consider them like assets. In consequence, when you package your game, those directory, and files are not packaging. so bad....
So go to your settings, packaging settings, I recommand to uncheck use pak file in a first time, because you will be happy to see the package content in the first time to validate its content.

Go down, to to Additionnal non assets directories to package, and browse to your directory to add it to your package.


You can refer to the wiki for other steps until unreal front cooking. I don't use unreal Front to package & prepare my game.
I use Ue4editor, through file->package project.

Packaged


At the end of the processus, you will have a directory "game" with WindowNoEditor, with two directories Engine, and yourGame.
Go through yourGame/Binaries/<platform>/ you must find a yourgame.exe, and yourgameserver.exe.
If you don't have your executable, maybe you forget to generate with visual studio (see the step in the wiki).
In certain case, you have to copy the binaries yourself, from your building directory, to your game package.

That's it. I recommand to through a shell script, or command line to launch with "-log" parameters to check that your server & games runs without problem.

I hope it will help people who want to manage dedicated server.

Thyshimrod

mercredi 15 juin 2016

Unity : networking part II

I create a tiny connection screen in a nex scene. This scene has no network, only a canvas to show a background picture, and panel/buttons.
To be exhaustive, I ve created a gameobject named PLayerOverScene I talked about in previous article. I linked to this gameobject, the playerscript script. I will store in it, some information, like the ip asked by the player.


Important field for me, now is IP and connect.
I will not speak about login and password for the moment. I will use a rest repository, I will connect to, to validate user/password in a further article.

As always, I will create a c# script to handle click button on connect : ShimConnection.
I create a single simple function:

 public void checkLogin()

I added the script as component to the button.
I create a onclick event on buttonscript component.


For now, when you click on connect button, you will call checkLogin function.

Travel

Now what you want is to load the game scene, and to link to the networked scene from server.

At connect click, I store the Ip into PlayerOverScene:

GameObject playerOverScene = GameObject.Find("PlayerOverScene");
PlayerScript plScript = playerOverScene.GetComponent<PlayerScript>();
plScript.setIpToGo(IP.text);

First of all, you have to load the new scene (I have only two scenes, so for the moment, I will put hardcoded name of the scene).

     SceneManager.LoadScene("scenes/level1");

The game scene will be loaded... now we have to connect to server.
I Will modify this previous code :
public void Start()
    {
         GameObject playerOverScene = GameObject.Find("PlayerOverScene");
        if (playerOverScene == null)
        {
            bool result =this.StartServer();
        }else
        {
            this.StartClient();
        }   
}

To


public void Start()
    {
         GameObject playerOverScene = GameObject.Find("PlayerOverScene");
        if (playerOverScene == null)
        {
            bool result =this.StartServer();
        }else
        {
           PlayerScript ps = playerOverScene.GetComponent<PlayerScript>();
            if (ps)
            {
                this.networkAddress = ps.getIpToGo();

            }
            this.StartClient();
        }   
}

I grab back the Ip store into playerOverScene object to determine to modify internal variable (networkAdress).
I start client, I am connected (I hope) to the server.

Quite simple...


Next step, I will describe how to spawn the player ship...

jeudi 9 juin 2016

Unity : networking part 1

In the way, to have a dedicated server, and client able to connect to it, you can use standard script from unity. One of them, draw a little hud, where you can choose to launch standalone server, a client, or client hosting server.

Another script is more usefull and manage all events upon network : NetworkManager.

For my purpose, I create my onw c# script, inheriting of networkmanager. I wish to override several events, and function, so it is the best way to do. Its name will be ShimNetworkManager.

As in any script, you have a start and update function. In the start function, I will start a server, or start a client.

When the scene will start, this script must be runned. For this, I will add in my scene, a simple GameObject. I will name it NetworkManager.
I will add as component, my newly ShimNetworkManager script.

For now, as you will launch the game, it will execute automatically this script. But how to know if I am a server, or a client?

From my mind, it will be a server, if the game is loading directly this scene.
If the load of the scene comes from an another scene, it is a player trying to connect to a client. It is my assumption.

Pass GameObject scene to scene


I spent lot of time on this question.
When you load a scene, you destroy the old one, and all object belonging to this scene, even those you have instantiated by a script.
Finally, I discover a trick that allow to pass scene to scene some GameObject. So, to know if this is a client that is loading the scene, I test the existence of this object.

I create a second scene, named authentificationLevel. In this scene, I create a GameObject named PlayerOverScene.
I create a c# script named playerScript which will contain in further articles, the information linked to user (name, id, ....).

To allow to an object to be not destroyed, when you change your scene, you have to code this :

void Awake()
    {
        DontDestroyOnLoad(transform.gameObject);
    }

This line of code save your life.

For now, in all scene you will go, this object will remain, and you have a good way to store game information (score, player information, server information,....).

Back to Networking : Client or Server

In ShimNetworkManager, I can test this PLayerOverScene Object to know if I have to run server or client.
public void Start()
    {
         GameObject playerOverScene = GameObject.Find("PlayerOverScene");
        if (playerOverScene == null)
        {
            bool result =this.StartServer();
        }else
        {
            this.StartClient();
        }   
}








mercredi 8 juin 2016

Unity : Shimstar ; reloaded

OK let's try to create a multiplayer space game with 6 degrees of freedom.

I am not sure to follow the right way to create a game from scratch, I will write articles depending of what I consider to be important to know to create a multiplayer game, with physics.

SkyBox


Because, I like to be in the atmosfear, I ve created a skybox using SpaceScape to grab 6 textures.

I create into a folder, named Materials a new Material called skybox. In the inspector, choose the shader (skybox/6 sided)


Next try to add your 6 images to have in the preview your skybox.

Now you can go to the top menu "Window", and choose lighting, to make your new material effective to your scene :

Modify light configuration, to have an ambient light to light your object into the scene.


Networking in Unity

A game is at first defines by different scene. A player will play into one scene, and can travel scene to another scene.
In a configuration of one server, and multiple client connected, you will have a server running for each scene you will create.
The client will loadLevel and connect to the server it needs.
Server must have authority on physics, and will receive input from client, and broadcast results to all client who needs it.
You don't have a global server which manage a world with subscene. It is important to understand this.
Indeed, you will to manage to connect to a scene, and to disconnect from the scene, to connect to another scene running elsewhere (different IP, or different port).

In Unity, each object of the scene, can have multiple component:
  • mesh
  • material
  • scripts
You can associate as much of script you need, to manage behaviour of the object.
For example, you will have 3 scripts:
  • network identity : standard unity script which provide an unique network identity
  • network transform : standard unity script which manage the data transfer of position and rotation of the object
  • your behaviour script : custom script, with your specific fields, and function to manage custom behaviour
Unity will manage network behaviour on object possessing networking script.

Next Step


I will try to describe enough in details the different mechanism, during construction of the game.

I will show you how to manage a connection scene, and connect to a server.

After that, I will show you how to manage physics through networking.







mardi 26 avril 2016

ShimStar : Poc Unity

I made a poc with ue4, and it appears that, from my mind, ue4 is a great tool.
But it is heavy... and for my purpose, I wonder if it is not something to huge to use, for such a game I am doing.
The editor runs down my laptop, compilation time from C++ is very long, and there is a huge orientation to character use, and fps.
But the community is very good, and it was a pleasure to work with such people.

I am trying for weeks unity, and my first opinion is it less matur, not totally finished, UI is not so good, and community is not very good. I think there are lot of amateur, and it is hard to have good answer, and when I ask about technical stuff it is quiet hard to have answer.
But unity is liter, but powerfull... and for the moment, I can reproduce lot of thing from ue4 in unity, and an easier way.

I think you have to program more, but it is c# so more convenient, and faster to compile and to test.

For the moment, I am trying, and see what I can do, and I will try to find the limit... but I am quite happy of unity.

I repeat, UE4 is wonderfull... just too much heavy for me:p

jeudi 18 février 2016

ue4 : AI in a space game : relative coordinate : part 1

I will make some articles about AI I am building.
I will not use for the moment, tooling set in ue, because I will not have change of behaviour (attack, defense, patrol).
I will for the moment make only one behaviour, and one goal to reach, without modification depending of the situation of the AI.

My goal is to put in space 2 cubes, and to spawn an AI pawn controlled by an AI controller.
The AI will retrieve first cube, and will fly to this one. It will shoot at it, destroy it, next it will change of target, and fire on the second one.

I ve created a pawn, with a static mesh, with physic enabled.
Don't forget to precise that the pawn is possessed by your specific AIController blueprint:





For my purpose, one of the central need I have, it to be able to orient my pawn to my target.

In AIController,  I ve defined a variable TargetToGo
and create a function to associate a value to the target


I retrieve all object in the scene which are from class gopoint (my cubes, there are two of them). If actual targetToGo is different of the one retrieve in foreach loop, I affect it, and break the loop.
Quite simple.

Ok, for now, I have a target for my pawn... The difficulty is to know how to orient my ship to the target, to move near it, and shoot at it.

Ue4 gives possibilities through transformation tools, to make world location, in local location relative to the ship.

From my pawn, and target, I retrieve static mesh.
From AI ship, I create a transform object (world transform) and I connect it to an inverse transform location object. This last one is the way to make world location into relative location (transform location does the inverse, relative to world).
In parameter, you give actual world location of the target, and you will have a vector in output.




Now, if you break the vector, y which is a left/right coordinate, and z a up/down coordinate. When z and y are at 0, target must be in front of you.
X value in case of y and z at 0 will be the distance to the target.
X can give you clue, if your spaceship is going to, or going away of. If x is equal to - (distance), you are going away from the target.

You have to make rotation, to make x near from distance, and then re apply torque to reduce y and z to 0





dimanche 14 février 2016

Third Party server with UE4 : part 4 : C++ : thread

UE brings you what you need to thread your program.

class POCSHIM_API UShimServer : public FRunnable

just extend the interface FRunnable, you will have to implement
    virtual bool Init();
    virtual uint32 Run();
    virtual void Stop();

Run will be the function which will be threaded, so you can put a while (1), with a break condition, mutex, and so on into.

I ve created a singleton in shimserver

in shimserver.h:
static UShimServer* getInstance();

static UShimServer *instance;


in shimserver.cpp
UShimServer*  UShimServer::getInstance() {
    if (!UShimServer::instance) {
        UShimServer::instance = new UShimServer();
    }
    return UShimServer::instance;
}

UShimServer* UShimServer::instance = nullptr;


In myGameInstance class, I ve created an intialize function, which retrieve the singleton of shimserver, and from it create and launch the thread.
once you create the thread, it will run automatically init on instance, and run().