Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Player ID, Replication & Client Side checking for a turn based game


So I'm making a TCG game similar to Magic: the Gathering or Hearthstone. I have a custom player state, game state, and player controller class. I'm pulling out my hair trying to figure out how to randomize which player goes first, and to allow the player whos turn it is, to advance the game and end their turn. I've ended up with some kind of race condition or something.

In my GameState, I have an array containing the "Player Order." Index 0 represents the first player to go, index 1 represents the 2nd player to go. The int within the array represents the player's ID (taken from gamestate itself). It uses the "get player state from index" function to search the general player array class and find matching ID's.

alt text

alt text

In my player controller, I have some client side checks to see if the "active player ID" is the same as the game states. If it is, then I can call a server function to move the game forward a phase (main phase -> combat -> end turn for example).

alt text

However, sometimes the player controller function fails, and I have mismatched values. I have been printing the values to the screen every time it fails, I often get this result:

On one instance of the client:

Active Player ID:552 (the one we need to progress the game) red text

Current Player ID: 553 (the player controllers) green text

On the other instance of the client:

Active Player ID:553 (the one we need to progress the game) red text

Current Player ID: 552 (the player controllers) green text

Both of these clients cannot progress the game, because the "active player" is not equal to the player attempting to call the function. But the ID's for both of them are correct on the OTHER client's information...

alt text

Other times it works perfectly as if there was no problem at all. Note that I am testing this using PIE, on a dedicated server with 2 players. And from these, I assumed that my logic for progressing the game was correct.

This is super frustrating as I cannot consistently reproduce this error. It seems like some kind of race condition (or else I don't fully grasp replication).

Would really appreciate any help on this issue! Thanks.

Product Version: UE 4.12
more ▼

asked Jul 06 '16 at 07:17 PM in Blueprint Scripting

avatar image

23 3 6 9

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Where is the SosGameState > Generate Player Order executed on? Is it executed on Server only or do the Clients execute it. That type of code looks like it belongs in GameMode instead of GameState, as it seems like a Server only thing to figure out who should be active.

EDIT: If it's executed on Client, then both clients could end up shuffling to different states. Just because you try to set Active Player Index on a client, doesn't mean the server will agree to it and replicate it to everyone else.

EDIT2: The only thing your cilent should be able to do is tell the server they finished their turn. Let the server decide if the active player should switch. So I'd disagree with the idea of having the client check for active player to let the server know what should be done.

more ▼

answered Jul 07 '16 at 06:03 AM

avatar image

130 3 58 13

avatar image Zerve Jul 07 '16 at 06:50 AM

Generate Player Order is executed once both players have the boolean "isReady" active. I have this behind a has authority switch so it only executes on the server and not the players.

I have the clients trying to notify the server that they have ended their turn (or advance the state). The thing is that I dont want to spam the server with these "end turn attempts" if the player mashes the space bar during other players turns: that's why I had the check on the client side. Check if I am the active player first, and if I am, then let me progress the turn.

Hope that makes sense.

avatar image Tinyted Jul 07 '16 at 10:10 AM

Oh hmm. I was expecting something like an RPC https://docs.unrealengine.com/latest/INT/Gameplay/HowTo/Networking/ReplicateFunction/Blueprints/#runonserver

Just for further debugging, you could consider adding in print logs for OnRep_Notify (Related blueprint doc: https://docs.unrealengine.com/latest/INT/Gameplay/HowTo/Networking/ReplicateVariable/Blueprints/#repnotify) to see when the clients are being replicated the value or they are even replicated the value at all. I also noticed that you didn't seem to be logging out what the server says is the active player, only what the clients are saying. Could you check that also, since its what the server has that's most important.

avatar image Zerve Jul 07 '16 at 02:35 PM

Solved the issue. I was stupidly accessing the wrong array which was why the data was incorrect. Derp. Wasn't an issue with any of the code in here. That's what happens when you code on a lack of sleep.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question