All extensions

@open-rgs/markov

Changes how clumpy reels look. Provably does not change frequency.

One knob for feel

Independent draws give exact frequency and no adjacency, so reels never feel like reels. Strips give adjacency but tangle it with frequency. A Markov chain over each column gives both, separately.

s = 0
s = 0.8
Two columns, same symbols, same rates. Only the runs differ.
import { stackyFill } from "@open-rgs/markov";

const BASE = { LOW: 60, MID: 30, HIGH: 10 };

const flat   = stackyFill(SHAPE, BASE, 0);
const stacky = stackyFill(SHAPE, BASE, 0.8);

Frequency does not move

Under sticky(base, s) the chain's stationary distribution is exactly base, for every s below 1. So stickiness is a pure feel knob - turn it up for stacks and your RTP does not shift.

=
The chain settles on the base distribution, whatever the stickiness.
import { sticky, stationary } from "@open-rgs/markov";

stationary(sticky(BASE, 0.9));

How tall are the stacks

Run length is what stickiness is actually tuned against, and guessing it from spin footage is slow. It is a geometric distribution, so it has a closed form.

High stickiness produces natural stacks, the one thing a strip gave you.
import { meanRunLength, transitions } from "@open-rgs/markov";

meanRunLength(BASE, 0.35, "HIGH");

transitions({ A: { A: 75, B: 25 }, B: { A: 75, B: 25 } });