Unity PUN2 Photon Methodoloy / Optimization - unity3d

Using Photon to sync a multiplayer game, I keep running into a methodology / best practice question as I develop. Using the case below, what's the proper / optimal way to accomplish?
Example: I have player1 (MasterClient) and Player2 (not master).
Player1 explodes a container and damage occurs to both players.
Player1 takes damage and sends Player2 their damage to process.
Player2 explodes a container and damage occurs to both players:
Should Player2 send this event to Player1 (MC) and let Player1 take damage and then send Player2 their damage to process?
Should Player2 process it's own damage and send to "others" including Player1 (MC) to take their own damage?

Related

How to make a common variable for all players. Photon

I need a variable responsible for the number of live players, when a player connects to a room, it increases by 1, when he dies, it decreases.
I tried using RPC and stream, but nothing worked.

Latency handling methods in a multiplayer game

I am working on a real-time multiplayer soccer game.
Currently on my game i created a architecture like that;
Every client have a copy of the game state, also server has it too.
Clients send their input vector(joystick data) to server.(Local player uses the current input and move)
Client waits for other player's input, once that data arrives i set rigidbody speed and direction. Than it goes with smoothly.
Used Things;
UDP(has lower ping)
Tickrate : 32(Increasing tickrate fix this issues most of the time but not everyone's connection is strong and sending many packets in a second cause a ping issue)
Problem is;
Some times server and clients get de-sync and this cause every client sees another copy of the current game.
What i've tried;
Tried to increase Tickrate, but this only caused a connection with higher ping + packet loss
Lerp between two data, this caused; players seems like moving with different speeds
Lerp + Jitter, this caused; players always see the game in past state
If client and server positions different than a delta-x use the server's position(normally this can fix the issue but some times server and client get de-sync in every 4 tick and transporting object in 4 tick cause a very laggy / not smooth visual)
What is the best method to fix or handle this de-sync?
And why it is happening?
Is it normal to happen in almost every 4-5 tick?(~9 times in a second)

Truck (Agent) Hitbox in process modeling library

im creating some paths with the process modeling library. The trucks shall stop in series when waiting for the "go" signal to go on.
At the moment the trucks are waiting "within" each other.
How to tell the trucks to recognize not the stopnode only but also the hitbox of the truck which arrived before him?
Thanks in advance
Chris
The trucks shall stop in series when waiting for the "go" signal to go on.
At the moment the trucks are waiting "within" each other. [...]
How to tell the trucks to recognize not the stopnode only but also the
hitbox of the truck which arrived before him?
AnyLogic allows for agents to queue along a path (from an animation perspective) whilst in a Queue block. So don't make them move to the stop-node (which I assume you are doing explicitly): make them (from a process point-of-view) go into a Queue which is animated via the path from the stop node 'backwards'. (This is the "Agent location" setting of the Queue block.) How you hold them in the queue and release them when they need to depends on the nature of your model; e.g.,
Use a Hold block following the Queue (if it makes sense to release them all at once)
Use a 'dangling' Queue block which you pull agents out of programmatically (e.g., via its removeFirst function) and then add them somewhere else in the process via an Enter block.
Use a Seize block (which has a built-in Queue you can set the location of) with the resource seized representing the 'token' you need to proceed.
NB: From the process perspective, they are in a Queue which happens to be animated as queueing along a path. This isn't exactly the same as modelling the 'spatial reality' of being in a queue: see this question.
Simple solution is to turn your truck agents into Transporters from the Material-handling library. They have build-in collision avoidance.
However, this can slow large models so you may want to convert them only when you need collision avoidance and then convert back to "simple" Truck agents again.
Else, you need to build your own additional stop-nodes and code spatial queuing manually. Possible but not straight forward

How to use Audio Groups in Photon Voice Unity3D?

Hi I am new to multiplayer development and I am using photon voice and wanted to make private voice chat between two player in a room created which has many players. I was directed to
https://doc.photonengine.com/en-us/voice/current/getting-started/voice-for-pun?utm_campaign=sendgrid&utm_source=sendgrid.com&utm_medium=email
by support of photon but I am not able to get it working. How should I make private voice chat in this multiplayer. please give example for explanation. Thanks
There is a demo scene for Push To Talk which showcases how to do this.
Let me try to explain how to implement player to player voice chat using current Photon Voice:
Photon Voice uses voice groups (which is nothing but Photon LoadBalancing's "Interest Groups") to separate voice channels/targets.
Filter incoming sounds (select "what to hear" or "who do you want to listen to"):
Each actor needs to subscribe to voice groups it's interested in. By default all actors listen to audio group 0 which could be seen as a global audio group for voice broadcast. If you want to listen to voice sent to other groups you need to subscribe to them. You can also unsubscribe from previously subscribed ones. The operation to do all this is: PhotonVoiceNetwork.Client.ChangeAudioGroups(byte[] groupsToRemove, byte[] groupsToAdd);
Select a single transmission target audio group (select "who do you want to talk to"):
Each actor needs to decide to which voice group it wants to transmit audio. The target audio group can be set using PhotonVoiceRecorder.AudioGroup.
So depending on the use case what you can do is:
Speak to a single group and listen to multiple groups. You can speak to a group other than those you listen to. You can listen to all available groups.
Speak to a single group and listen only to default group.
Speak and listen to a single same audio group. For this particular use case, there is a shortcut to switch between this single in/out group by setting: PhotonVoiceNetwork.Client.GlobalAudioGroup. If you choose to set GlobalAudioGroup no need to call ChangeAudioGroups or set PhotonVoiceRecorder.AudioGroup as it's done internally for you.
In the three cases, you always listen to default audio group 0.
The Photon Voice demo offers two options for private (1 to 1) voice chat:
"MuteOthersWhileTalking" enabled: corresponds to case n°3.
"MuteOthersWhileTalking" disabled: corresponds to case n°1.
The audio groups in the demo are constructed this way:
We have rooms of 4 actors.
We need 6 audio groups.
For each pair of actors we calculate a unique group code.
actor A with actor number (player ID) equal to x
actor B with actor number equal to y
Here is how we get the audio group of private voice chat between A and B (if an actor number reaches 24 we have a problem):
if (x < y)
{
AudioGroup = y + x * 10;
}
else if (x > y)
{
AudioGroup = x + y * 10;
}
else
{
// error
}
Example: The audio group for actors 1 and 2 is 12.
Another approach of "calculating" private voice groups is to use the actor number as audio group: each actor subscribes to a single audio group with a code equal to its actor number. whenever you want to talk to a remote actor you set the target audio group (using PhotonVoiceRecorder.AudioGroup only) to the target actor number.
The advantage of this approach:
Less audio groups: We need as many audio groups as actors.
Less audio groups switching: single audio group to subscribe to and no unsubscribing.
The drawback of this approach:
You can't mute any other actor. You will listen to anyone who wants to talk to you privately.

Mutli Player Game synchronization

The Situation:
I would like to ask what's the best logic for synchronizing objects in a multiplayer 1:1 game using BT or a web server. The game has two players, each of them has multiple guns & bullets, the bullets are created dynamically and disappear after a while, the players my move objects around simultaneously.
The Problem:
I have a real issue with synchronization, since the bullets on one device may be faster than other, also they may have already gone or hit an object on one device while on the other its still in the air.
Possibilities?
What is the best way of handling synchonization in this case? Should all the objects be controlled by one device acting as the server, while th other just gets the values, positions and does very little thinking. Or should control be distributed where each device creates, destroys and moves its own objects and then through synchronization tells the other device.
What is the best to handle transmission delay in this, since BT might be faster than playing over the web?
The best would be a working sample - thanks very much!
You seem to have started on some good ideas about synchronization, but it's possible there are two problems you are running into that are getting overlapped: the synchronization of game clocks and the sychronization of gamestate.
(1) synchronizing game clocks
you need some representation of 'game time' for your game. for a 2 player game it is very reasonable to simply declare one the authority.
so on the authoritative client:
OnUpdate()
gameTime = GetClockTime();
msg.gameTime = gameTime
SendGameTimeMessage(msg);
on the other client might be something like:
OnReceivGameTimeeMessage(msg)
lastGameTimeFromNetwork = msg.gameTime;
lastClockTimeOfGameTimeMessage = GetClockTime();
OnUpdate()
gameTime = lastGameTimeFromNetwork + GetClockTime() - lastClockTimeOfGameTimeMessage;
there are complications like skipping/slipping (ie getting times from over the network that go forward/backward too much) that require further work, but hopefully you get the idea. follow up with another question if you need.
note: this example doesn't differentiate 'ticks' vs 'seconds' nor does is it tied to your network protocol nor the type of device your game is running on (save the requirement 'the device has a local clock').
(2) synchronizing gamestate
after you have a consistent game clock, you still need to work out how to consistently simulate and propagate your gamestate. for synchronizing gamestate you have a few choices:
asynchronous
each unit of gamestate is 'owned' by one process. only that process is allowed to change that gamestate. those changes are propagated to all other processes.
if everything is owned by a single process, this is often called a 'client/server' game.
note, with this model each client has a different view of the game world at any time.
example games: quake, world of warcraft
to optimize bandwidth and hide latency, you can often do some local simulation for fields with a high update frequency. example:
drawPosition = lastSyncPostion + (currentTime - lastSyncTime) * lastSyncVelocity
of course you to having to reconcile new information with your simulated version in this case.
synchronous
each unit of gamestate is identical in all processes.
commands from each process are propagated to each other with their desired initiation time (sometime in the future).
in its simplest form, one process (often called the host) sends special messages indicating when to advance the game time. when everyone recieves that message they are allowed to simulate the game up to that point.
the 'in the future' requirement leads to high latency between input command and gamestate change.
in non-real time games like civilization, this is fine. in a game like starcraft, normally the sound acknowledging the input comes immediately, but the actually gamestate affecting action is delayed. this style is not appropriate for games like shooters that require time-sensitive actions (on the ~100ms scale).
synchronous with resimulation
each unit of gamestate is identical in all processes.
each process sends all other processes its input with its current timestamp. additionally a 'nothing happened' message is periodically sent.
each process has 2 copies of the gamestate.
copy 1 of the gamestate is propagated to the 'last earliest message' it has receive from all other clients. this is equivalent to the synchronous model, but has the weakness that it represents a gamestate from 'a little bit ago'
copy 2 of the gamestate is copy 1 plus all the remaining messages. it is a prediction of what is gamestate at the current time on the client, assuming nothing new happens.
the player interacts with some combination of the two gamestate (ideally 100% copy 2, but some consideration must be taken to avoid pops as new messages come in)
example games: street fighter 4 (internet play)
from your description, options (1) and (3) seem to fit your problem. again if you have further questions or require more detail, ask a follow up.
since the bullets on one device may be faster than other
This should not happen if the game has been architected properly.
Most games these days (particularly multiplayer ones) work on ticks - small timeslices. Each system should get the exact same result when it computes what happened during a tick - no "bullets moving faster on one machine than they do on another".
Then it's a much simpler matter of making sure each system gets the same inputs for each player (you'll need to broadcast each player's input to each other player, along with the tick the input was registered during), and making sure that each system calculates ticks at the same rate.