Help with external die roller

First off, if I suspected an opponent was employing such tactics to cheat, I would resign from such a game. It is simply no fun playing against a cheater.

It seems to me, that what one would like to accomplish is, that after an player as played back a log file (or loaded a save file), that the new player must continue immediately and without interruption, so that the die rolls (and other random numbers) cannot be tampered with.

What that means, is in some sense that the second player (and later) must continue to use the same random number sequence (i.e., the same random number generator seed), or some sequence which comes from a predictable seed. Then, the first player can check, given the seed that was used originally, that the sequence of random numbers used by the second player, is the same or predictable as the one used by the first player.

In practise, this could look like

  1. Player A starts a game
  2. A starts a log file - say A1.vlog
    • This will put the currently used seed - say sA1 - into the log file
  3. A generates random numbers
    • Each random number is written to the log file, irrespective of whether it corresponds to a die roll or some other random thing. In this way, the sequence of random numbers is documented in the log file.
  4. A ends the log file
  5. A sends the log file to player B

Now it is player Bs turn

  1. Player B opens the log file A1.vlog
    • Vassal will, as part of reading the log file, see the seed - sA1 - written down in step 2 above.
    • The Random number generator is seeded with that seed sA1.
  2. B starts to step through the log file A1.vlog
    • When ever A made a random number, it is read in from the log file. Vassal can now check, that given the above seed - sA1, that the random number read in is indeed the next random number in the sequence of random numbers - simply by drawing an equivalent random number from the random.
      • If the random number read from the log file matches the generated random number, then all is good.
      • If the random number read from the log file does not match the generated random number, then something is a miss and the problem is reported (an exception is thrown).
  3. Once B has stepped through the log file, B then immediately opens up a new log file - say B1.vlog.
    • As above, that means that the current seed should be written to the log.
      • However, there’s a bit of a caveat here, as we cannot reuse the old seed - sA1 (otherwise we’d need to know the full sequence of random numbers, which will no be in the newly started log file).
      • So instead, we draw one random number - say iB1 (a long) using the current seed (the one read from the log file) and write that to the log file.
      • Furthermore, we use that random number as the new seed - sB1 - from the random number generator, and we then write that seed to the log.
        • While we made a new seed - sB1, the seed we created is derived from the previous seed - sA1, and therefore we can check, later on, that that seed is as expected.
        • Had we simply generated a new seed, then we’d be back to the situation where a player may restart logs until favourable outcomes are achieved).
  4. B now generates random numbers and these are written to the log file, just like above.
  5. B ends the log file - B1.vlog and sends it to A.

Now comes the part where we check that things are consistent

  1. A Opens up its own log file A1.vlog first
    • This reinitialises the Random number generator with the seed in that log file - sA1.
  2. A then fast-forwards through the log file.
    • As above in 7, this will read in the random numbers and check if they are indeed in the sequence (and in order) of the Random number generator given the seed sA1
  3. Once A has stepped through the log file A1.vlog, the game is back to the state in step 4 above.
    • But crucially the current random number seed is set to the read seed - sA1, and we have replayed the sequence of random numbers to the same point as in step 4 above.
  4. A now opens the log sent by B - B1.vlog
    • This means that the random number generated in step 8 above - iB1 - using the seed sA1 is read in. We can therefore check that that random number is the expected random number - as in step 7 above.
    • Opening the log also means we read in the seed - sB1 - set in step 8 above, and we seed the Random number generator with that seed.
  5. A nows steps through the log file B1.vlog
    • As in step 7 above, every time we see a random number in the log file - generated from the seed sB1, which we are currently also using, we check if that read random number matches the next random number in the current Random number generator sequence.
  6. Once A has stepped through all of the log file B1.vlog, then A immediately starts a new log file - say A2.vlog
    • Again a new random number, given the seed sB1 is generated and written to the log
    • That random number is set as the new seed - sA2, and written to the log
  7. A does its moves, including generating random numbers from seed sA2, which are recorded in the log file.
  8. A ends the log file A2.vlog and sends it to B

Now B follows the same logic:

  1. B plays back its own log B1.vlog, so that the seed is set to sB1, and the sequence up to step 10 above is replayed.
  2. B then opens the log file A2.vlog, which first checks the random number - iA2 - based on seed sB1 - written in the log, and then reads in the new seed sA2.
  3. B then replayes the log and on each random number checks that it is the next random number in the sequence seeded in sA2.
  4. B starts a new log - B2.vlog, generates a random number based on sA2, and sets that as the seed - sB2.
  5. B makes random numbers, based on seed sB2
  6. B Closes the log and sends it back to A

In this way, there’s a consistency check on every step, that the sequence of random numbers is ultimate derived from the initial seed - sA1 - possibly via intermittent seeds - sB1, sA2, sB2, sA3, …, which them selves are derived - in a predictable fashion from the first seed sA1. The “trick” is to use the fact that pseudo random number generators are just that - pseudo - and they will always produce the same sequence of random numbers given the same starting point (seed).

The benefit of this approach, in so far as it works and can be implemented in Vassal, is that it is entire self-contained and does not require external services or the like. That also means that reading and writing log files does not require an internet connection.

Note, if no seed is seen in a log file, then no checks are performed. This would be to support older log files. Also note, that the logic carries over to on-line games, as an online game is really just a live replay of a log file. In an online game, all players will use the same seed and they will all see the same sequence of random numbers so they can check for consistency.

Yours,
Christian