Skip to content

feat: client-authoritative character select #401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

fernando-cortez
Copy link
Collaborator

Description (*)

This PR introduces a more reactive flow for the local player's character select screen.

The local player's character choice is shown instantaneously, instead of previously waiting for a confirmation event from the server. This clears the local player's previous choice and sets the new seat visuals right away.

The server will still override changes for the local player when they are locked in/out, or set to inactive due to another player confirming the same player, and of course any other player's selection.

The confirm button is server-authoritative. I figure a visual update for that when waiting for server confirm can be done as a follow up to this PR.

Related Pull Requests

Issue Number(s) (*)

Fixes issue(s): MTT-1438

Manual testing scenarios

  1. ...
  2. ...

Questions or comments

Contribution checklist

  • Pull request has a meaningful description of its purpose
  • All commits are accompanied by meaningful commit messages
  • All new or changed code is covered with unit/integration tests (if applicable)
  • All automated tests passed successfully (all builds are green)

@fernando-cortez fernando-cortez added the 1-Needs Review PR needs attention from the assignee and reviewers label Nov 3, 2021
var isLockedInEvent = (changeEvent.Value.SeatState == CharSelectData.SeatState.LockedIn && !m_HasLocalPlayerLockedIn) ||
(changeEvent.Value.SeatState == CharSelectData.SeatState.Active && m_HasLocalPlayerLockedIn);

if (!isLockedInEvent && changeEvent.Value.SeatIdx != -1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic number, should be a const somewhere (also other -1 should use that const)

// has been reset to -1 (both server-authoritative)
if (changeEvent.Value.ClientId == NetworkManager.Singleton.LocalClientId)
{
var isLockedInEvent = (changeEvent.Value.SeatState == CharSelectData.SeatState.LockedIn && !m_HasLocalPlayerLockedIn) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we use local values for locked in? With server authority, we should only take the server value as the authoritative value and never rely on local values

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So on OnPlayerClickedSeat(..), that's where the local player makes their anticipated selection, but also sends a ServerRpc for that change to be applied by the server to the NetworkList, which is then replicated to other clients.

Since the local player will still receive that same change event, I need to identify if it's just a local character selection change which can be ignored. What shouldn't be ignored is seat status changes.

NetworkListEvent doesn't provide that granularity on exactly what value was modified, so I'd need to compare it against something locally, no?

I could also be comparing it against the current seat from m_PlayerSeats, since that is what is actually modified before the ServerRpc is sent. But that's still also something stored locally.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discussed IRL, should have previous value coming from SDK, need following up with Fatih

{
var otherPlayerSharesSeat = false;

// if any other user shares seat, set them as owner; else deactivate seat
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"owner"? I thought the lockedIn state was server driven?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a player chooses a new seat, I need to clear the local player's previous seat selection from the UI. But sometimes that seat is shared by another player.

Whether that previous seat now becomes empty, or "held" by another player is determined by the last update that was received by the server on the seats.

{
// populate this seat with a shared player's lobby player state
otherPlayerSharesSeat = true;
m_PlayerSeats[m_LastSeatSelected].SetState(lobbyPlayer.SeatState, lobbyPlayer.PlayerNum, lobbyPlayer.PlayerName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're to show this in doc, let's rename m_PlayerSeats. I had to go to definition to figure out this was UI elements only (since it has a "SetState" method, I thought this was a netvar of some sort)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth to note too that we're doing a pass over all seats. This serves as a sort of "merge conflict resolution" where instead of just trying to apply deltas, we're resetting everything.

}

// get local player, and populate the seat that is anticipated to be taken
TryGetLobbyPlayer(NetworkManager.Singleton.LocalClientId, out var localLobbyPlayerState);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be worth to note this is the client drive part where we take the seat without waiting for the server driven value

@fernando-cortez
Copy link
Collaborator Author

fernando-cortez commented Jan 4, 2022

State of PR: fix containing a NetworkListEvent's previous value has been merged to Netcode's develop branch. However, it was not included as part of pre.4 release.

Will place on hold until Netcode SDK version has been upgraded.

@fernando-cortez fernando-cortez added 4-On Hold PR can't proceed because it's blocked or is otherwise waiting on something. and removed 1-Needs Review PR needs attention from the assignee and reviewers labels Jan 4, 2022
@SamuelBellomo SamuelBellomo added 2-Reviewed with Comments PR requires owner's attention and removed 4-On Hold PR can't proceed because it's blocked or is otherwise waiting on something. labels Feb 1, 2022
@fernando-cortez
Copy link
Collaborator Author

Moving this to blocked. Awaiting possible refactors to NetworkVariable implementation.

@fernando-cortez fernando-cortez added 4-On Hold PR can't proceed because it's blocked or is otherwise waiting on something. and removed 2-Reviewed with Comments PR requires owner's attention labels Feb 2, 2022
@SamuelBellomo
Copy link
Contributor

So coming back to this, an owner netvar solution might still be weird. After discussions with Luke, we'd still need a server driven network list to manage locked in state, with an additional owner netvar for selection. Syncing between the two could be weird and buggy. Owner netvars can't be corrected by the server, so we'd effectively need to sync the network list and the owner netvar's state, with all the latency in between.
With client driven movements coming, not sure showing this example would still have value? Let's keep it until we have merged other client driven stuff.

@SamuelBellomo
Copy link
Contributor

Adding this for all PRs that have been opened since this new flow has been added. Please add your changelog here project changelog file and/or package changelog file

1 similar comment
@SamuelBellomo
Copy link
Contributor

Adding this for all PRs that have been opened since this new flow has been added. Please add your changelog here project changelog file and/or package changelog file

@fernando-cortez fernando-cortez deleted the feature/client-authoritative-character-select branch December 15, 2022 19:17
@fernando-cortez fernando-cortez restored the feature/client-authoritative-character-select branch December 15, 2022 19:17
@fernando-cortez fernando-cortez deleted the feature/client-authoritative-character-select branch May 9, 2023 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4-On Hold PR can't proceed because it's blocked or is otherwise waiting on something.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants