MantisBT - Zandronum
View Issue Details
0000637Zandronum[All Projects] Bugpublic2011-12-18 10:072018-09-30 23:00
MytiS 
Torr Samaho 
highmajoralways
closedfixed 
MicrosoftWindowsXP/Vista/7
98d 
1.42.0 
0000637: Adding a bot breaks 'random'
Adding bots to a game breaks 'random' when it interacts with players (not entirely sure on latter part).

When a map is present in a game a script with the random function will always have random produce the same variables in the same order.
1) Enter Map01
2) Type 'addbot' in console
3) Enter teleport strip at least 3 times & record pattern

4) Type 'map map01' in console
5) Type 'addbot' in console
6) Enter teleport strip at least 3 times & record pattern

!) The random variables will be the same each time.
No tags attached.
related to 0000759closed  Random Number Generator resets on map change, losing randomness 
zip randombot.zip (10,118) 2011-12-18 10:07
/tracker/file_download.php?file_id=435&type=bug
Issue History
2011-12-18 10:07MytiSNew Issue
2011-12-18 10:07MytiSFile Added: randombot.zip
2011-12-21 11:44DuskNote Added: 0002327
2011-12-21 11:44DuskNote Edited: 0002327bug_revision_view_page.php?bugnote_id=2327#r1198
2011-12-21 17:30QentNote Added: 0002328
2011-12-21 18:06QentNote Edited: 0002328bug_revision_view_page.php?bugnote_id=2328#r1200
2011-12-21 18:10QentNote Edited: 0002328bug_revision_view_page.php?bugnote_id=2328#r1201
2011-12-28 08:11Ijon TichyNote Added: 0002329
2011-12-28 15:20QentNote Added: 0002330
2011-12-28 15:35QentNote Edited: 0002330bug_revision_view_page.php?bugnote_id=2330#r1203
2012-01-12 02:37Torr SamahoNote Added: 0002354
2012-01-12 02:37Torr SamahoStatusnew => feedback
2012-01-28 20:26QentNote Added: 0002546
2012-01-29 15:38Torr SamahoNote Added: 0002552
2012-04-08 23:26unknownnaRelationship addedrelated to 0000759
2012-06-09 13:22Torr SamahoCategoryGeneral => Bug
2012-11-01 15:14unknownnaNote Added: 0005267
2012-11-01 15:16unknownnaStatusfeedback => confirmed
2012-11-01 15:34unknownnaNote Edited: 0005267bug_revision_view_page.php?bugnote_id=5267#r2884
2012-11-01 15:34unknownnaNote Edited: 0005267bug_revision_view_page.php?bugnote_id=5267#r2885
2012-11-01 15:47unknownnaNote Edited: 0005267bug_revision_view_page.php?bugnote_id=5267#r2886
2012-12-27 14:38Torr SamahoAssigned To => Torr Samaho
2012-12-27 14:38Torr SamahoStatusconfirmed => assigned
2012-12-27 14:49Torr SamahoNote Added: 0005592
2012-12-27 14:50Torr SamahoNote Edited: 0005592bug_revision_view_page.php?bugnote_id=5592#r3061
2012-12-27 14:50Torr SamahoNote Revision Dropped: 5592: 0003060
2012-12-27 14:51Torr SamahoStatusassigned => feedback
2013-11-12 21:34WatermelonNote Added: 0007544
2013-11-12 21:34WatermelonNote Edited: 0007544bug_revision_view_page.php?bugnote_id=7544#r4205
2014-10-12 16:49WatermelonNote Added: 0010547
2014-10-12 17:01Torr SamahoNote Added: 0010549
2015-01-21 10:35Edward-sanNote Added: 0011473
2015-01-21 11:15Edward-sanNote Edited: 0011473bug_revision_view_page.php?bugnote_id=11473#r6479
2015-01-21 11:20Edward-sanNote Edited: 0011473bug_revision_view_page.php?bugnote_id=11473#r6480
2015-01-21 14:17Edward-sanNote Edited: 0011473bug_revision_view_page.php?bugnote_id=11473#r6481
2015-01-21 14:22Edward-sanNote Edited: 0011473bug_revision_view_page.php?bugnote_id=11473#r6482
2015-01-21 14:31Edward-sanNote Edited: 0011473bug_revision_view_page.php?bugnote_id=11473#r6483
2015-01-21 14:32Edward-sanNote Edited: 0011473bug_revision_view_page.php?bugnote_id=11473#r6484
2015-01-21 16:43Edward-sanNote Edited: 0011473bug_revision_view_page.php?bugnote_id=11473#r6487
2015-01-21 16:44Edward-sanNote Edited: 0011473bug_revision_view_page.php?bugnote_id=11473#r6488
2015-01-21 18:50Torr SamahoNote Added: 0011480
2015-01-21 20:21Edward-sanNote Added: 0011486
2015-01-21 20:37Edward-sanNote Edited: 0011486bug_revision_view_page.php?bugnote_id=11486#r6494
2015-01-22 17:34Edward-sanStatusfeedback => needs review
2015-01-22 21:53Torr SamahoNote Added: 0011506
2015-01-22 21:54Torr SamahoNote Edited: 0011506bug_revision_view_page.php?bugnote_id=11506#r6504
2015-01-23 01:31Edward-sanNote Added: 0011509
2015-01-25 09:15Torr SamahoNote Added: 0011522
2015-01-25 09:15Torr SamahoStatusneeds review => needs testing
2015-01-25 11:46cobaltTarget Version => 1.4
2015-01-25 11:46cobaltDescription Updatedbug_revision_view_page.php?rev_id=6528#r6528
2015-01-25 11:46cobaltSteps to Reproduce Updatedbug_revision_view_page.php?rev_id=6530#r6530
2015-01-25 11:46cobaltNote Added: 0011533
2015-03-29 20:20DuskStatusneeds testing => resolved
2015-03-29 20:20DuskFixed in Version => 2.0
2015-03-29 20:20DuskResolutionopen => fixed
2018-09-30 23:00Blzut3Statusresolved => closed

Notes
(0002327)
Dusk   
2011-12-21 11:44   
ACS random() doesn't seem to be very random anyway. In AOW2 the powerup crate favors some effects over others per match - it does a single random(1, 64); call to determine the effect. Therefore, the random() function seems to want to give a certain value over others per games...

(0002328)
Qent   
2011-12-21 17:30   
(edited on: 2011-12-21 18:10)
I believe that this has to do with seeding and keeping the client and server random calls in sync. If you host this WAD online, you do not need to add a bot to make the sequence predictable.

@ Nightfall, I don't think that's true. Here is the data from 1000000 calls to Random(0, 63):

#: Count
0: 15144
1: 15650
2: 15567
3: 15541
4: 15436
5: 15502
6: 15504
7: 15571
8: 15726
9: 15843
10: 15545
11: 15545
12: 15627
13: 15687
14: 15687
15: 15559
16: 15736
17: 15781
18: 15821
19: 15492
20: 15676
21: 15795
22: 15722
23: 15630
24: 15610
25: 15800
26: 15803
27: 15556
28: 15363
29: 15689
30: 15554
31: 15716
32: 15564
33: 15860
34: 15833
35: 15619
36: 15757
37: 15637
38: 15266
39: 15669
40: 15437
41: 15565
42: 15765
43: 15734
44: 15588
45: 15611
46: 15810
47: 15532
48: 15470
49: 15672
50: 15667
51: 15690
52: 15567
53: 15611
54: 15493
55: 15483
56: 15569
57: 15674
58: 15672
59: 15752
60: 15716
61: 15664
62: 15583
63: 15592
Average: 31.516
Std. dev.: 18.455

(0002329)
Ijon Tichy   
2011-12-28 08:11   
@Qent:
I'm confused as to how keeping the client and server seeds in sync would cause the first seeding to become predictable. Obviously, this predictable seeding is there (when playing Synert's Hangman online, you'll notice that a sequence of words comes up on a new map), but how would syncing screw up the original seed generated by the server (which I assume is the current time, possibly combined with the bytes at some memory addresses to throw a bit of entropy in)?
(0002330)
Qent   
2011-12-28 15:20   
(edited on: 2011-12-28 15:35)
I haven't a clue, but it only happens online and I can't think of another excusable reason to keep the same seed around. I'm sorry if you got the impression I had based it on anything concrete.

(0002354)
Torr Samaho   
2012-01-12 02:37   
FYI, the seed for the ACS random function is not synced between clients and server. Can you check if adding a player (i.e. letting a new player join) leads to the same behavior?
(0002546)
Qent   
2012-01-28 20:26   
Online, random behaves non-random even before adding a bot/player.
(0002552)
Torr Samaho   
2012-01-29 15:38   
How does ZDoom multiplayer behave in this regard?
(0005267)
unknownna   
2012-11-01 15:14   
(edited on: 2012-11-01 15:47)
In ZDoom you can only use "changemap" online. The example WAD seems to work fine there. And it doesn't break in ZDoom when you add a bot.

Edit:

This breaks when multiplayer emulation is enabled or when playing online. It doesn't matter whether bots are present or not.

(0005592)
Torr Samaho   
2012-12-27 14:49   
(edited on: 2012-12-27 14:50)
This behavior is inherited from ZDoom. In does the following in G_InitNew in g_level.cpp:

        if (!netgame)
        { // [RH] Change the random seed for each new single player game
            rngseed = rngseed + 1;
        }

Zandronum checks "( NETWORK_GetState( ) == NETSTATE_SINGLE )" instead of "!netgame", this explains why adding a bot changes this behavior (it changes the state to NETSTATE_SINGLE_MULTIPLAYER). Can somebody check why ZDoom does this?

(0007544)
Watermelon   
2013-11-12 21:34   
Whenever "map maplump" is called, the seed seems to reset itself regardless of compat_oldrandom, and the calls are always the same.

I was running a wad that generates random map numbers, whenever the map ended or map maplump was called, would get this:

20
32
19
5
...

Something is not making the server's seed work randomly. I tried offsetting the seed with this function:

    randomSeedSet++; // Global variable set to 0 on start
    int modificationFactor = Timer() + randomSeedSet + PlayerCount();
    int randNum = random(modificationFactor + a, modificationFactor + b) - modificationFactor;
    return randNum;


Doing this did not help.



I implemented in ACS the Xorshift algorithm ('http://en.wikipedia.org/wiki/Xorshift [^]' ) which works really well, I seed it with Timer() based on the first join and it's usually good enough to work from there.

Would be nice to have a new completely random seed from the very beginning though.

(0010547)
Watermelon   
2014-10-12 16:49   
Quote
Zandronum checks "( NETWORK_GetState( ) == NETSTATE_SINGLE )" instead of "!netgame", this explains why adding a bot changes this behavior (it changes the state to NETSTATE_SINGLE_MULTIPLAYER). Can somebody check why ZDoom does this?


How could we check it? Do you mean PM'ing Randy, or asking on the forums? Or investigating the code?
(0010549)
Torr Samaho   
2014-10-12 17:01   
I'd say asking on the ZDoom forums is the easiest way.
(0011473)
Edward-san   
2015-01-21 10:35   
(edited on: 2015-01-21 16:44)
Uh, was it asked in the forum, in the end? I can't find it..

[edit] Asked on irc:


<edward-san> does someone know why zdoom changes the random seed, when using changemap, only in single player?
<Edward850> Changemap shouldn't change the seed?
<Edward850> It doesn't reset the session, so it shouldn't even touch the RNG.
<edward-san> I ask this because of'http://zandronum.com/tracker/view.php?id=637#c5592 [^]'
<Edward850> Yeah, just checked, changemap doesn't touch the RNG state.
<Edward850> Only G_InitNew does.
<edward-san> ah
<edward-san> is G_InitNew called just when doing a new game, ie 'map'?
<Edward850> Now, yes, netgames and demos wont have their seed reset from G_InitNew, true, but they also can only ever call it once anyway.
<Edward850> Yes.
<Edward850> At no point should G_InitNew be called in the middle of a valid netgame, so either Zandro is resetting a netgame (which sounds pointless as it has no reason to. It can't even load net saves.) or it's calling G_InitNew in situations where there is no actual new game.
<Edward850> Or it somehow thinks a netgame is an offline session?
<Edward850> Which makes absolutely 0 sense seeing as it doesn't support listen servers.


so I'm literally confused on the correlation between this issue and G_InitNew..

[edit2] From what I know, in zdoom multiplayer, G_InitNew is called only once when the game starts. Also, the check is there, because the seed is generated by the arbitrator and passed to the other nodes during the handshake, so the seeds are synced very well.

Other info: netgame is true only in the 'real' multiplayer (for example, if you use 'zdoom -host 1', netgame is off, but 'multiplayer' (the bool value) is true), so in case of zandronum, '!netgame' should be equivalent to have NETSTATE_SINGLE || NETSTATE_SINGLE_MULTIPLAYER.

Other info(2): zdoom doesn't allow 'map' map change in netgame mode, and if you use 'map' in '-host 1' mode, multiplayer will be turned off and the game resets to single player mode, so this is why, I suppose.

[edit3] Hence, I suppose we can allow the random seed increment to all the network states, or make sure the server regenerates it with 'I_MakeRNGSeed()', since the game state is reset. If you're interested, I can make a patch for this.

(0011480)
Torr Samaho   
2015-01-21 18:50   
Aren't we only talking about "map" map changes here? See "Steps To Reproduce".

From what I can tell, G_InitNew is only called when using a "map" map change. So Zandronum is behaving the same as ZDoom in this regard. What is different, based on your findings, is that in ZDoom "map" map changes simply do not exist in multiplayer games.

So, based on 0000637:0011473, I'd say the correct solution is to change the snipped I mentioned in 0000637:0005592 to

            if ( ( NETWORK_GetState( ) == NETSTATE_SINGLE ) || ( NETWORK_GetState( ) == NETSTATE_SINGLE_MULTIPLAYER ) || ( NETWORK_GetState( ) == NETSTATE_SERVER ) )
            { // [RH] Change the random seed for each new single player game
                rngseed = rngseed + 1;
            }
(0011486)
Edward-san   
2015-01-21 20:21   
(edited on: 2015-01-21 20:37)
Made a new commit, works fine with the example wad offline, multiplayer emulated and online.

[edit] While I'm at it, I noticed two unsequenced calls to P_Random() in the Doom original random numbers handling. See this other commit for details.

(0011506)
Torr Samaho   
2015-01-22 21:53   
(edited on: 2015-01-22 21:54)
Thanks! After seeing the code in the diff, I realized a much shorter way for the very same thing is

if ( NETWORK_GetState( ) != NETSTATE_CLIENT )
{ // [RH] Change the random seed for each new single player game
    rngseed = rngseed + 1;
}


Quote from Edward-san

While I'm at it, I noticed two unsequenced calls to P_Random() in the Doom original random numbers handling.

Interesting finding. I guess it can't hurt to fix the sequence like you suggested.

(0011509)
Edward-san   
2015-01-23 01:31   
Ok, updated the fix.
(0011522)
Torr Samaho   
2015-01-25 09:15   
I pulled the updated fix.
(0011533)
cobalt   
2015-01-25 11:46   
Issue addressed by commit 0ec3e4366554: - Fixed: Emulated multiplayer and multiplayer map changes broke random (fixes 637).
Committed by edward_san [edward-san] on Friday 23 January 2015 02:29:49

Changes in files:
 docs/zandronum-history.txt | 1 +
 src/g_level.cpp | 3 ++-
 2 files changed, 3 insertions(+), 1 deletions(-)