Gamble Features
Gamble features allow players to risk their winnings for a chance to multiply the payout. Wager features are configured at the feature level in config.json using either wagerFeatures or wagerStakeFeatures.
Gamble features are opt-in per game. Only games with wagerFeatures or wagerStakeFeatures defined in their config support wagering. Games without wager features auto-end the round and credit winnings automatically.
Two Wager Modes
wagerFeatures — Relative Multiplier
When the engine plays a spin in a wagerFeatures feature:
- The entry's
winfield acts as a multiplier on the player's accumulated winnings win = 0means the player loses everythingwin = 2means the player doubles their winnings- The player can
collect()at any point during a wager feature to cash out
Best for: card gamble, ladder gamble — games with few wager steps where the player gambles their accumulated win.
wagerStakeFeatures — Absolute Cashout Multiplier
When the engine plays a spin in a wagerStakeFeatures feature:
- The entry's
winfield is an absolute cashout multiplier relative to the original stake win = 0means the player loses everythingwin = 1.75means the player's cashout is 1.75x their stake- The player can
collect()at any point to cash out
Best for: mines, frogger — multi-step progression games with many wager steps. This mode avoids compounding rounding errors that accumulate when applying relative multipliers across many steps.
Both types are triggered via featureAwards on base game entries and handled automatically during placeBet() continuation calls.
Configuration
Wager features are listed in the game's config.json:
{
"wagerFeatures": ["color-red", "color-black", "suit-hearts", "suit-diamonds"],
"wagerStakeFeatures": ["mines_1_pick_1", "mines_1_pick_2"],
"minWagerableWin": 1,
"maxWagerableWin": 10000
}A game can use both types simultaneously — e.g., mines progression via wagerStakeFeatures combined with card gamble via wagerFeatures.
These feature entries live in the output files alongside basegame and other features.
Available Wager Features
Wager features are returned in the loadConfig response:
const config = await loadConfig({ backendURL, token });
if (config.success) {
const wagerFeatures = config.result.config.wagerFeatures;
if (wagerFeatures) {
console.log(wagerFeatures);
// e.g. ["color-red", "color-black", "suit-hearts", ...]
}
}Game Flow
When a base game spin awards a win eligible for wagering, the engine sets canCollect = true and sends the available gamble options as playerChoice entries in engineData:
{
"entryIndex": 1,
"scenarioInfo": { "scenarioIndex": 34, "currentScenarioIndex": 0, "inProgress": false },
"inProgress": true,
"canCollect": true,
"playerChoice": [
{ "feature": "step_1", "count": 1 },
{ "feature": "color-red", "count": 1 },
{ "feature": "color-black", "count": 1 },
{ "feature": "suit-clubs", "count": 1 },
{ "feature": "suit-diamonds", "count": 1 },
{ "feature": "suit-spades", "count": 1 },
{ "feature": "suit-hearts", "count": 1 }
]
}Each playerChoice entry represents a gamble the player can take:
feature— the wager feature name (maps to feature entries)count— number of spins (always1for gambles)
The player selects a gamble by sending playerChoiceIndex with placeBet(), using the same mechanism as any other player choice. Alternatively, the player can call collect() to cash out.
import { placeBet, collect } from '@hizi.io/engine-sdk';
// Base game spin triggers a wager feature via featureAwards
const spin = await placeBet({ backendURL, token, stake });
if (spin.success) {
const { engineData } = spin.result.result;
if (engineData.canCollect && engineData.playerChoice) {
// Present the gamble options to the player
for (let i = 0; i < engineData.playerChoice.length; i++) {
const option = engineData.playerChoice[i];
console.log(`Option ${i}: ${option.feature}`);
}
if (playerWantsToCollect) {
// Cash out
await collect({ backendURL, token });
} else {
// Player chose a gamble — send the selected index
const chosenIndex = 2; // e.g. "color-black"
const wagerSpin = await placeBet({ backendURL, token, playerChoiceIndex: chosenIndex });
if (wagerSpin.success) {
const { totalWin, engineData: nextState } = wagerSpin.result.result;
if (totalWin === 0) {
// Lost — round ends
} else if (nextState.canCollect && nextState.playerChoice) {
// Won — player can collect or gamble again
}
}
}
}
}Integration Pattern
Base game spin
│
├── No wager feature → normal flow
│
└── Wager feature triggered (canCollect === true, playerChoice present)
│
├── Player collects → collect({ backendURL, token })
│
└── Player selects a gamble → placeBet({ backendURL, token, playerChoiceIndex: N })
│
├── Won (totalWin > 0, canCollect + playerChoice again)
│ │
│ ├── Player collects → collect({ backendURL, token })
│ │
│ └── Player gambles again → placeBet({ ..., playerChoiceIndex: N })
│
└── Lost (totalWin === 0) → round endsNext Steps
- Response Handling - Full response structure including
playerChoice. - Error Handling - Handle errors during gameplay.
- Endpoints - Full endpoint reference.