Loot — Core / Internal¶
Folder Overview¶
The two random sources LootService chooses between.
Both are internal. They are not an extension point — IRandomProvider is, and it lives in Core.Abstractions. Supply your own implementation there if you need a different source.
Purpose¶
Loot needs two different things from randomness at different times, and one implementation cannot be both:
- Reproducible, so a drop-rate check means something and a bug report can be replayed.
- Ordinary, so a shipped game is not accidentally running every player on the same seed.
What Lives Here¶
SeededRandomProvider¶
Xorshift, seeded, fast. Installed by LootService.UseDeterministicRng(seed).
Returns values in [0, 1) — never exactly 1. Seed 0 is remapped, because xorshift cannot start from zero and would otherwise return 0 forever.
UnityRandomProvider¶
The default. Backed by UnityEngine.Random.value.
Returns values in [0, 1] — inclusive of 1. It also draws from Unity's global random state rather than holding its own, so results depend on whatever else in the project draws from it and are not reproducible across runs.
Important Notes¶
The two providers do not share an upper bound¶
SeededRandomProvider is half-open. UnityRandomProvider is closed. Swap one for the other and a comparison written against the wrong assumption changes behaviour at exactly one input — which is the least likely value to appear in a test and the most likely to appear across a million player sessions.
LootRoller therefore treats Value01() as inclusive at both ends everywhere it consumes one, and handles the boundaries explicitly rather than by comparison. If you write your own IRandomProvider, either bound is acceptable; the roller does not care which you pick, only that it never assumes.
Determinism does not survive a change to draw order¶
The seeded provider replays a sequence. Reordering the values a roll consumes, or short-circuiting a draw that used to happen, changes every result after that point even with the seed unchanged. That is why the roller draws unconditionally rather than skipping work it could skip.