Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion packages/components-shared/src/components/Authenticate.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@
import { onMount, type Snippet } from 'svelte';

import { requestAuthenticate, requestReplay } from 'rgs-requests';
import { stateUrlDerived, stateBet, stateConfig, stateModal, stateUi } from 'state-shared';
import {
stateUrlDerived,
stateBet,
stateConfig,
stateMeta,
stateModal,
stateUi,
reconcileBetModeMeta,
} from 'state-shared';
import { API_AMOUNT_MULTIPLIER, MOST_USED_BET_INDEXES } from 'constants-shared/bet';

type Props = { children: Snippet };
Expand Down Expand Up @@ -66,6 +74,15 @@
stateConfig.betMenuOptions = stateConfig.betAmountOptions.filter((_, index) =>
MOST_USED_BET_INDEXES.includes(index),
);

// Example of authenticateData.config.gameModes
// [
// { "mode": "base", "costMultiplier": 1, "maxBet": 2000000000 },
// { "mode": "bonus", "costMultiplier": 200, "maxBet": 2000000000 }
// ]
if (authenticateData.config?.gameModes?.length) {
stateMeta.betModeMeta = reconcileBetModeMeta(authenticateData.config.gameModes);
}
}

// round
Expand Down
32 changes: 32 additions & 0 deletions packages/state-shared/src/stateMeta.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,35 @@ export const stateMeta = $state({
export const stateMetaDerived = {
betModeMetaList: () => Object.values(stateMeta.betModeMeta),
};

/**
* Reconcile `betModeMeta` against the bet modes the RGS reports at authentication.
*
* `betModeMeta` defaults to a placeholder table that does not describe any
* particular game. Modes it lists that the RGS does not know are rejected with
* ERR_VAL "invalid amount" when played, and a costMultiplier that disagrees with
* the published math is wrong in the UI before it is ever sent.
*
* Server-reported modes win on identity and cost; presentation a game has already
* set (assets, copy, type) is kept for the modes that survive.
*/
export const reconcileBetModeMeta = (
gameModes: { mode: string; costMultiplier: number }[],
): BetModeMeta => {
const reconciled: BetModeMeta = {};

gameModes.forEach(({ mode, costMultiplier }) => {
const key = mode.toUpperCase();
const existing = stateMeta.betModeMeta[key] ?? stateMeta.betModeMeta[mode.toLowerCase()];

reconciled[key] = {
...(existing ?? DEFAULT_BET_MODE_META.BASE),
mode: key,
costMultiplier,
// only infer when the game has not described this mode itself
type: existing?.type ?? (costMultiplier === 1 ? 'default' : 'buy'),
} as BetModeData;
});

return reconciled;
};