random: port Alea, one generator per character

pqcli used Python's global Mersenne Twister, seeded once from the clock.
Upstream uses Johannes Baagøe's Alea, with Random(n) = uint32() % n, and
keeps the generator state with each character. The port matches the JS
output bit for bit, including UTF-16 seeding of non-BMP characters.

Each Player now owns an Alea that is pickled with the save, and
Simulation.tick draws from it. Saves without one get a fresh generator.
As upstream does, a new character's game continues from the state the
kept stat roll was made from.

The parity traces are re-recorded, since every random number changes.
This commit is contained in:
Dash committed 2026-10-17 15:55:50 +02:00
1 parent f1cdff8140
commit 9c44d69633
11 files changed
+5741 -5452

No files matched your search

+5 -1
View File
@@ -124,7 +124,11 @@ class BasicUserInterface(BaseUserInterface):
break
player = create_player(
name=name, race=race, class_=class_, stats=stats
name=name,
race=race,
class_=class_,
stats=stats,
seed=stats_builder.seed,
)
self.roster.players.append(player)
if auto_play and self.confirm(