#archived-networking
1 messages ยท Page 92 of 1
If the master leaves, another client gets picked and is told it is the MasterClient... and then it takes over controlling room objects.
Host Migration is a mess with ServerAuthority, because everyone has to reconnect to a new server and try to get back into sync.
With relay, everyone already knows the state of everything. All that changes is who has "authority"
Again, there is no hosting in Pun2
There is a room, which is just an lightweight instance that is created on a PhotonEngine server
so basically, all of the clients has the all of the information about the game room, but only one controls the general events and actions int he server
Everyone connects to that room, and they start transmitting data about the things that they have authority over to other players.
If I join a room and spawn a player, I own my player object. I can move it around, and I send that objects state to others. They all do the same.
If I leave, my objects get destroyed for everyone.
Room objects - objects not owned by anyone in particular are the responsibility of whoever has the MasterClient flag to control.
damn, i completely missunderstood everything about it
Master client can change hands at any time, by your choice, or by the old Master dropping.
it all seems extremely clear right now.
Yup, its pretty basic once you get the concept.
you check IsMine... if true... you control it.
i never thought about such a server mechanic, god damn genius
It has very real limitations of course.
Server authority is out the window
But pun2 is mainly for casual lower player count, short lived room based games.
If your game falls into that category, it is very pleasant.
yeah, once i understood i can now see the flaws, but my game has nothing to do with server authority, it is perfect
If you try to make it do something outside of that box, it gets more complicated.
the more i think about it, the more it fits. perfect
thank you so much
and here i am trying to implement AWS GameLift.
NP, there is a photonengine discord as well
I would paste the link here, but it isn't allowed
thanks i will check it out. i just went back to where i left of with photon. now it all makes sense
This feels like such a basic question, but I'm following along with some photon pun tutorials and whenever I go to set the players nickname or the playername it kicks back a NullReferenceException saying that the object reference not set to an instance of an obj..
@crimson mirage Where is the null coming from? Your or PUN's code?
puns code
PhotonNetwork.NickName = name.text;
that line is giving me an error
in the videos I'm watching it shows PhotonNetwork.playerName = "bob"; or what not
setting it to just a raw value like "bob" gives me the same result
Stepping into it to find out what is null might give a clue
Maybe PhotonNetwork.player is null because you haven't connected yet or something
I think you just call PhotonNetwork.ConnectUsingSettings() and it handles it for you. This should be covered in the documentation
I've done that already
void Start()
{
PhotonNetwork.ConnectUsingSettings();
PhotonNetwork.ConnectToRegion("eu");
}
public void CreateRoom()
{
string tempCode = "";
for(int i = 0; i < 5; i++)
{
tempCode += alphabet[Random.Range(0, alphabet.Length)];
}
joinCode = tempCode;
PhotonNetwork.CreateRoom(joinCode);
}
public override void OnCreatedRoom()
{
//This line underneath is giving me an error
PhotonNetwork.NickName = name.text;
joinAttempts = 0;
GameObject.FindGameObjectWithTag("MainMenu").SetActive(false);
if (joinCodeTxt != null) { joinCodeTxt.text = joinCode; }
Debug.Log("Created room: " + PhotonNetwork.CurrentRoom.Name);
start.SetActive(true);
}
public override void OnCreateRoomFailed(short returnCode, string message)
{
joinAttempts += 1;
if(joinAttempts >= 3)
{
Debug.Log("ERROR");
}
else { CreateRoom(); }
Debug.Log(joinCode + " already exists");
}```
this is a section of my code
Did you confirm what is null?
Hi Everyone. So I have been opening 2 different instances of my game, and when I create a room in one instance, it doesn't list on the other. I set some print debugs to show if the OnRoomListUpdate function would run, but it seems that it isn't. How do I debug this? Many thanks!
Hey guys, I want to make a simple main menu and lobby for my game. I imagine that I should put both in a separate scene. This means that I need a way of maintaining connections and their details once the game is started and loaded.
Does anyone have experience with this? Is having a network manager that I DontDestroyOnLoad or smt the standard approach?
Hi! If I just need to connect 2 players like in a 1v1 multiplayer turn-based game what should I use and where to start?
I've been walking this path for the past week @acoustic spade haha
If you want to write the solution yourslef try tom weiland's tutorials on youtube
I tried to follow this but I ended up doing smt pretty different because I wanted to make greater use of async https://16bpp.net/tutorials/csharp-networking/04e/
thanks @cloud orbit
np, let me know if you get anywhere our code will probably be similar
I got a basic connection working. Trying to set up some kind of a lobby before I work on the meat of syncing both clients
@mellow sapphire First I would confirm that the clients are on the same region. There should be a development region setting in the PUN settings that should help with this
So I am having this weird problem that when I load into a game the playercontrollers are inverted like I see through one cam but than control a different player.
can some 1 pls help meee
plszzz
how do u detect when a client has left the server in mirror
Hey guys I am making a server host system with mirror but whenever i create a match on the client its name will be "default" which is the default value for the inputfield im using and it only works on the host. Anyone that could help me out?? Thanks!
Thanks @spring crane , gonna try that
Back at it again with dem white vans
@spring crane Didn't work =/
Any other tips?
Hello Network engineers. If anyone is in need of a good lock-less queue or two, look no further!
https://github.com/DennisCorvers/Lockless-Queue
Happy developing everyone!
@prime stag Yea you are likely mismanaging your camera(s). Make sure your camera only targets the local player. Might be helpful in general to separate camera from the player object
@mellow sapphire Make sure that the region thing is not an issue by logging the current region. First step is to figure out what is wrong, then figure out what fixes to try.
Revisiting the doc and checking the examples might be helpful
Not sure if you had to toggle or request lobby changes.
@gleaming prawn During clientside reconciliation, about how many steps should I be re-simulating? Is 20-30 too much? Obviously I don't have much control over this since it's just whenever the client gets the packet from the server
But my fps appears to spike during this, profiler shows that physics.simulate() is the cause of this. I feel like I'm doing something wrong
That's even on LAN, over a real network I feel like It's going to be much more
Other question: How often on average (based on what you've seen) does it take for player and server physics to drift apart during continuous movement (so that reconciliation needs to be called)? Couple seconds? Minutes? (It's hard for me to test this because my client/server run on the same machine)
@spring crane how to do i do this.
Straightforward way to handle this would probably be to attach a component on network spawnable objects that can be targeted by the camera. That component would then somehow notify the camera when a new camera target is available. NetworkIdentity on that spawnable object has hasAuthority and isLocalPlayer.
Okay someone just told me to spread out the physics.simulate events over multiple frames. That will probably help.
That is ramping up the complexity, for what is a band-aid to the real problem. Your simulation is either too expensive, or something is breaking sync more than it should, or some combination of those two. Either way if you are hitting a wall already on your testing platform, its only going to get worse as the game gets more complicated and when it is run on lesser computers.
@jade glacier The simulation is done in another scene and is literally a flat plane on the ground, with a rigidbody cylinder getting moved with .velocity
so definitely not expensive at all
Sounds like something else is going terribly wrong then
I looked in the profiler and it literally shows the frame taking 20ms because of the physics simulations
How many resims is it doing in one update?
isn't that how reconciliation of physics works?
Lan at worst would be a couple frames difference between server and client
Player gets teleported back to server's last known spot, then he runs through all of the client predictions from that timeframe, up until the present
you literally need to call simulation like 30 times for that to work
Why though? Are you doing a replay or something?
Yes. My client needs to sync with the server somehow
it's authoritative
and the client has prediction
Totally lost me again
for prediction on lan, you would be resimulating a few frames tops.
No, because the server is still very behind physics-wise
how my server works is: it literally stacks the player movement actions up on a queue
and executes one for every player
on fixedupdate
There is something about your setup that isn't typical, because none of that lines up with normal.
This is for client prediction?
Yes
Normal client prediction, like what most games do?
Then nothing you are saying adds up sorry
Okay so the client and server both work with physx. Physx is non deterministic, so over time their movements will separate
correct?
The client needs a way to re-sync with the server
Step one is make your thing work without prediction... you send commands to the server, and the server applies them on the tick. The server then sends everyone the state results.
that all works
Should be a tiny amount of lag is all
Let me try to get a video for you
Step 2, you add in client prediciton... the client rather than waiting for state from the server, is allowed to simulate the tick. You store the state result.
Step 3: You compare the states as they arrive from the server with what you had gotten for those ticks on the predicting client. If they don't match, you go back to that frame where they disagree... reset the scene to the SERVER state values, and then resimulate forward.
The number of frames involved there should only be a few ticks.
how do you end up resimulating 20 ticks for a lan game?
I have no clue
It sounds like your server and client are WAY out of alignment
Sounds like your tick management has a serious bug
You are numbering your ticks I assume, and you can tell how large your buffer is at any given moment?
Yep
And you are seeing a buffer of 20 ticks?
Are you making any adjustments to get that corrected?
here is the multiplayer
on the client, yes, I'm trying to make an adjustment
the reconciliation
oh you mean the large buffer
yeah I have no clue what thats caused by
yes, you can't move on until you have your tick buffers being managed correctly
Having 20 ticks of buffer is insane. Fix that.
I have no clue where to even start
when the server sends the update packet to the client, its literally of THAT client's state
when it's sent
You made your buffer system, only you know the answer. What was your plan for it?
my plan was to spread the physics.simulate over multiple frames like another guy is doing
because after simulation, it's the correct value
I've tested it
but yeah I think I did my server wrong
I'm kind of at a loss, you are skipping over major core parts of a tick engine and then slapping on wacky band-aids
if your client and server aren't nearly on the same tick on lan, you need a way to adjust your buffer sizes
Being that far off means your initial offset guess is way off.
And that it stays that bloated means you have no mechanism for growing/shrinking the client buffer as needed
Go back to Step 1: Pure server authority with no prediction.
That should be nearly in sync on lan, with just a small amount of latency
So wait, the server runs an automatic simulation each fixedupdate right?
and it should be 0.02?
This tick system is confusing me so much
It is your tick system, I would hope it isn't confusing to you? LOL
No I never really understood it, and just built it in a way which I understood
which apparently is wrong
yeah, it's ok to go back and try again. i'm on my third iteration and it's looking like i'll need another
If things get beyond your understanding, don't keep pushing more bad code on top of it.
Start with Step 1. No prediciton.
alright
Then number your ticks
In the mean time though, I seriously need you to explain to me how the ticks work on the serverside, because clearly I'm not getting it
but ill go remove the prediction one sec
Player sends server inputs for tick 22 ... server stores that in its buffer... server applies that on the next aligned simulate for that tick, gets the state results, and sends that to the client with the tick number.
Store those server states in a ring buffer, and consume those on the fixed.
exactly.
So next step is to make sure that is working correctly
You should be getting back a tick state shortly after sending out your tick inputs.
autosim is fine for now, but generally you want to run it yourself so you can have a postPhysX callback
alright
Get to a point where you have a numbered input buffer, and numbered predicted state buffer, and a numbered server state buffer on the player's client.
The player stores its input and predicted state values for each tick.
And it stores incoming states from the server.
I'm at the point where I have a numbered input buffer and I've already tested it, the client/server are completely synced on that end
"synced"?
they have the same values for each number
The states come back from the server in agreement with your local predicted states?
Not like misaligned by a tick?
Then all you should be doing is testing when a server state comes in, to see if it agrees with your stored predicted state.
How many ticks behind your current player state are the server states numbers? It should only take few ticks for the server states to come back after you send out your input tick.
So when the server tick comes in, it's say 130, and the client is already at 150
that's the gap I'm working with
Then your buffers need aligning
alright
Because that is massive latency
thought so
You need to be measuring your buffers. Why is the server holding on to some 20 ticks of inputs before simulating?
And how did it get started so far out of alignment?
I think because they're still waiting to be processed inside the input queue
since it only does one input per fixedupdate
waiting for what though?
This is our buffer management that you have to do. They aren't going to magically consume all that buffer if they are both ticking at the same rate.
You have to 1) not start with a bad value like you are for the offset and 2) have the client speed up and slow down as needed to get the servers buffer right
For lan though, you shouldn't even need #2 yet. Your initial offset is just bad it sounds like.
Not sure what you mean by initial offset
Not sure how else to explain it. You wrote the code - so only you know why things are starting off with a 20 tick input buffer.
alright
Normally you would just offset that incoming input by 2 or 3 ticks, so it gets consumed within a couple fixed updates.
Something about your initial alignment has you not consuming that input for a massive number of ticks.
@slow monolith PhysX is very far from ideal for networking, but if you have very few rigidbodies in your scene you should be able to run Physics.Simulate a lot before your sim would hang. This is like 1000 rigidbodies w/ 10 ticks rollback every confirmed tick at 60hz, does get choppy when they all settle, but you get the idea.
@floral turtle Awesome thanks
So as for the other question I had, about how long can you go before you need a rollback
like do the physics stay relatively synced on different hardware? I know physx is non deterministic, but I've heard a few people say they only need rollbacks every so often, not every tick
you will diverge for differences in how floats are handled on different platforms or between cpu vendors. You will also diverge as PhysX contains internal data not accessible from Unity that affects the outcome of the simulation
alright
example running a sim twice, with snapshots to restore the state of the sim every 60 ticks https://gfycat.com/fondbeneficialcuckoo
can see large pops after impact
@jade glacier You were right, there were a bunch of garbage ticks getting created beforehand on the server
movement on the client/server is basically 1:1 now, virtually no delay
You will need to make that more adaptive later, to account for latency and jitter
@jade glacier I'm getting a difference of 4 ticks now, on my LAN connection
is that still too high?
Depends on what your tick rate is, what your buffers consist of and if you want that much buffering. But that might be a tad high for a lan connect. Lan isn't realistic anyway. You will want to play with that later with a network simulation going.
tick rate is 60hz
the server and client are literally running both on my machine at once
@floral turtle Is a 4 tick difference too much for LAN?
everything emot said is right on. But if you want to know for certain you can test just sending messages with whatever your transport is to see RTT. Good to have debugging tools ahead of time anyways
alright
@floral turtle @jade glacier Realistically what value should I be aiming for on LAN on 60hz?
1? Cant seem to get below 4 no matter what I do, besides upping the tick rate
I'm also having this extremely weird bug where I'll be getting 4 ticks for every re-sim, and then I open the profiler and it jumps up to 20
Hi. I used to use php for some file upload and sql query
But now im making webgl, and using javascript instead of php. How does things work now?
Cmiiw.
Unity webrequest, post
To a jslib
Jslib makes sql query?
Then the result is passed as result in the unity webrequest? Is this string only or can it be object?
Wait do I have to thread the sending of UDP messages? Will it fuck shit up if I dont?
Right now I only have threading of receiving the messages
Hi guys! Is there any reason I can't uncheck Interpolated Client and Predicted Client from a PhysicsColliderComponent in the Ghost Authoring Component?
I am thinking of how to store player data on the database. When it's about currency it's easy: two or more entries, fine. However, storing items give me a stroke, because I can't imagine a database having a mountain of entries for the quantity of each item. I thought to store in a separate entry a name of the textfile to store this data in a simple manner, but I don't know if it's the best solution. Could someone give me an advice on that?
"I can't imagine a database having a mountain of entries for the quantity of each item"
Why not?
It looks like a nightmare when you are updating a game and add some new items, and you have to add a new entry for each registered player
Or maybe it's just a typical solution around this, hell I know
"and you have to add a new entry for each registered player"
Why though? @frosty coral
Why would you add such an entry if they don't have the new item?
Doesn't make much sense to put an entry in there with quantity 0 now does it?
Ok, but for some reason putting the player data (hashed nicknames and hashed passwords) and currency along with all the items seems inelegant
Yes, because it is
And why would you hash a nickname/username?
Player <-> PlayerItems <-> Items
That's how it should look, as basic as possible
to make it harder for a potential attacker to look for a target
ok cool, but when hijacked the database will spit the entry with a searched username right away
if hashed then attacker has to spend more resources to break through it
Yeah, or I just find some rich players username, hash it and I get the entry anyway
if you have the function of course
Hashing passwords works because one person and one only knows the password
Mate
You're not suggesting security through obscurity are you?
And you do understand that you can simply try a whole lot of hashing algo's to find out which one is used?
Or... you know... just look in the code?
let's cut it here, because it leads to nowhere. nicknames are not to be hashed
That's not what you came for anyway
correct
also, something has bothered my mind as well. How are rapidly changing values, such as ammo count, handled in multiplayer?
I mean ammo not as in one match or something, but for an account
Depends on the game
Many match-based games only save data after the match
Other games save on an interval (say, 5 minutes)
Calling a database each time seems insane, but letting the clients do this job instead seems insecure and unreliable
Some games save when something "important" happens
A database should never ever have access to the internet
i know
But server has to know these values all the time, regardless if the client has disconnected or not, cuz in interval variant it would create exploits, such as unlimited resources when someone knows when to disconnect
Interval can't create exploits, because the server keeps track
What are you going to exploit by disconnecting early?
The server still has the clients' state
that would mean that server has an access to all the client's variables all the time
or maybe it is, i'm just a newborn in game networking
If you want to ensure validity of data, that is indeed the case
so to clear this up: the server can access the clients' variables at any time, but intervals decide when to do so?
what if the client session is lost? or can it be preserved until the next update?
No, the server normally handles the clients data in the first place, and broadcasts it to other players
If a player in a game like Halo shoots his gun, he also shoots on the server
On both the client and the server, the same amount of ammunition is known (assuming no desycns atc)
So in my fixedupdate(), whenever a fixedupdate occurs, it writes the user's current input to a list, this happens 50 times per second. My client however sends packets 60 times per second, and it sends everything in the fixedupdate list and then wipes the list afterwards
is this the correct way to go about things? Since sometimes my client sends a packet with 2 fixedupdate intructions inside of it
This causes the player's input queue on the server to have an average max size of 3, which is why I'm receiving a tick difference of 4 on the client
I just don't know how else to go about this
should I just be sending a packet on the client to the server AS SOON as fixedupdate ends?
That confuses me because it would probably work, but I wouldn't be sending at 60hz
i have a rather long question, about MIRROR. I have been researching but i wasn't able to find a detailed answer. or similar issue.
So, i am working on a moba like game that is highly depended on physics. So i when i cast a spell, I want it to be controlled on the server rather then the caster.
But at the moment i cannot cast the spells in the clients because they crash due to the Variable being null that has been set by a ScriptableObject.
So i have a few question.
1- do i actually need to put [Server] on all functions on Ability to make sure the ability is completely handled by the server.
2- if i do like this, how can i handle Force and Damage apply to the collided players? i think for damage, all i need to do is to keep the values as SyncVar, i am not there yet. but what about force.
and 3- the most important one.
when the TriggerAbility method is sent to the server by the client, The values that are assigned by the ScriptableObjects are null. I have tried using syncVar but couldn't make it work.
I am sorry, this has turned into a Forum type question.
Have the client send its input at whatever its tick rate is. If both the client and server are ticking at 50Hz, just have the client send at 50Hz. There's little point in sending more frequently except for redundancy.
You do still want some kind of redundancy later on to mitigate packet loss, but it's done a bit differently than what you're currently doing.
On the client, keep track of the latest tick it has received from the server. After the client reconciles, it can safely toss any input from or older than that tick. After each FixedUpdate(), the client sends its input for all ticks it's predicted that are later than this latest acknowledged tick. Since each button is 1 bit and aim is 16 bytes, you should be able to cram a lot of them into one packet.
On the server, you just have to drop old and duplicated inputs and sort the incoming queue (if any inputs arrive out-of-order).
Hi guys I was planning to develop a simple mobile multiplayer game but I am still learning how to use Unity.
My plan would be to first make the game offline and then use PUN to make it multiplayer, is it OK to do it this way or should I just start learning game networking and start developing the game with multiplayer in mind?
I need opinions from experienced people as I am not. Thank you.
i am also new to unity, but i am trying to implement multiplayer for a week now. and based on this experience, i recommend you to start building as it's multiplayer. because later you will need to make lots of implementations to your script, and i would be easier to turn it to singleplayer later.
@dense hedge The physics for the client and server is 50hz (default for unity), so should my network be ticking at 50hz?
instead of 60hz?
Why bother having the client send input at a faster rate than it actually produces new inputs?
@jade glacier @floral turtle Alright last question, so my networking stuff all happens on a different thread which is no problem, I just queue it up and receive it on the main thread. The problem is, however, I have to poll in update() to receive the queue contents on the main thread, and 100fps doesn't seem to be receiving it fast enough because 200fps gives me less of a tick difference, I just don't think every client is always going to be able to get above 100fps
So is there like an async blocking queue I could use on the main thread instead of having to poll the queue?
@midnight bane in general for a moba i would suggest to follow the server authoritative workflow.
If you use syncvars you can use hooks to decide who can update the syncvars by referring to the method.
The method itself can be either server or client
In an authoritative design you let do the server most and only sync back the results to clients
so methods that are called to a server are not results but rather asking the server to run a certain kind of logic
in return the server send the result back to all clients or a specific client
that is what i want to do, because i think it would be easier to sync all those physics to the clients
on that point idk, probably best to ask emotitron or Roystan next time they're online
alright
i want to keep everything on the server except players, so the abilities would handle themselves, can even collide with it's own caster...
but i can't get the clients to spawn the prefabs of the scriptable objects
you should not sync physics over the network but rather end results and use lerp between intervals to reduce data.
i have found out that there are methods called network reader and writer but i can't get them to work either
why not make the scriptable object part of a gameobject and spawn that instead?
or just load them in during runtime
i have been making researches so, i assume i can write client side prediction to cover it
with corrections
AbilityInfo : ScriptableObject > https://hatebin.com/qufvkfwykl
AbilityTrigger : NetworkBehaviour > https://hatebin.com/kogsyatouk
Firaball : AbilityBehaviour > https://hatebin.com/fksawgkhmo
AbilityHebaviour : NetworkBehaviour > https://hatebin.com/zsmsyfvetr
scritable objects are nothing else as datacontainers
yeah but tit contains the prefab and spirte or audioclip
of the ability
and it doesn't let me send those over the network
you could make a object in you game that has alist of all those object and pick the one you need
every object that you want to sync or spawn needs a network identity
it has network identity
the problem i have it when the client tries to spawn the object in TriggerAbility script
thats a scriptable object, its not a gameobject
all of the variables are null
it's in a game obj
what i normally do is to get a copy of this into player's skillbar
when cast
in TriggerAbility script that i post link above
i clone it
spawn it's prefab
and rest of it is on the ability's own script where it add forces on self and stuff
yeah i did
but i couldn't get networkreader and writer
work
at the end of the page
it looks exactly like what i need but i couldn't figure it out, and i have been researching for a few hours now
NetworkWriter writer = new NetworkWriter();
AbilitySerializer.WriteAbility(writer, this);
i have tried writing like this in scriptable Object's instantiate method
but couldn't read if in [Command]SpawnAbility method
and not just this, as it says, Vector3 can be send through network
but those values are also null
when i send it from client
are all those abilties in your list prefabs or just gameobjects?
they are all scriptableobjects' instances
and all of them are also networked?
they also hold the prefab of the ability, so i only carry around the instance of SO
yes
why you dont make those scriptable object not part of the scene itself so they are all available for all clients and the server and just only make a callback so the server tells the client which one they are currently use
they are not part of the scene tho
you only need a reference to them in that case and not need to network it all
so, my game has ability shop,
so i put all abilities in the list to the shop,
when a player buys it
i instantiate a clone of the ability to player's skillset
why?
then when casted, i instantiate a clone of the ability's prefab
you should only sync the data and let the server decide what abilities each player has access to
because i want to apply different buffs or debuffs based of items or character status to the abilities
so i need a clone of the ability for each player
otherwise i would need to modify everything when the ability is cast
instead i am just changing the values of the clone in the player's skillset
you should not spawn and despawn to much, it will make it worse, its the same as with bullets, you should have most stuff preloaded and just use a design like a pool manager
the only data you sync is just the simple data that says what you bought by a simple ID, the rest of the skills the player cant use if the server does not send the ID
I only use spawning in most cases for players itself, the rest is either already in scene and use use server client logic to decide what be used when, where and by whom.
If i dont use object i disable their renderer and add them to a pool list
the server controls those items
so i should keep an ID for each ability or item, and instead of having clones of those in the player's local, i should have a list of IDs. When notify the server with the action and the id that represent the scriptableobject or prefab ?
what you think is less traffic sending everytime a enire data object or just a simple int ? ๐
yes it makes sense
reduce date improve prefomance and reduce lag
would be easier, and ii wouldn't have this problem where i need to send the scriptable object over the network
but i am still in the fence.
scriptable object i use for static data
i don't get which of the object or prefabs i created are on server
like alevel layout
and which are not
you load the enitre scriptable object into each scene server and client and make a reference to it
you only make the server logic that can choose what data the client shoudl use from it
and then forward that to the deisred client
the client just takes the data out of the same local scriptable object
the client itself cannot change the value of the ID itself only server can do
so you need to make a call back for a client to request a change if need via a Command
the server can send back via a clientrpc
so you have in general 2 steps
the tags [server] and [client] means those can only be called by one of them bit those dont do syncs over the network, dont get confused with those
those tags only say who can run this code, it does not sync it for hose you need the commands and clientrpc
E.G.
that is good to know
It sound confusing but thats how it is
i am having trouble following the logic
it is simple [server] only a server can execute the method
i mean it makes sense
no i mean the top part not [server] [client]
i have all those objects in both server and client
and i just send id and what to do with command and rpcs
it makes sense, and sounds easy actually. but when i think about everything that needs to be done this way i am lost
for example
can you just check these 2 ?
Firaball : AbilityBehaviour > https://hatebin.com/fksawgkhmo
AbilityHebaviour : NetworkBehaviour > https://hatebin.com/zsmsyfvetr
not all of it
i made all methods [Server]
:P
thoise are only run on server, client cant run those
because i my mind i thought that makes it, handled completely on serve
r
i don't want any player to have access to it
unless they get hit by one which than applies force to the player which player still doesn't have any access to it
why not tho
becuase they are not clientRPC
oh i see
only the server will have the changed data
so for the functions that should send information to the client
[server]amd[client] only filter who can execute that code
i should to have [server][clientrps]
you need [command] and [clientrpc] to sync the data
comaand is from a client to server to ask for execute some logic
the server does the logic and as result at the end you let the server run a client rpc
cmd > spawn fireball then fireball > server + clientrpc wouldn't it be like this ? since fireball is a go in hierarchy
see the command as a request for the server to do something liek spawn fireball
yes
the server then does server logic itself to see if you can etc etc
it thats true you let the server spawn it
depending on your need you can run the rpc on a specific client or all clients
for example a syncvar can be on a player like HP and synvars only autosync on datachange , you can let the server send a client rpc to that specific client to change the syncvar value and the synvar itself will then sync with others
in that way you prevent a client to be able to change a synvar
just as an example
yeah i understand this
but when you say that the script wouldn't sync with players
what does it mean ?
i have networkrigidbody and networktransform, and an abilities script is mostly about, what happens in collision or how he projectile behaves like, follow a target, or bounce from a target to another.
so player's unless it hit them, do they need to get synced with anything other than transform
[server][client] does not sync, it only says who can execute it.
then you use [server]
those methods can never be called on a client
private void FollowTarget(Transform target)
{
Debug.Log(target);
var vectorialPos = new Vector3(target.position.x - rigidbody.transform.position.x,
0,
target.position.z - rigidbody.transform.position.z);
rigidbody.AddForce(vectorialPos.normalized, ForceMode.Impulse);
}
where another method keeps getting the nearest enemy as target
so the ability slowly follows the target
if i don't sync this with clients
would there be a problem ?
the ability is under full authority of server, and all players need to see is it's location right ?
if this callback is server only
then the result is server only too
client will not run rigidbody.AddForce(vectorialPos.normalized, ForceMode.Impulse);
so you should instead add that one a client rpc
it sends the same force value to the clients
doesn't it basically clientrpc the rigidbody methods ?
the client rpc icallback itself on client will only have the rigidbody.AddForce(vectorialPos.normalized, ForceMode.Impulse);
as the vector calcualtion is already done on the server
the vector 3 data you send into the client rpc to the client and that value will be used then
RPC systems will either make your development a lot easier, or a lot harder ๐
haha yeah its pretty easy if you get it
you need to write more steps of methods and split things up compared to non multiplayer game
i bet, but even though i understand what it is basically, i am still not sure how to use it in the project efficiently. it doesn't fit very well in my mind
YET
i always aply the rule of dynamic and static data and additional deterministic reults
if its dynamic i moslty need to sync
if static i dont
my priority is learning unity, not the game. so i take it slow as i understand i move on, so i will try till i figure it out. i am not worried
if deterministic i could let the client just run it
yeah i got this part, and it makes total sense
let me give you an example
k
The vyvanse is strong with this one
this a game im developing
the snake grows every time and also shrinks, i dont sync every gameobject
is this snake on vr nice
which is vector3 as pos
the rest of body parts simple follow code logic as they follow the head they are predictable
also the food dots are not networked
i let the server spawn them on each client via and client rpc
wait wut
i also use client rpc to diable or destroy objects
@midnight bane, I can highly recommend the book "Multiplayer Game Programming" by Glazer and Madhav.
if server is spawning and lets clients know their position
how are they not networked
i either take object form a pool manager or just use local instantiate ๐
i will check it out
wouldn't it make the foods, different for each client ? so they can't eat or collect other's food
you need to see it like this i just let the server say to the client that it need to instatite a object at a position
which removes the competition, well i am not sure about your game's objective so , just guessing
the server tells all client to do the same local instatiate
the client does that becuase the server tells them to do
if the snake hits a food it does a command to the server
and when eaten, cmd destroy this food > clientrpc, local destroy this ??
the server checks if that player realy hits it
if yes it does the logic and send the related client rpc to remove that one on all clients
yeah got it, also makes sense
`OntriggerEnter(){
CmdEatfood();
}
[command]
CmdEatfood(){}`
@midnight bane you only need to think about data results if you do networking, i think that is the easiest way to learn it.
it is just about sync data, you dont realy sync objects and use proper code design to make the flow easier and reduce data traffic
there is not really a golden concept as each game requires different things
But if you can let a server tell the client what to do only that amount of data is very small rather then syncing every piece of data
yeah, i got what you mean, i am still fuzzy about how to handle clientrpc, but i will figure it out when i get there.
but i think for now the first thing i should do is to alter my could so i can sync things easier.
like animations, you only let a server send an animation status not every possible vector 3d as it does not really matter its not 100% in sync, players dont see that
yeah i was just gonna ask this
atm
in general critical data should be done by server
yeah i like that style all small specific scripts
command has user inputs
its easier to make it networked
movement has the objects movement mechanism with rigidbody
that one should mostly have client rpc's
but from what you say, i feel like
i need to handle some of these
on server only
or wut
the part after here
confused me a little bit again :P
a command is just like i want to move up, then server look if you can and send a client rpc to the movement manager to do the move for that player;
so command script should be run by server mostly
the way it works for me , command sets a destination point and changes player's task to running
and in movement ,if player task is running it move towards to the destination
Join our Discord: http://discord.shrinewars.com
Patreon: https://www.patreon.com/shrinewars
In this video, we'll look at the features Mirror provides to synchronize data across clients/server for a multiplayer game in Unity using Mirror.
GitHub Repo: https://github.com/ShrineGames/NetworkingTutorial
Mirror: https://mirror-networking.com
Intro...
watch this i might let you understand it ewasier
yeah i have wastched this
he explains really well
the think is i understand it in theory
in practice i get confused because i have no experience
nahh you let me understand a lot of things
i am actually trying to put together in my mind
just some parts doesn't fit yet
for example, atm, i have command manager in local ( i think )
i click and i sets destination for movement and
makes the player go
why would i want command manager to run in server
as you said here
authoritative server setup is more work compared to client authoritative , it requires more logical steps.
If you are making a mobaa i think you need most be done by server.
it's kind of a moba, where players are casting projectiles to eachother to eachother off the platform where the last one standing wins
there are no targeted abilities
and a caster can hit himself, that is why i want everything to be handled by server.
those things are in general still simple and easy but if you make a mobaa game you harder part will come as you need to make a matchmaking system lol, thats going to be more challanging
i wanted to make a game like this for a long time, but i was working in web dev
i quit because i didn't like it at all so my priority is to learn unity
i don't care if it's hard
as long as i get to learn it, i don't mind how hard or long
an advice i can give is just try to start with something that is more simple. especially if you a 1 person working on it, dont torture yourself too much bro ๐
naah it s not a torture really, i enjoy the struggle actually
i've been there too when i started developing, and im still not making big games after many years
haha webdev is boring, done that too.
i have started 1 month ago. and so far, i have learned so much. and i believe that i can do the game if it was single player
but i have started implementing multiplayer
in the beginning it was fun, but now there are so many websites, you dont really want to start form scratch but rather use an existing framework
about 5 days ago
i checked out photon first but physics was way to hard to sync
so i had to switch to mirror
ok let me explain, its like comparing photoshop with 3dmax
it requires more time and skills
and you need to think different on how logic goes
that is what i like about this
photon also will cost you monthly money due to CCU
yeah i figured how photon actually works , it is actually a creative idea to have a system like that
and for small games, it can be useful for indie developers
its usefull for mobile games
or .io
as those can have ads running so as long as ppl play you get revenue and can pay photon their ccu
but on a 1 time sale its not a good idea to use it
i don't like mobile, and it didn't fit into my game so whatever. i got to learn it tho since i have spend a few days, to sync physics which i couldn't and finally decided to switch to dedicated server
me either im an XR devloper
i work on VR
and have 2 titles ready as soon as my hardware arrives for
https://www.tiltfive.com/
yeah i plan an rts game for that too if there is enough playerbase for it
their current schedule is Q2021 to deliver the hardware to me
good luck man, it's a nice idea. it's like combination of board games and old screenshare parties :P
perfect for dnd
they have a delay almost a year due to covid
oof sorry to hear that
i think this device is will be more intresting than VR for gaming
augmented reality is nice
I partnered with them before the Kickstarter
vr need to be improved imo
yeah already have 5 headsets hre for vr lol
well good luck with this, sound like it's almost done
i am sure it would make profit tho, looks promising
oh i dont really use it for profits
i support it because i think it has potential
its tech that has been abandoned by Valve as they went for the vive vr instead
and it only starts at a price of $300 being able to connet to pc or phone for rendering
yeah at that point it need applications since it's almost the price of a console
yeah they will ahve games for it, 2 of them come from me
and based on how it goes there will be more from my side
my main usage i actually need it for is for educational aplications
thats where the money is for me with those devices
as VR does not work on kids
yeah that could be used for education, i can imagine simulations of chemicals and such stuff
like the
mix of them
I am making arcade games for them.
They dont cost me much time adn they already have at elast a player base of 5k users
its a better player base compared to what i had on my vive preorder lol
VR is fun but i think AR is way much more fun to play for people.
yeah as i said , VR needs more improvement
thats a preview of the game for T5
at least one of them
As i said simple arcade games, they dont cost too much time and can be just fun.
yeah, i like arcades too. simple and fun ,
one of my favorite was digger
which come to think of it, wouldn't be hard as well
oh i got so many games i like form old times the time of C64 and MSX
the 80's are golden years
if you like digger a lot why not make a networked version of digger ๐
idk, i have a specific vision atm. which i enjoy to follow
Great, hope to see your mobaa game when its done,im a dota fan myself ๐
not technocally a moba :P but i am not sure what exactly it is either
other then having rts style game mechanics
i have played dota like 11 years, maybe that is the reason i enjoy the game style :P
My longest and most played game was diablo 2 LOD
i never played tho, i enjoyed diablo's story but never bothered the play the games myself
I gtg now, hope i could help you in the direction to make it work now;)
yeah
you did,
i am planning my way to re structure my inventory and skillset mechanism
and eventually i think it will work out
thank you!
Ok so huge problem right now, whenever I drag the window that my game is in, it completely freezes, and then when you stop dragging it, it executes EVERY SINGLE fixed update that it missed
all in a single frame
that causes the server to be behind the client even more, like 20+ ticks
since the client only sends his update packets every fixedupdate()
any help is greatly appreciated on this
I did some more research, apparently windows blocks the main thread completely when an application is dragged around. So how do I get around this problem?
So how would I deal with this problem
with the fact that 50 fixedupdates get executed at once if a user drags the window
YOu normally play a game at fullscreen. But let me do a google search
server will be running in windowed headless console mode
so I'd need to find a workaround for that specifically since I'm probably going to want to drag it around
Why do you need to keep moving a server window?
just on the offchance that I need to move it somewhere
This is a non existent problem. When you start a server it's supposed to be headless and run on machines you do not even access
then it wont brick the whole server
Well... Do not move it while testing is the best work around
alright
But maybe there's a way to decouple the headless builds from a UI thread
but that is something I have not tried, as I don't see this really as a problem for production.
So I'm still a little bit confused. The server ticks on it's own right? How do I keep the client and server ticking together
do I just do periodic syncs?
And then say a player lags and sends 30 packets all at once and some of them were in the past for the server. You just use physics.simulate to resimulate the scene on the server's end with those late packets up until the present right?
or would you just drop the packets which came in too late?
The part that I'm just logically confused on though, is how to sync the tickrates. Like by the time the packet has reached the client to tell him to start at tick 489, the server has already gone to 490
and now they're ticking differently @gleaming prawn
@slow monolith You are using a custom server/client solution?
Are you handling client prediction, server reconciliation, entity interpolation and lag compensation?
Yes
I don't have secret potion here, but see how Unity Netcode is answering about Time synchronization maybe it will put you on the right path: https://docs.unity3d.com/Packages/com.unity.netcode@0.6/manual/time-synchronization.html
Yes I know, just trying to give you some materials that lead you to implementation ideas
Only says you gotta predict it which I have no clue how to do
Okay so you have to get the round trip time and divide by two
I dont really know where to go from there
Or I could just go back to the way I was previously doing it, where each client has his own tick and just keeps sending input packets for the server to process (server drops any out of order packets)
unless someone can convince me otherwise to share a tick between all clients and server
@slow monolith if you want to run a dedicated server you better of using a headless server and preferable on linux in combination with a custom console.
If you talk about a listen server ( player hosted ) then i can understand it might be a problem. but player hosted comes also with many other problems what could let players lag/disconnects anyways.
Maybe you could look into the source code of Forge Networking as they had somehow a pass around the main threat solution to use multi threading.
what does this mean:
Did not find target for sync message for 178 . Note: this can be completely normal because UDP messages may arrive out of order, so this message might have arrived after a Destroy message.
Did not find target for sync message for 178 . Note: this can be completely normal because UDP messages may arrive out of order, so this message might have arrived after a Destroy message.
UnityEngine.Logger:Log (UnityEngine.LogType,object)
Mirror.ILoggerExtensions:LogWarning (UnityEngine.ILogger,object) (at Assets/Mirror/Runtime/Logging/LogFactory.cs:93)
I m using mirror and when i instantiate a bullet and spawned it with NetworkServer.Spawn() and the bullet only showed up on the screen of the one shooting it and not the other give the error pls help
I think the recommendation people have been pushing you towards is to never re-simulate on the server and drop all packets that arrive too late. This is what Overwatch, Quantum (IIRC), and Unity's preview networking package go for.
Re-simulating on the server is a slightly different networking model (Source engine does this). IIRC the main problem with doing it that way is that lower ping becomes too strong an advantage in shooter games during really close battles. (This is different from the normal "peeker's advantage")
If two players locally predict killing each other the same tick, first input to arrive wins basically. The input from the player with lower ping is probably going to reach the server first, so 9/10 the server will decide the higher ping player is dead. When the higher ping player's input arrives (even just 1 tick later), the server ignores it because they're dead. This is why kill trading basically never happens in Counter Strike (because hitscan weapons and really fast server tick rates make it extremely unlikely for two inputs for the same tick to arrive at the same time), and why melee is particularly bad in Source games.
The client somehow needs to get an estimate of how many ticks ahead of the server it should be (accounting for latency and jitter). You could have the server literally tell the client how early or late it is, by measuring how many ticks some input sat in its queue or how stale a rejected input packet was.
Then, the way you get the client to approach that optimal lead is by scaling the tick rate on the client. If the server and client are normally ticking at 50Hz, the client can change its own rate to like 52Hz to speed up or 48Hz to slow down until the offset is just right. Server's tick rate should stay constant.
Interesting thoughts, thanks for sharing ๐
Since Unet is dead, what is the best networking solution (that isn't photon)
I've looked into MLAPI
but it seems to lack, well, everything when it comes to documentation
and Mirror has a ton of documentation but no lobby and only one client per connection
which seems a bit limiting
it really seems the networking scene is a bit barren, but considering my only experience in networking was running a minecraft server for my friends, I could very well be mistaken
only one client per connection
what do you mean by this?
@abstract zinc we just used mirror to make our global game entry. It was solid for us. 4 player multiplayer. Im not sure what you mean by one client per connection.
Could mirror support about 16 player per lobby
Here is my player movement code: https://hatebin.com/zyctuezawp
I am currently getting errors when I click the space bar button, which is what I made the jump button in the input system asset. I am using Mirror as well.
just look at the bottom 2 errors
looks like you treated that float like it was a vector2 and it got salty
@abstract zinc I don't see why not. Max connections on the network manager is simply an int, no max. So I'm thinking the api let's you go til your host can't handle it. Their showcases have an example that show several hundred mmo style.
oh damn then I really underestimated mirror
I suspect the limiting factors will be your server infrastructure and architecture. It probably goes till Network bandwidth makes it terrible or till your host crashes. So throwing hardware at the problem might extend that. What's your planned deployment architecture?
We were solid on pretty standard laptops. You could move it to a server and probably expect pretty good results. I'll test how many clients I can get connected om my xeon based server. Will report later
I bet I'll be limited by my client try to spin up many connections before I'll be limited by the lib
Network lib aiming to be "mmo scale" should probably be able to support 16 players ๐
how do i sync rigs with pun 2?
i have all animations synced already but to look up and down i use my spine and all of that. not an animator.
how do i sync that?
@dense hedge That's exactly the part I'm confused about, speeding up and slowing down the client to match the server
it seems simple but it also seems like the client could very easily fall behind
So since my client packets send inside fixedupdate(), I would obviously need to change that right and make it send inside a coroutine or something?
Also does the server have to send the client tick-related information too? Like for updating player's movements?
fixedupdate has some weird logic, you could also just use Update
what you need is a method for both ends to request/carry out synchronization.
has anyone done multiplayer webGL games?
@slim ridge I will probably make my own method based on packet's RTT / 2, I just don't know how to implement it at all
i'm told you need a standalone executable build as the server and then you use websockets to have webGL clients connect to it
has anyone done that before?
@south palm You can't have your server being hosted on a web application
you need a dedicated server
mine synchronizes initially by the client requesting it and taking note of the current time. The server responds with it's current tick. The client then adds this plus however many ticks the transport time was to all the packets
i pay for server space for my website, can I use that?
No
you need a dedicated box
or a VPS
something that runs machine code
VPS are cheap, you can rent them like $3 a month
PM me if you need a good host
is it difficult to set up?
Most get automatically setup
you just remote desktop into it
or SSH if it's linux
@south palm I did see that mirror supports websockets as a transport. So my theory is it's possible provided the statements above
@slim ridge So when the server receives the client's packets with the predicted tick, the client should be in the future right?
there are some decent libs for webgl, but since it can't use UDP you are stuck with all the downsides of tcp.
at that point it doesn't matter where the client is because the server is about to tell it where it should be
That's what I'm talking about, like how accurate is the client when guessing the server's tick
Because you need to add latency etc
it'll always be off. but it doesn't have to be precise, only consistently off
that's what i thought initially, but since then i've switched to the server pushing it ahead based on latency
If you send too early, the input buffer on the server grows. If you send too late, the packet gets dropped.
If you send it too early, can't you just drop it?
if the server already processed that tick?
If the client sends something to the server too early.
you would have to reconcile the past with this new information
which is optional as joy said earlier?
ok, hold on a second, I think you're confusing yourself
I am 100%
i think you're overlooking the fact that the protocol needs to be reliable
if you drop a packet, the simulation is now out of sync for everyone
I was just saying that if the client sends something to the server and it arrives too early, the server can just queue it up until it's time to use it. Like say your client sends input for frame 30 and it gets to the server on its frame 25, it'll just sit in the server's input queue for 5 frames.
oh alright I see
ah, yes. and what i meant was that i make it "early" by the server picking a number when it syncs and pushing them all ahead by that much.
a poor connection would put the input farther into the future, and a good one would put them closer
that way the laggy client sees his input in real time, and everyone else sees him lagging
So I should be regularly testing the connection between client/server so it knows to adjust the client's tickrate?
yes
in my system, the server knows when to resync because inputs are getting closer to/farther away from it's idea of now.
Shouldn't most connections be relatively stable?
I suppose if you start up a download you'll experience some problems
yeah, this is about the two computers counting the ticks at slightly different rates
Did you design your own protocol for this?
yes, i'm still working on this part though
So how do I make the tickrate changeable? Coroutine?
sure, i use update
So take this with a grain of salt because I haven't implemented it personally. From what I've read of the new preview package, this seems to be more or less what Unity does.
Whenever the server gets an input from the client, the server checks the packet's tick number (if the client sent a bundle of inputs, it checks the newest one) and compares that to its own tick number.
delta = (server_tick_number + buffered_ticks) - client_packet_tick_number
Then the server sends that back to the client. All that matters is if the delta is positive (speed up) or negative (slow down).
I think they go a bit further and do some averaging on the client or something to get around the fact that the delta is always old by 1 RTT.
How often does that happen
Every server tick probably
Alright
So how does unity handle packets received that are older than the tickrate
does it resim them?
Also the delta, how much would I speed up the client if it was positve?
idk 5% might be good enough
alright
Yo, so this might be more confusing than it helps, but there are kind of like two sub-variants on this whole client-server thing.
client ticks are behind the server tick ("the CSGO way")
client ticks are ahead of the server tick ("the Overwatch way")
You've been getting suggestions for the Overwatch way as far as I can tell.
Doing re-sims on the server is for the CSGO way. Because clients are behind the server, you can't make it so that everyone's inputs for tick N arrive at the same time (since you can't magically reduce latency). You could add delay, but that would just be lockstep. So as a result the server **has ** to re-sim. The pro is you get "time sync" basically for free. Clients can just overwrite their tick numbers with whatever they get in a packet from the server and boom, synced again. The con, like I mentioned earlier, is that because the server has to process inputs at different times, you end up with "ping" being the deciding factor in a really close fight. (Which is ironically a pretty big con for a shooter to have).
If you have clients ahead of the server, the server can get away with simulating each tick only once because you can orchestrate things so that everyone's inputs arrive at (roughly) the same time. But now it takes "manual effort" to keep the timelines in sync. This is where the whole scaling the tick rate comes into play.
So if, for any reason, I got a packet behind the server's tick
I just drop it outright?
yeah
And say I was going for the RTT / 2 method for doing this, and my packets send every 0.02 seconds, and the time to the server was 10ms. Would I add or subtract the 10ms from 0.02
So on that point I'm not all that sure, but lemme see if I explain in the way I know.
There are 4 key points in the round-trip of a packet.
t1 t2
server recv -- server send
/ \
client send client recv
t0 t3
If you just do t3 - t0, you'll know the overall RTT. This is usually a good enough approximation to estimate latency even though it'd be more accurate to remove the server processing time t2 - t1 to get the "pure" RTT. That said, RTT doesn't answer "What is the current tick delta between the client and server right now?" Like where was the server at time t0?
To estimate that "clock skew," you basically average the two time differences (t1 - t0) + (t2 - t3) / 2 (I think the ordering here tells you how much client is behind the server).
The you can translate between client and server time with:
arrival time (server POV) = send time (client POV) + RTT/2 + c2s_clock_skew
Then you're just trying to have the clock skew more or less counteract the combination of network latency and the jitter buffer on the server.
c2s_clock_skew (ideal) = -RTT/2 + buffer
alright
I dunno how common it is to sync time using these estimates (like trying to precisely match the right skew) versus a "lazier" method like computing only whether the client is late and should speed up or is early and should slow down.
Would you recommend the RTT method or the lazier method
idk, I'm probably not much further in to learning networking than you are, actually. I think they end up being more or less than same, since at some point it reduces to "speed up, slow down, or tick normally." I just think the lazy way might be simpler to code.
alright
and lastly, since my player moves inside fixedupdate(), would I have to speed up fixedupdate to have it match the new tickrate?
or just leave it alone?
yeah, speeding up the tick rate means you sim and send faster
ok
I dunno if you can change the fixed timestep on the fly like that tho, might have to go back to Physics.Simulate or something
Time.fixedDeltaTime = 0.05f; does it I think
this also changes the rate at which fixedupdate is called right?
If assigning it like that actually works, then sorta yeah?
FixedUpdate() doesn't strictly get called at a fixed rate, though. It's a bit weird to explain.
I think as long as your Update() rate is faster than the FixedUpdate() rate, FixedUpdate() will more or less get called the rate of the fixed timestep.
so I shouldn't be sending packets inside fixedupdate?
idk
I think fixedupdate always catches up no matter what
yeah, but due to the nature of unity it might decide to catch up all at once.
So if the server has a current tick of 160, and my tickrate is every 20ms, and it takes 40ms one way, I would set my client tick to 162?
I don't see why I would have to alter the tickrate on the client though tbh. Can't I just keep sending at 50hz on the client, but only predict what the tick is going to be, by the time it reaches the server?
That would seem more logical
yes, but would be subject to error
Your example sounds about right, although you'd probably want to pad that with a 1-2 tick buffer juuuuust in case.
I'm not sure how having the client estimate when the server should receive the tick will be different. Like, I think the snag is that you don't want the client to skip over ticks. Like you generally want to have an unbroken timeline so that snapshots compress better.
if you are even using snapshots
So when my client is sending info to the server, he would have to account for that 40ms delay right? So if the client/server are both running on tick 180, I would have to set the packet to the server for tick 182?
or 183 with the buffer you stated
but that packet might get dropped, your next packet would have to make a new calculation
Like, let's roll with your hypothetical scenario. Client on 183, server on 180, 20 ms ticks, 40ms one-way delay. Everything's perfect. What happens if all of a sudden your delay increases to say 120ms?
yeah, every new packet would make it's own calculation based on the latency
yeah that would be a problem
Can't I just get the RTT every single packet?
and just re-calculate with every packet I need to send?
it's too volatile, you should be working with a rolling exponential average
alright
It's always one packet behind.
Like by the time you're sending a packet, you only know about packets that were sent before.
And yeah a moving average is good
and you still have to handle the case where packets are too slow/fast
err, i mean bursts and gaps of packets
I think gaps can be mitigated by having the client send a whole window of inputs every time. Like every input whose results from the server are still pending.
ya, that's how i get reliable + ordered: send every message with every packet until they are acknowledged.
But yeah, whenever you fall out of sync, you have to adjust, but I guess you do have the option to just skip forward instead of scaling the tick rate. I don't know how that would look to the client or if it would cause any weird issues, though.
yeah I would probably just skip forward tbh
Seems like being too far ahead might have some weirdness.
that seems a lot easier than scaling the tick
So if the client is sending ticks 1-2 ahead of the server, it's not really going to be a big deal?
The padding? It's 1-2 on top of whatever the latency is. Just enough to leave some wiggle room to smooth over most small network variations. Since the clients are predicting, they won't notice it, but its desirable to have the buffer be as small as possible to reduce the amount of lag between clients.
okay
But then when I need to reconciliate on my client, won't the client's tick log be out of order from the server since the client is only guessing which tick it's going to end up at?
idk, I haven't tried or thought through this skip ahead idea before
Because what I'm doing right now is, every client has his own tick, and the client ticks on his own, he tells the server which tick he's currently at, along with the movements, so the server can store it properly and be in sync pretty much all the time with the client
that seems to work incredibly well believe it or not
so is it absolutely necessary that all clients share the same tick?
server drops all ticks in the past
then when it's time for the server to tell the client the positions, it just gives the clients the last known positions of everyone on the server
no tick sync needed
I think remote entities are often interpolated between two valid states if that's what you're saying. Like only the client's own entity is being extrapolated. I don't know how you reconcile without knowing where to rewind to though.
Also wdym by share the same tick, I think the aim is to have everyone's input for a given tick collectively reach the server shortly before it executes that tick.
In practice, this means if you had a birds eye view of every client, they would probably be on slightly different ticks cuz their pings are different.
So basically right now, the client just sends a packet every 20ms. When the server receives it, he puts it on a queue along with that player's tick that he sent it at
so when the server updates the position, it moves the character then sets the player's tick on the server to whatever it was for that specific movement packet
so when the server sends the client his last known position on the server, he also sends the tick assosciated with it, which the client also has a table for
then you're able to reconciliate, which works perfectly for my current game, I just don't know if its going to work in the long run
basically the server doesn't automatically tick for the client. The client sends his current tick and the server updates it when that happens
all clients have a different tick
So like your server state is a collection of multiple ticks, not one authoritative tick?
each packet that the server receives, has movement commands, and a tick attached to it
so when the server receives it, it checks if the packet's tick is higher than the last one
if not, drop it. If it accepts it, then the player's tick value on the server is now that tick value the server received.
and yes, each player object has it's own tick assosciated with it
its extremely simple and works well, just dont know if its going to keep working well as development furthers
My game isn't necessarily a competitive shooter either, sort of just a first person open city RP game with ocassional gun battles
Only one packet is processed every fixedupdate. So the client can't send 800 at once and expect to have speed hacks
Plus if the server's movement buffer for the player is >= 2, it drops other incoming packets headed for it, since it really shouldn't be over 2 at any time
to counteract it, if the client, for any reason decides to send a bunch of packets at once. Then the client isn't 800 steps ahead of the server
can't be any worse than GTA V's multiplayer
Your way is pretty foreign to me, seems closer to the Source engine model.
I understand "clients ahead of the server" as having the server be on tick N. Each tick is only simulated on the server once (I think this is what you mean with "everyone is on the same tick", from the server's POV I guess).
So if the server is about to simulate tick 20, the clients are probably on like 23, 26, 30, etc. depending on their ping. All their inputs for tick 20 should have arrived by now (ideally between server ticks 18 and 19) because the server isn't going to do it again. The server simulates 20 then sends it out to everyone at once.
I wouldn't say "clients on the same tick." It's super confusing. Clients are never guaranteed to be on the same tick locally for any networking model except lockstep.
There's no issue of accidentally processing multiple inputs from the same player since the server only goes one tick at a time and never re-simulates. A client's input for that tick was either available or lost (in which case, we copied their input for the tick before).
To simplify it for you, for my game as of right now, every fixedupdate, each client just sends an instruction for the fixedupdate that he just processed locally
client has no clue what the server's tick is
so the client just sends a packet saying "I JUST (in this moment) walked forward and left, please repeat this on the server when you get the next chance to" and has a sequence number attached to it for A. Later reconciliation (server can tell the client: your last known position was XYZ at Sequence Number). So the client can look up that sequence number and resimulate all physics actions extremely precisely from that point to the present, and B. So the server knows the order of packets and can drop out of order packets
All I need to know is if this is viable for a game
In your case, if you have two clients, A and B, and client A's tick 20 reaches the server 3 ticks before client B's tick 20 does, how does the server handle that?
In my mind, if you aren't shifting the clients' timelines such that their inputs for the same tick all get processed by the server at the same time, then I don't see how you can avoid re-simulating ticks on the server. Like, doing that is a fully-functioning network model, I'm just trying to understand if you are. Granted, no one has suggested doing it that way to my knowledge.
AFAIK the main caveat there is that for really close gunfights with instant/hitscan attacks, trades are unlikely, they're basically predetermined in favor of the player with the lower ping.
yeah ill probably redesign my system so there's one global tick that everyone uses
I'll probably run into less problems in the future with that
But like you were saying with padding the buffer with 1-2 ticks in the future, that would be around 40ms of added latency from client to server right?
ye, sounds about right if 1 tick is 20ms, a buffer of 2 would be an extra 40
also when I need to send information from server to client, telling him to update, say, 10 other players, do I just send their updated positions and client applies them as quick as possible
or does that need to be tick based as well
so I think for a smooth experience, games usually interpolate the other players (the remote entities) between the two most recent positions you have from the server
so like on each client, his player entity is a guess in the future, the entities of the other players are in the past being blended between the two most recent updates you got from the server
alright sounds good
I think if you run out of states to interpolate for the other players, then you can start extrapolating them but I'm not exactly sure what that looks like
I would probably have to do that with cars
not sure either
Do you think I could just give the car a rigidbody, set it to extrapolate. Then when an update packet comes in for a player in a car, I set him to that last known position and last known velocity from the server
Probably something along those lines would work
for vehicles idk, I feel like no matter what, you'll have at least one edge case that won't look right
The rigidbody itself would probably be invisible, then just have the car model lerp to it
yeah
Use Mirror, its the the fixed UNET
https://assetstore.unity.com/packages/tools/network/mirror-129321
https://mirror-networking.com/
Mirror worst case stress test with 480 CCU
@abstract zinc
https://mirror-networking.com/showcase/
So when you modify the tickrate on the client, is that so that the server receives low ping and high ping connection packets at exactly the same time, so it makes it more fair for all players?
Still trying to wrap my head around this. I just don't understand modifying the client's tickrate unless its the reason I stated above @dense hedge The way I see it, is that players with higher ping will send messages sooner than players with low ping, so all players have their messages arrive at the same time. This is purely optional and mainly used for competitive shooters, right?
I also looked on valve's networking docs and they don't do anything like that. They do something called lag compensation though which sounds somewhat similar
hi when making a multiplayer game, is it better to do the mechanics first then the network code? or doing both of them at the get go?
pros and cons of photon and mirror?
haven't used either, couldn't tell you
One of the main cons would be, that you don't own any of this software that you're stacking into your game
so if you ever want to sell it, you might run into some licensing problems
some1 pls help
whenever i try to spawn my bullet
using mirrors NetworkServer.Spawn()
it spawns then deletes instantly
it gives an error
@gleaming prawn In the games you've worked on, did you ever have the client's tickrate change based on his latency to the server?
or is it always a fixed amount for every player?
So before I go to bed, yes to your first question and the first paragraph that follows it. Syncing the arrival of messages (by modifying tick rate) is "optional" in that you can choose a different networking model, like Valve's (it's a slight difference). Otherwise, I don't know if you can just not do it without paying some penalty.
Lag compensation is a separate thing that you would do regardless of whether you do it like Valve or like Overwatch. Again, the client's current view is in the future relative to the server while the players he sees are all in the past relative to the server. When the server does things like hit registration, it'll do so by first recreating the client's perspective.
Otherwise, you'd have to lead shots like crazy. An important side effect of lag compensation that players will experience "getting shot from behind cover", though. The server is literally OK'ing people being shot in the past. So usually there's some ping cut-off where the server stops helping you and then you have to lead your shots.
So the penalty would just be players seeing delayed player movement
if I chose to not modify the tickrate
And lastly before you go to bed one more question: My bullets move with physics, so would the lag compensation still be done the same way?
I dunno if "delayed movement" is the penalty or if that's the only penalty. If message arrival isn't synced I think you're open to have cases (like a really close gunfight) where the outcome will be biased towards the lower ping player.
AFAIK you should be able to predict and lag compensate projectiles (even slow moving ones). I haven't thought about it that much, though.
alright
where the outcome will be biased towards the lower ping player. I'm pretty sure this is standard in most non competitive shooters
I could be wrong though
something like that right?
peeker's advantage is a different thing
you can't really escape that because it's a byproduct of latency
alright
What I mean is that in cases where you allow clients' input to be processed separately, sometimes when the server is about to weigh in on some conflict between players that it can't redo (like killing a player), the outcome can be biased in favor of whoever's packet gets processed first (which clearly can't happen when everyone's inputs are processed simultaneously). 99% of the time the server isn't deciding a close outcome, though, so it might be worth the tradeoff.
but since players are sending packets 1-2 ticks ahead of where the server is, shouldn't they be queued up and all execute at the same time?
assuming they even arrive on time
But when dealing with that, the player should only increase the packet sending rate at 1/2RTT then right
I think I'm starting to understand this better
So I was describing how you'd buffer for the case when you are syncing message arrival. I don't think you can assume they'll arrive on time if you're doing it the way you described earlier.
Like what does it mean to be on time if clients' inputs can kind of come in whenever? How do you come up with a deadline?
that's it from me for tonight tho, we'll understand this stuff eventually
Alright, appreciate it
some 1 pls help me y wont my bullets show up on d other side
Someone's input is always going to be processed first in the end
Even if you queue up your packets
{
while (true)
{
byte[] StartNetworkingTCPFirstBytes = new byte[2];
byte[] StartNetworkingTCPSecondBytes = new byte[2];
await NetworkStream.ReadAsync(StartNetworkingTCPFirstBytes, 0, 2);
await NetworkStream.ReadAsync(StartNetworkingTCPSecondBytes, 0, 2);
int StartNetworkingTCPFirstMessage = BitConverter.ToUInt16(StartNetworkingTCPFirstBytes, 0);
int StartNetworkingTCPSecondMessage = BitConverter.ToInt16(StartNetworkingTCPSecondBytes, 0);
var StartNetworkingTCPRemaining = StartNetworkingTCPFirstMessage;
var StartNetworkingTCPOffset = 0;
var StartNetworkingTCPBuffer = new byte[StartNetworkingTCPFirstMessage];
while (true)
{
var StartNetworkingTCPReceived = await NetworkStream.ReadAsync(StartNetworkingTCPBuffer, StartNetworkingTCPOffset, StartNetworkingTCPRemaining);
if (StartNetworkingTCPRemaining == StartNetworkingTCPReceived)
{
break;
}
StartNetworkingTCPRemaining -= StartNetworkingTCPReceived;
StartNetworkingTCPOffset += StartNetworkingTCPReceived;
}
HandleTCPMessage(StartNetworkingTCPSecondMessage, Encoding.ASCII.GetString(StartNetworkingTCPBuffer, 0, StartNetworkingTCPFirstMessage));
}
}
TCPListener is giving me 300 millisecond delays when receiving info on localhost, on the same machine
very annoying
I'd certainly start by throwing away all the async and awaits for something as real-time as a game
Try polling a socket directly and see what the difference is
Still, 300 ms is way too high, even for await readasync
yeah it was due to the fact that I wasn't running that part in a separate thread
should've known
thought I could get away with running the client's networking on the game thread, I was very wrong
The delay or the async?
You can get away very easily by running the networking on the main thread
It just depends how intensive everything is
What game, how your sim looks, etc
Nothing was happening, empty scene
300ms delay. Changed it to it's own thread, much less delay
Blame the await in that case
Just use a non-blocking socket and poll it every frame if you want it on the main thread
04.45.41.813184 is the server's send time, 04.45.41.816175 is the client's receive time
is that good enough for the time?
I'm writing a very slim tcp netlib aimed at boardgames and low-sim games
You can use that if you want, up to you
๐
04.58.27.332080 start and end value
Async is cool for developer-friendly socket programming
But it has quite some overhead, especially in IL2CPP builds
Cool for business applications, not cool for real-time applications
Might have another issue
05.00.04.867880 this is the time before my TCP send function is called
05.00.04.874861
This is directly after
is that slow?
Slow/Fast is relative
You know the frame time for your game
You know the tickrate also
See if that fits, with some slack preferably
well removing the function call and adding debug.log gives me around the same time
so I'm gonna say it's fine for right now
hi guys, new to unity and pun, I was trynna implement pun in a game, but when testing my game photonView.IsMine is returning false, when should it return true?
by pun docs it says
True if the PhotonView is "mine" and can be controlled by this client. PUN has an ownership concept that defines who can control and destroy each PhotonView. True in case the controller matches the local Player. True if this is a scene photonview (null owner and ownerId == 0) on the Master client.
I am the client when testing it right? So why would it return false?
How are you instantiating? @worthy gale Something like that has been coming up a lot lately
and is this 2020.2?
I just linked the Photon View script to my gameobject but tbh this scene I am testing does not connect or join to any room so that might be the issue?
It will be false until you are connected
2019.4.13d1