Jump to content

Multiplayer coding questions


lorneagle

Recommended Posts

Hey guys,

I've been working on getting my mod to work on multiplayer and since there are very little resources on that topic I have a few questions.

 

isClient() / isServer() 

 

What these methods do is clear, however when I call isClient() in a file that is located in shared it returns false although

the initial call flow was triggered client side. So I execute a UI action located in client and call my reload script located in shared but isClient() returns false.

 

Can anyone give me further information on these two methods?

 

ModData

 

I noticed that if I modify moddata on client side, it will not affect the moddata on server side. Now I looked through the existing code and found:

 

transmitModData() - That sounds like exactly what I need, however it is not available on the HandWeapon object

                                   weapon:transmitModData() - Object tried to call nil

 

player:sendObjectChange('addItem', { item = kit } ) - Seems to send a request to the client to add an item, I'm not sure if every object supports this and what the exact syntax is, can I just call any method on the target remote object with parameters? Can anyone elaborate on this function?

 

Does anyone have another idea how I could sync the modData of an object betwen client and server?

 

My first attempt to use sendClientCommand - process it server side and change the moddata failed to accomplish what I need.

Link to comment
Share on other sites

Soooo since noone answered this I had to figure it out myself. And like a keener, I answer my own question. :) Jjust for reference if someone searches for this in the future

 

First you have to understand what data is stored on the server and what is stored on the client.

 

The server manages all map assets, such as cabinets and the loot in it, zombie corpses on the ground, camp fires, windows, doors, burned ground and so on. As your character moves around the map your client will constantly request map data from the server. The smallest map entity is a GridSquare and it contains all the object that were just mentioned. Whenever you want to interact with something on the server, like turning on a camp fire, you have to communicate with the server.

 

The client stores all the character assets such as his weapon, inventory, XP, skills, condition and so on. So when you move stuff around in your bags you will not communicate with the server. As soon as you drop something on the ground however, the server is notified.

 

The folders

Zomboid mods have three different  lua folders:

  • client 
  • shared
  • server

These folder's purpose is code organisation. Simply putting code into server doesn't mean it is executed on the server and not on the client. In single player for example all code is executed no matter in which folder you placed it. 

 

So what determines if code is executed on the server or client?

 

Usually you hook your code into the existing code using Events:

ZXBmulti = {}--Event handlerZXBmulti.test = function()	print("I was called");end-- Register event handlerEvents.OnWeaponSwing.Add(ZXBmulti.test); 

Now in SP, all these events are fire locally BUT in multiplayer some Events are only fired on the client side while others are only fired on the server. Consequently the event hook you chose determines where your code is executed.

 

Example:

OnWeaponSwing - Is executed on the client

OnWeaponHitCharacter - Is executed on the server
 

So the folders are simply to organize your code, typically

 

  • client

          Put all your UI logic like menus here

  • shared

          Put everything else here

  • server

          Put all your server logic like, what happens when a zombie is hit, here

 

Execute code only if you are client or server or if its a local SP game

 

As I mentioned before: When you play a local game all code is always executed because all events are fired locally.

This can cause problems because you want some of your code to only be executed if you are the client in a multiplayer game, or when you act as a server. To solve this problem IS gave us three helpers:

 

isClient()

 

This returns true if you are the client in a multiplayer game, but false in a local game or if you are the server

 

isServer()

 

This returns true if you are the server in a multiplayer game, but false if you are client or local game

 

getWorld():getGameMode() == "Multiplayer"

 

This returns true if you are in a ... (guess :) )

 

Client Server communication

 

The basic pattern is to use

 

sendClientCommand to send a message to the server

sendServerCommand to send a message to the client

 

These commands will trigger an event on the other side which you can hook you code into

  • OnClientCommand - is triggered on server side when a client command is sent
  • OnServerCommand - is triggered on client side when a server command is sent

Example Client to Server

 

Client

if isClient() then   sendClientCommand(char, "myModule", "myMethod", {foo = "bar", difficulty= "easyPZ"});   end		

Server:

MyClientCommands.OnClientCommand = function(module, command, player, args)	if not isServer() then return end	if module ~= "myModule" then return end;  	if command == "myMethod" then           --dostuff        endendEvents.OnClientCommand.Add(MyClientCommands.OnClientCommand);

For server to client you follow the same pattern but use sendServerCommand an OnServerCommand respectively.

 

Moddata

 

Moddata is a great sink for any data you want to store with an object. Let's say you want to save the currently loaded ammo type with a weapon you'd do something like:

weapon:getModData().loadedAmmo = "NuclearLaserRailProjectile"

However you must be aware that if you modify the moddata of an object client side, it is not modified server side. IS added methods to sync client/server object like sendObjectChange or transmitModData but these methods are not universally supported by every class.

So whenever you modify moddata on client side and rely on it on server side you will have to send a client command and modify it on the server.

 

 

I hope this helps someone understand how to get their mod multiplayer ready in the future

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...