All extensions

@open-rgs/pay-lines

Longest run, paid once.

Anchored, and paid once

A payline is a row index per column. Evaluation walks it left to right and pays the longest qualifying run - paying every prefix as well roughly doubles a game's RTP.

A run must be anchored at the leftmost reel.
import { evalLines, rowLines } from "@open-rgs/pay-lines";
import { totalMultiplier } from "@open-rgs/paytable";

const LINES = rowLines(5, 3);

const wins = evalLines(grid, LINES, PAY, { roles });
totalMultiplier(wins);

A wild-opening run is ambiguous

It can be read as the wild's own symbol or as whatever it substitutes for further along. The convention is to pay whichever is worth more; reading it only as the wild silently underpays the best board in the game.

=5×A
The reading worth more is the one that pays.

Both ways compete

A game paying from either end evaluates both directions and keeps the better one. Paying both would double-count a run that spans the whole grid.

from the right
The two directions compete rather than accumulate.
const wins = evalLines(grid, LINES, PAY, { roles, bothWays: true });

evalLine(grid, [2, 2, 2, 2, 2], PAY, { roles });