Continue spawning after master client is left - unity3d

I am trying to build a tower defense game using Unity and Photon. I generally find answers on the web but found nothing for this situation:
I have a spawn manager script that spawns enemies and increases a spawnIndex (only the master client does this). Since the master client is handling the spawnIndex, as soon as the master client leaves the game, another player takes over and starts spawnIndex back at 0.
I tried singleton implementation with no luck. I need a way for the master client to maintain a variable and, if they leave the game, have that variable taken over by a new master client, continuing where it was left off.

Thank you for choosing Photon!
The spawnIndex should be a custom room property and not a private field.
You can read about "Host Migration and Master Client" in general here.
It's also preferable to set the spawnIndex using "Compare-And-Set" (or "Check-And-Swap") only by passing the old value as expectedProperties parameter in PhotonNetwork.CurrentRoom.SetCustomPropreties.

Related

Trying to understand Unreal Engine 4 replication

I'm trying to understand how to call events between client and server. My goal for now is simple. I want to create anything that is interactable for 2 players.
Easiest thing I could think of was cube that is switching color when clicked. So I did create actor based blueprint, checked "Replicates" and AlwaysRelevant to be sure. PlayerController is also replicated and there is no pawn needed.
Color change blueprint:
SM is just static mesh if that is important. As far as I know client have no authority to call multicast events so I wanted to push it through server but it stops there. Called from server works as expected and color itself IS replicated to client, however client cannot change color himself.
What am I missing in this concept? I've watched like 5 videos about replication and I started to think there is something missing which is either obvious for everyone but me or their examples do not need things I do here.
As you've found out, a player's client can not directly call server RPCs on actors which the player does not own. Calls must be routed through that player's PlayerController. The server copy of the player's PlayerController can then call server methods on server-owned actors.
Another issue is that you seem to be using both RPCs and replicated properties for the same purpose. Unclear to me why changed is replicated since you're modifying it in a multicast event which normally runs on all the machines. This is a recipe for hard to find race condition bugs.
Replication in Unreal is definitely one of the harder concepts to get the hang of. The resource that helped me the most is this guide which while quite dated, is both comprehensive and to the point.
You can't have it in PlayerController, it's got to be in a Pawn, or if not, in PlayerState, or it won't get shared to other clients.

How do I access my Player Camera Manager (replicated (listen server and client)) in UE4 Blueprints

When I try to access the location of my Player Camera Manager on the server it returns 0, 0, 0.
I think that I tried every option on setting the Player Camera Manager respectively the Player Controller in all the replicated options. To be clear: At first, I used my common sense but after a week of failure I tried every combination with no success.
As an example: Here is how I tried to access the Location and the forward Vector for a Line Trace
I also tried to set the Camera Manager as a variable (I tried both server and client) and then access it on the server.
Does anyone have any ideas on how to fix that?
Any help is much appreciated.
APlayerCameraManager is not an actor that replicates, so I'd expect that blueprints to only work on the client. You'll have to replicate the values you need back to the server.
If you're making a first person game APawn replicates a variable named RemoteViewPitch that may be enough depending on what you're doing.
You can do it just make an interface function with input the information that you need from the manager then go to character and assign that to it then go to the manager blueprint and get the information and use controlled pawn to get ur player ref and call interface function

How to synchronize a 1v1 realtime action online mini game?

What I'm trying to make
Hi, game development newbie here. The game I am trying to make is fairly simple. It's almost exactly like the old FC game "Ballon Fight" except that I'm trying to make it online where players can go through a match making to find opponents.
BalloonFight:
What I Read
I have read some articles, and found most of them lead to two approaches:
Put all game logic on the client, and the client sends player inputs to server on every frame update. The server acts like a dispatcher which only makes sure player A's input is received by both client A and B. My understanding is that if we see the client in this case as a pure function, and if the two players' inputs are received by each other, the game should produce same results on both clients. Thus synchronization is achieved.
Put all game logic on the server, and let the server do the calculations and send back results to both clients. In this case, clients only worry about displaying.
My Fears
Solution 1 sounded like a simpler one to me, but immediately I realized when network problem is put into account, it becomes incredibly complicated. Losing player A's connection for a few seconds means all the input is lost in that period. What I can guess is, to counter that, the server has to detect whether player A is lagged out and accumulate input from player B until player A is back then feed all the accumulated input to player A's client. Player A's client then need to do a fast forward to catch up. This sounds like there's huge amount of infra work on both client side and server side.
Solution 2 on the other hand looks very daunting to me, since for now I have only written some games on the client side.
My questions
in order to make a simple online game like this, what is the most beginner friendly way to synchronize game state?
if I were to use solution 1 stated above, is there any framework that provides such infra so that I don't have to handle network issues all by myself?
In advance, thank you game dev gurus.

Unity UNET How to change online scene in sync with clients

I'm using the old Unity 2017.3 UNET implementation in my game. Players connect to a server and are placed in a Lobby scene until the party leader selects another level to go to. The implementation is just a slightly modified version of the default NetworkLobbyManager.
The trouble started now that I've begun heavily testing the networking code by running a compiled build for a client and then using the editor as the server. Very frequently, the server running in the editor will run a great deal slower than the compiled client build. So when I use NetworkManager.ServerChangeScene the client will load the scene before the server, which will cause all NetworkIdentities on the client scene to be disabled (because they haven't been created on the server yet.)
It's a lot less likely to happen if the server is running a compiled build, because the server will almost always load the scene before any clients. But it does surface a bigger issue with Unity itself. That there's no guarantee that the server will be available when changing scenes.
Is there some other way of changing scenes in a networked game? Is there a way to guarantee that the server enters the scene before any clients? Or am I stuck just kind of hoping that the network remains stable between scene changes?
Well I thought about it more overnight and decided to look in other directions, because more investigation revealed that sometimes the Network Identities are still disabled when the server loads the scene first as well.
I was looking through the UNET source code and realized that the server should be accounting for situations where it loads the scene after the clients, although that code looks a little jank to me. This theory was backed up by the documentation I found that also says NetworkIdentities in the Scene on startup are treated as if they are spawned dynamically when the server starts.
Knowing those things now, I'm starting to think that I'm just dumb and messed some stuff up on my end. The object that was being disabled is a manager that enables and disables other NetworkIdentity objects. I'm pretty sure the main problem is that it's disabling a network identity on the client, that is still enabled on the server, which is causing the whole thing to go haywire.
In the future, I'm just going to try and stay away from enabling and disabling game objects on a networked basis and stick to putting relevant functionality behind a flag of my own so that I can "soft disable" an object without bugging out any incoming RPCs or SyncVar data.

Game Kit Peer to Peer

I coded a bomberman application that uses a gamekit peer to peer connection. The problem is that after a while the game isn't in sync anymore.
I looked at the sample code for GKTanks and used their model. There is no client/server relation between peers so I didn't use one in my game. Both peers maintain a gamestate which they update based on received data.
I have a NSTimer that's used for running the gameloop at each frame. The NSTimers aren't in sync so sometimes the gamestates become different ex: players pick up a powerup at approximately the same time and they both get the powerup because it takes a while to send data.
I would appreciate any idea on making the app work. I'm thinking of rewriting the code to use client-server but I'm not sure if it's a good idea... yet
Thank you!
EDIT: I changed the code such that a random player is picked to be the host.
Every time a player places a bomb he asks the server where to place it. The server returns the players position(as seen on the server) and then tells the player where to place the bomb.
For powerups the server checks if a player picked up a powerup and if he did it sends a packet informing him.
Another problem has appeared now. The latency between devices is high(I'm using a bluetooth connection). It takes around 0.2 seconds to place a bomb after the client tapped the button to place it.
I'm sending all data reliably. Am I doing this right?
Well preferbly you want a host-client relationship where only the host can manipulate the game state, so in your case it would be:
Both players rush to the powerup.
Host picks it up first.
It gets registered and the host recieves the power-up.
Meanwhile player#2 also picks up the power-up, sends the action to the host.
The host informs player#2 that the power-up is already disappeared.
The thing with your situation you are bound to get desynchs from packet loss.
With host-client relationship that cannot happen, the only problem is the host always has an advantage that becomes greater when the latency increases between devices especially on smartphones.
In a game like bomberman it's perfectly plausible to send the entire gamestate each time something changes instead of the action that was performed, this is to ensure both devices are in sync.
To sum it up: both users have their gamestate but only the host can manipulate both.
what you should do:
one of the devices is host, another one is client
host process all the game states and makes decisions, then it sends whole gamestate to the client
client gets the gamestate and just draws everything based on it - it doesnt make any decisions (who picked bomb, did bomb exploded etc)
client just sends input to the host (pressed left,right, pause etc)
that's it. if you try to make decisions on both machines, you will run into big troubles trying to keep them in sync.