Empire of Gold: New Conquest — Game Spec & Implementation Notes

Status: Implemented GameId: empireofgoldnewconquest Math file: empire-of-gold-new-conquest-R3.json Math modes: R3 Pack: pack-alpha

1. Overview

Variant of empireofgold. Mechanically identical except for one addition: a passive base-game metamorphic feature ("Symbol Change" / "Symbol Replacement") that can upgrade all instances of a selected low-paying symbol into a selected high-paying symbol under specific conditions.

All other mechanics (cluster pay, cascades, free-spin trigger, multipliers, ANTE stacks, buy-bonus trigger, buy-bonus) are unchanged from empireofgold.

2. Symbol Change Feature

2.1 Rules

The feature runs on the initial reel view of a base-game spin, after reel generation (and after any ANTE stack replacement, though it only runs in BG anyway) and before pay evaluation.

Algorithm:

  1. Pick one low symbol selectedLow from SymbolChange_LowWeights (L1:15, L2:15, L3:20, L4:20, L5:18).
  2. Pick one high symbol selectedHigh from SymbolChange_HighWeights (H1:10, H2:25, H3:25, H4:25).
  3. Count occurrences of selectedLow and selectedHigh on the reel view.
  4. If count(selectedLow) + count(selectedHigh) <= 7 then do nothing.
  5. Else roll SymbolChange_TriggerWeights (Yes:1 / No:49, ~2% Yes). On No → do nothing.
  6. On Yes → replace every cell equal to selectedLow on the reel view with selectedHigh.

2.2 Scope

Runs in BG only. Does not run in:

  • ANTE (ante bet)
  • BB_Trigger (buy-bonus trigger spin)
  • Free spins (FG) or buy-bonus (BB) — the feature hook lives in engine.executeSpin which is not invoked for free spins; they run via engine.executeFeature → logic.runFeature.

2.3 Cascade behavior

Runs exactly once per spin, on the initial reel view only. Does NOT re-run on any cascade following a win within the same spin.

2.4 Counting rules

  • Straight cell-equality match against selectedLow / selectedHigh (plain string compare).
  • SC (scatter) and BN (bonus) cells are naturally excluded because they never equal L* / H* symbols.
  • At the point this feature runs, no BN_<mult> suffix has been applied yet (those are added later inside the cascade loop), so no special-casing is needed.

2.5 Math weight tables (source of randomness)

All three live under BG in the math JSON in the 2D shape used by @slot-platform/sdk getRandomValue<T>:

"SymbolChange_HighWeights": [["H1","H2","H3","H4"], [10,25,25,25]],
"SymbolChange_LowWeights":  [["L1","L2","L3","L4","L5"], [15,15,20,20,18]],
"SymbolChange_TriggerWeights": [[true,false], [1,49]]

The trigger table uses booleans (not the raw "Yes"/"No" strings from the XLSX) so getRandomValue<boolean> returns a directly-usable flag.

3. Architecture & File Layout

games/empireofgoldnewconquest/
├── project.json                          # Nx lib, mode R3 for simulate
├── tsconfig.json
├── tsconfig.lib.json
└── src/
    ├── index.ts                          # exports plugin + config + types
    ├── config.ts                         # EmpireOfGoldNewConquestConfig
    ├── interfaces.ts                     # adds SymbolChangeResult + field on SpinResult
    ├── plugin.ts                         # EmpireOfGoldNewConquestPlugin
    ├── engine.ts                         # hooks applySymbolChange on BG
    ├── logic.ts                          # unchanged vs empireofgold
    ├── symbol-change.ts                  # NEW: pure helper for the feature
    └── maths/
        └── empire-of-gold-new-conquest-R3.json

Path alias (inherited from the @slot-platform/game-* glob in tsconfig.base.json): @slot-platform/game-empireofgoldnewconquest → games/empireofgoldnewconquest/src/index.ts

3.1 Dependency graph

  • Depends only on @slot-platform/sdk (tag type:game → type:sdk).
  • No NestJS dependency (same as all other games).

4. Implementation Details

4.1 engine.ts hook

In executeSpin, after reel generation and any ANTE stack replacement, and before logic.spin(...):

let symbolChange: SymbolChangeResult | undefined;
if (gameType === 'BG') {
  const sc = applySymbolChange({ reelView, mathByGameType });
  reelView = sc.reelView;
  symbolChange = sc.result;
}

const spinResult = this.logic.spin({ /* ... */ reelView, /* ... */ });

if (symbolChange) {
  spinResult.symbolChange = symbolChange;
}

gameType is already computed at the top of executeSpin and is one of 'BG', 'ANTE', 'BB_Trigger'.

4.2 symbol-change.ts

Pure function, no side effects. Never mutates the input reelView — returns a new 2D array when the feature applies, else returns the input reference.

Return value:

{
  reelView: string[][];
  result: {
    applied: boolean;
    selectedLow?: string;
    selectedHigh?: string;
    lowCount?: number;
    highCount?: number;
    triggered?: boolean;   // only set when the trigger roll actually happened
  };
}

4.3 SpinResult.symbolChange surface

Optional field on SpinResult (see interfaces.ts). Populated whenever the feature hook ran (BG only), so even a "not applied" result is visible for client / replay / simulator inspection.

Not involved in any win calculation.

4.4 Unchanged from empireofgold

  • logic.ts — identical cluster detection, cascade loop, BN multiplier logic, FS trigger, max-win cap, FS retrigger.
  • Free-spin path (engine.executeFeature → logic.runFeature) is untouched.
  • config.ts values (layout 5×6, min cluster 8, FS triggers, bets, max-win) are identical; only the exported symbol name was renamed.

4.5 Plugin registration

apps/pack-alpha/src/app.module.ts:

GameCoreModule.register([
  new EmpireOfGoldPlugin(),
  new EmpireOfGoldNewConquestPlugin(),
  new Royale81Plugin(),
]);

apps/pack-alpha/games.json:

{ "games": ["empireofgold", "empireofgoldnewconquest", "royale81"] }

The pack's webpack config auto-copies the math JSON directory for every game listed in games.json, so no webpack changes are needed.

5. Math Parser (feg_parse-maths)

New command registered in src/cli.module.ts:

  • Command name: empire-of-gold-new-conquest
  • Source file: src/commands/empire-of-gold-new-conquest.commands.ts
  • Input XLSX: ./rawMaths/empireOfGoldNewConquest/GoO added feature PAR sheet.xlsx
  • Output: ./output/empire-of-gold-new-conquest-R3.json

5.1 Sheet layout differences vs original empireofgold XLSX

The only structural change in the new XLSX is in the Base Game sheet where the "Symbol Change Feature" block was inserted at columns AJ..AN. This pushed the existing cascade weight tables right by 6 columns. All other sheets (Free Game, BuyBonus, BaB Trigger, Ante) use the same ranges as empireofgold.

KeyempireofgoldNew Conquest
BG_RallyNonRallyCascadeWeights_START_RANGEAJ21:AK22AP21:AQ22
BG_RALLY_WEIGHT_TABLE_RANGEAP27:AQ31AV27:AW31
BG_NONRALLY_WEIGHT_TABLE_RANGEAS27:AT31AY27:AZ31

5.2 New ranges for the Symbol Change feature

KeyRangeNotes
BG_SymbolChange_HIGH_WEIGHTS_RANGEAJ6:AK9H1..H4
BG_SymbolChange_LOW_WEIGHTS_RANGEAM6:AN10L1..L5
BG_SymbolChange_TRIGGER_WEIGHTS_RANGEAK21:AL22"Yes"/"No" → converted to booleans

5.3 New helper in the parser

parseWeightTableAs2D(worksheet, range) reads a 2-column Symbol|Weight block (skipping blanks) and emits [[keys], [weights]] ready for getRandomValue. Used for all three new tables. For the trigger table the "Yes"/"No" strings are mapped to true/false before emit.

5.4 Reel ranges

Same as original empireofgold. In particular, do not extend the reel ranges past their documented ends — the columns underneath the reels (H150/H118 etc.) contain numeric symbol-count statistics that would pollute the reel strips if pulled in.

6. What is intentionally NOT changed

  • Math numbers (pay table, bonus multiplier weights, cascade bracket weights, scatter pay, stack weights, reel strips, FS reels, etc.) are the same as the new XLSX provides. Where the new XLSX tables are identical to the original, the JSON values match. No manual balancing was done.
  • Free spins, ANTE, buy-bonus, buy-bonus trigger.
  • SpinResult fields other than the added symbolChange.
  • logic.ts source.

7. Known open items / heads-up

  • The XLSX caption cell reads > 8 while the screenshot originally showed > 7. The implementation uses > 7, matching the confirmed spec. If the math team wants > 8, change the single constant in games/empireofgoldnewconquest/src/symbol-change.ts.
  • No unit tests, no build verification, and no math simulation were run as part of the implementation (repo policy: only on explicit request).
Built with LogoFlowershow