Skip to content
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

Initial infection is out of order #126

Closed
bretonium opened this issue Mar 14, 2019 · 7 comments · Fixed by #134
Closed

Initial infection is out of order #126

bretonium opened this issue Mar 14, 2019 · 7 comments · Fixed by #134
Labels
bug Something isn't working high priority This issue has higher priority in progress will be fixed soon

Comments

@bretonium
Copy link
Collaborator

bretonium commented Mar 14, 2019

Steps to reproduce:

  1. Join a server
  2. Wait till more people join
  3. Join as spectator and wait for rounds to switch

Expected: initial infected are chosen in order
Observed: after some time, almost always one person gets selected to become initial zombie

This is not reproducible on oi8306. This is reproducible on test oi8306 or any other server based on current master.

@bretonium
Copy link
Collaborator Author

bretonium commented Mar 15, 2019

Can you elaborate on what seems incorrect? I don't understand the issue.

If there are players A, B, C, D and player S is spectating, instead of infecting [A, B], then [C, D], then [A, B], one of the players, for example, A will always be chosen to become initial zombie and initial infected will be [A, B], [A, C], [A, D].

If people leave the game and rejoin the game from spectators, they will be zombie next round.
Nothing wrong with that.

The steps do not mention people reconnecting

@teoman002 teoman002 added the bug Something isn't working label Mar 15, 2019
@teoman002 teoman002 added in progress will be fixed soon and removed in progress will be fixed soon labels Mar 18, 2019
@bretonium bretonium reopened this Mar 23, 2019
@bretonium
Copy link
Collaborator Author

diff --git a/src/game/server/gamemodes/mod.cpp b/src/game/server/gamemodes/mod.cpp
index e393405..9546ec8 100644
--- a/src/game/server/gamemodes/mod.cpp
+++ b/src/game/server/gamemodes/mod.cpp
@@ -219,9 +219,19 @@ void CGameControllerMOD::Tick()
                        }
                        
                        int NumNeededInfection = NumFirstInfected;
-                       
+
                        while(NumInfected < NumNeededInfection)
                        {
+                               // before infecting those who play, mark spectators as
+                               // already infected. It will prevent issue causing a
+                               // player getting infected several times in a row
+                               CPlayerIterator<PLAYERITER_SPECTATORS> IterSpec(GameServer()->m_apPlayers);
+                               while(IterSpec.Next())
+                               {
+                                       IterSpec.Player()->SetClass(PLAYERCLASS_NONE);
+                                       Server()->InfecteClient(IterSpec.ClientID());
+                               }
+
                                float InfectionProb = 1.0/static_cast<float>(NumHumans);
                                float random = random_float();

I came up with the following patch on my server

@teoman002
Copy link
Collaborator

teoman002 commented Mar 24, 2019

My assumption is that If a client is tagged with "m_WasInfected" which is a consequence of InfecteClient(), then this client can't get infected the next round.
Do we want that spectators can't get infected after they rejoin the game?

@bretonium
Copy link
Collaborator Author

bretonium commented Mar 24, 2019

Do we want that spectators can't get infected after they rejoin the game?

This is a bug, yes. I think this bug is "better" than one client always getting infected.

ok your code contains a new bug, you just have to infect the character, not the client!

I don't understand. What is the consequence of the bug? How does it affect the behavior?

@bretonium
Copy link
Collaborator Author

#140 made things much worse. In a 1vs1 game 1 player always becomes zombie. To illustrate, if there are players A and B, then initial infected sequence will look like this: A, A, A, A, A, ... . #140 should be reverted as soon as possible.

@bretonium
Copy link
Collaborator Author

Here is a great example of current infection system. Note that nobody joined or left the game.
Screenshot_20190328_161009

7 people played and 3 were spectating. astral@fedora got infected 3 out of 5 times. Camperbob - 2 / 5. Suifiaw - 2 / 5. Hallo - 2 / 5. Prototype - 1 / 5. Why 2 other players never were infected is a mystery.

One of the players, who was never infected in that round, had id 1 and played for 4 rounds in the next map, and was never infected again.

This bug is major and discourages people who get infected out of order to play.

@teoman002 teoman002 added the high priority This issue has higher priority label Mar 28, 2019
@teoman002
Copy link
Collaborator

teoman002 commented Mar 28, 2019

Thanks for further details.
I think I need some help from @yavl
@bretonium do you think that this will be fixed, if spectators have nothing to do with the infection process anymore?
I think the unfair infection random chooser is broken and does not generate proper random numbers, so that part has to be rewritten as well.

feature outline:

after infection trigger

  • infect all spectators, so spectators won't interfere with game mechanic

initiation 1:

  • every ClientID that is allowed to be infected will be added to an vector1
  • do not add zombies
  • do NOT add clientID if client wasInfectedBefore
  • NumActiveInfected contains number of NbActivePlayers minus NbHumans

fair infection process:

  • there has to be always 1 human left after initial infection or game will end
  • while (vector1.size > 1 && NumActiveInfected != NeededInfected)
  • generate true random numbers in the range of vector slots
  • traverse vector and infect a slot
  • delete this slot, repeat

initiation 2:

  • every ClientID that is allowed to be infected will be added to an vector
  • do not add clientID spectators can't be infected
  • do not add zombies
  • DO add clientID if client wasInfectedBefore

unfair infection process:

  • while (vector2.size > 1 && NumActiveInfected != NeededInfected)
  • generate true random numbers in the range of vector slots
  • traverse vector and infect a slot
  • delete this slot, repeat

Repository owner deleted a comment from bretonium Mar 29, 2019
@teoman002 teoman002 added the in progress will be fixed soon label Apr 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working high priority This issue has higher priority in progress will be fixed soon
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants