DOWNLOAD THE SOURCE FOR THIS POST HERE
TL;DR
My
I don't even know where to begin with this post, it'll be a long one I think since I've gone 'round in circles trying to deduce the problem, probably partially due to how difficult it is to get into a networking frame of mind anyway.
So I've got a project I'm working on. Doesn't particularly matter what I'm trying to achieve artistically at this early stage but clicking on the source link at the top of this post should give any casual observer an idea. Right now, all I'm expecting the mod to do is:
1. Let Mario press the Y button in a stationary action to initiate a 'windup' action
2. Let Mario press the Y button again during that 'windup' action to initiate a 'cast' action, or else default back to the vanilla 'idle' action assuming no input
3. Upon entering the 'cast' action, a do-nothing behaviour that looks like a Bob-Omb Buddy should spawn and then subsequently be deleted once Mario is out of any of the custom actions defined in this mod's
Right now, when playing alone in a server, this is exactly what happens as shown below:
However, when at least one other player is present in the server, the logic goes all out of whack:
This disparity between the two linked pieces of footage left me with lots of questions, many I have been doing my own investigation into with little success:
A) What is the topology of the network for this game? I would assume with just how easy it is to host a game that it's peer-to-peer, but I have very little experience with peer-to-peer topology, only star topology for me. Additionally, stuff like the
B) The only way that I am able to effectively tests
C) I'm using a call to
I do apologize if this post was hard to follow, I barely understand how to describe the problems I'm experiencing myself. In an ideal world, I would want all clients to send anything that should be networked as a request to the server and then for the server to have the final say on how that request is handled and then managed until further requests. This way, I can much easier visualize how I'd be able to network my code. Perhaps I can jerry-rig this to be the case with the
Many thanks for reading!
TL;DR
My
.lua
moveset edit has wildly different behaviour between a server with only one player present and a server with multiple players present. I'm quite sure the reason is that I don't understand peer-to-peer network topology very well, but I need a second opinion.I don't even know where to begin with this post, it'll be a long one I think since I've gone 'round in circles trying to deduce the problem, probably partially due to how difficult it is to get into a networking frame of mind anyway.
So I've got a project I'm working on. Doesn't particularly matter what I'm trying to achieve artistically at this early stage but clicking on the source link at the top of this post should give any casual observer an idea. Right now, all I'm expecting the mod to do is:
1. Let Mario press the Y button in a stationary action to initiate a 'windup' action
2. Let Mario press the Y button again during that 'windup' action to initiate a 'cast' action, or else default back to the vanilla 'idle' action assuming no input
3. Upon entering the 'cast' action, a do-nothing behaviour that looks like a Bob-Omb Buddy should spawn and then subsequently be deleted once Mario is out of any of the custom actions defined in this mod's
.lua
files (which is currently an automatic process after ~2 seconds of being in the 'cast' action).Right now, when playing alone in a server, this is exactly what happens as shown below:
However, when at least one other player is present in the server, the logic goes all out of whack:
This disparity between the two linked pieces of footage left me with lots of questions, many I have been doing my own investigation into with little success:
A) What is the topology of the network for this game? I would assume with just how easy it is to host a game that it's peer-to-peer, but I have very little experience with peer-to-peer topology, only star topology for me. Additionally, stuff like the
gPlayerSyncTable
and the level of client access to what I'd consider server functions further suggests a peer-to-peer design. I guess the point of this question is how does syncing work here? If every client is authoritative and Lua is an interpreted language, then surely there's tons of room for not only desyncs but also cheating (not that cheating matters much in a game like this I suppose, but it could easily bend into otherwise malicious behaviour).B) The only way that I am able to effectively tests
.lua
mods for this game is by having at least 2 clients open, one hosting a local server and one joining that local server. Both clients seem to always be listening to input even if they aren't the active window. As such, I'm wondering if half of my issues presented in the 'faulty' of the two pieces of footage above this text is down to execution order and technically receiving 2 inputs per client for every 1 input? It's a little hard to explain my thought process on this, but what I'm trying to say is that because each local client is hooking into the update loop per-Mario, then when I press some input it might be creating an echo effect in that the input happens for all Marios on one client and then again for all Marios on another despite both clients sharing their list of Marios. Would all my problems magically go away if I somehow just found a way to make only one of the two clients listen to inputs at once?C) I'm using a call to
spawn_sync_object()
to spawn the behaviour that looks like a Bob-Omb Buddy. This call is made inside of a call stack hooked into an action, and so it is a call made by clients to let themselves and all other clients know to spawn something. gPlayerSyncTable
cannot store the return
of the spawn_sync_object()
call to itself as a value to some key as the return
type is the Object
class
with gPlayerSyncTable
only being able to sync and therefore store unmanaged
types like int
, float
, bool
, etc.. As such, each Object
spawned by spawn_sync_object()
is tracked locally per-client through my own un-synced table indexed by the MarioState.playerIndex
values of the client's player instances. My concerns here are sort of related to question A about the network topology of this game and not really understanding it. If I'm using spawn_sync_object()
from one client to tell all other clients to spawn some Object
, then why am I seemingly left only with the option to track/manage the existence of the spawned Object
locally per-client? I totally get the limitations as to why I can't just cache the spawned Object
to the gPlayerSyncTable
to make the Object
'belong' to some player, what I don't get is what the alternative to that might be. To me, this'd be a great time for a star-topology network design (assuming that's not already how this works) in which a client could send out a request to the server to spawn some Object
and then the server caches and tracks that Object
which it orders all clients to represent graphically.I do apologize if this post was hard to follow, I barely understand how to describe the problems I'm experiencing myself. In an ideal world, I would want all clients to send anything that should be networked as a request to the server and then for the server to have the final say on how that request is handled and then managed until further requests. This way, I can much easier visualize how I'd be able to network my code. Perhaps I can jerry-rig this to be the case with the
network_send_to()
function sending everything to global player index 0
?Many thanks for reading!