Skip to the text

The budget determines what a wave can spend. Two different selection rules determine what it buys: an index-based choice of types, followed by repeated weighted draws among those that remain affordable.

01 / THE CAST

Choose the types first

Start with the world's basic zombie bb and configured pool R0R_0. The generator selects k=4k=4 pool entries without replacement, using a bounded integer draw at each step. Weight does not participate in this choice.11Pool selection by indexThe builder adds the stage basic type, then chooses ZombieTypeCount entries from the configured pool. Each selected vector entry is removed before the next bounded draw. The baseline count is 4. Weight is not read by this selection pass.0x101ab6840

jt=ut mod ∣Rt∣,zt+1=Rt[jt],Rt+1=Rt∖{entry jt},t=0,…,k−1.\begin{aligned} j_t &= u_t\bmod |R_t|,\\ z_{t+1} &= R_t[j_t],\\ R_{t+1} &= R_t\setminus\{\text{entry }j_t\},\qquad t=0,\ldots,k-1. \end{aligned}

Removing the vector entry prevents that pool entry from being picked twice. A type with a large Weight has no larger interval in this initial draw: each remaining pool entry contributes one index.

The selected types, together with bb, become available to the ordinary filler from the first wave. The pool choice and the eventual frequency of a type are therefore separate questions.

For L>50L>50, an additional rule checks whether a selected type costs at least 1500 points. If none does, the last pool choice is replaced by a randomly chosen remaining type meeting that cost threshold. This is a WavePointCost test, not a test for the Gargantuar class.22The high-cost replacementAbove BigZombieSureExistLevel, baseline 50, the helper checks for a selected type whose WavePointCost is at least 1500. If absent, it draws from qualifying remaining pool entries and replaces the last pool selection. The predicate concerns cost, not a particular runtime zombie class.0x101ab6d78

02 / THE DRAW

Cost admits. Weight selects

Let SS be the active types. For each type ii, write cic_i for WavePointCost and aia_i for Weight. With rr points remaining, the positive-weight candidates form

A(r)={i∈S:ci≤r, ai>0},T(r)=∑i∈A(r)ai.A(r)=\{i\in S:c_i\le r,\ a_i>0\},\qquad T(r)=\sum_{i\in A(r)}a_i.

Each candidate owns an integer interval of length aia_i in a bag of size T(r)T(r). For the chosen ordering, let CiC_i be the cumulative weight before ii. A draw selects the unique interval containing dd:33The weighted integer bagThe ordinary filler drops candidates whose WavePointCost exceeds the remaining budget, draws through the integer weighted bag, appends the chosen type, and subtracts its cost. FirstWave and the separate Cost property are not inputs to these helpers. Bounded integer draws use modulo reduction; bag shares describe interval lengths, not a claim of perfectly uniform RNG residues.0x101ce7f080x100366650

d=u mod T(r),Ci≤d<Ci+ai,r←r−ci.d=u\bmod T(r),\qquad C_i\le d<C_i+a_i,\qquad r\leftarrow r-c_i.

The nominal share of the bag is ai/T(r)a_i/T(r). The bag is rebuilt as affordability changes; a type can disappear from consideration while still having a large weight. Filling ends when no positive-weight candidate fits, so the budget can leave a remainder.

Neither FirstWave nor the separate property named Cost is used by this filler. An entry's declared first wave is therefore not an additional gate on this path.

The cast: the basic type and four pool choices, with cost and weight

  • Mummy100 · 1000
  • Camel300 · 3000
  • Pharaoh450 · 3000
  • Endless Gargantuar1500 · 3000
  • Conehead Mummy200 · 3000
  1. 1,825d = 11848 of 13000Conehead Mummyd = 11848 of 13000
  2. 1,625d = 10487 of 13000Conehead Mummyd = 10487 of 13000
  3. 1,425d = 2301 of 10000Cameld = 2301 of 10000
  4. 1,125d = 3896 of 10000Cameld = 3896 of 10000
  5. 825d = 8710 of 10000Conehead Mummyd = 8710 of 10000
  6. 625d = 8331 of 10000Conehead Mummyd = 8331 of 10000
  7. 425d = 2442 of 7000Cameld = 2442 of 7000
  8. 125d = 515 of 1000Mummyd = 515 of 1000

25 points left: no type fits, so filling ends.

Plate 2.1Egypt at level 36, wave 4: the ordinary filler spends 1,825 points among the cast above in 8 draws, example seed 2. On each line the bag holds every type that still fits, each by its weight, and the draw falls in the chosen type’s interval; as the points run down, the bag loses the types it can no longer afford.

03 / THE LAST WAVE

One last inclusion attempt

The materializer tracks which selected types have appeared in earlier instructions. Before filling the final wave normally, it visits the remaining unseen types in the active set’s order. It attempts to insert them in order, subtracting each admitted cost from the remaining budget. This pass uses a strict inequality:44Strict final-wave reservationBefore normal final-wave filling, the materializer visits selected types not yet seen. A type is appended only when its cost is strictly less than the current remaining budget. The budget is reduced after each insertion, so ordering and earlier insertions affect later eligibility.0x101ce8598

Final-wave reservation:ci<r,Ordinary filling:ci≤r.\begin{array}{ll} \text{Final-wave reservation:} & c_i<r,\\ \text{Ordinary filling:} & c_i\le r. \end{array}

An exact cost match can be accepted by ordinary filling and rejected by the reservation pass. Skipping a reservation does not remove that type from the later weighted bag. Earlier accepted reservations also reduce the balance for later ones.

For an ordered unseen pair costing 200 and 400 with 600 points left, the first insertion leaves an exact match for the second, which the reservation skips. Reversing the order changes which type receives the reservation. The filler can still draw an affordable skipped type afterward.

Reservation pass: cost < points left

  1. Conehead Mummy200 < 600reserved→ 400
  2. Buckethead Mummy400 < 400skipped

Weighted filling: cost ≤ points left, seed 3

  1. Buckethead Mummy400 ≤ 400drawn→ 0

The budget, spent in insertion order

Instructions:Conehead Mummy · Buckethead Mummy

Plate 2.2A final wave with 600 points, Conehead Mummy and then Buckethead Mummy still unseen. The reservation admits a type only while its cost is strictly below the points left, so it skips 1 of them. The filler then admits cost ≤ points left, and here draws the skipped type after all; example seed 3, 0 points left.

04 / THE RESULT

The roster is still a starting point

The ordering of a weighted bag affects its draw-to-type mapping. The native set is ordered by type pointers; equal costs and weights therefore do not make an arbitrary replacement order reproduce the same seeded sequence.55Ordering and the component exampleThe native ordered-set comparator compares type-pointer values. The website uses selected display order and reconstructed integer draws. The isolated filler demonstrates budget spending; the construction and music views generate preceding waves, final reservation, per-instruction levels, and the level-wide leader attempt.0x100c03c8c

From level 4 onward, generation makes an extra wealth-entry attempt and an extra leader-entry attempt for the level, then assigns a successful entry to a chosen wave. This is not a fresh 0.4 leader roll on every wave. The baseline leader probability is 0.4; its type is selected by weight from types whose cost is strictly greater than 100.

The baseline wealth probability is zero, but its chance draw is still consumed. If both features are enabled and succeed, another draw suppresses one. A surviving extra entry is appended after ordinary filling without deducting its cost from the ordinary budget. World processing can then replace it, including clearing a removed leader’s marker when Jam constructs its replacement.66Extra leader entriesThe materializer attempts extra entries from displayed level 4 onward. The shared baseline declares LeaderProbability = 0.4 and LeaderMinWaveCost = 100. Leader eligibility uses a strict cost-greater-than test, followed by weighted selection. Successful entries are appended outside the ordinary filler budget. Wealth probability is zero in this baseline, but its chance draw is still consumed.0x101ce8a540x101ab6840

Together with the wave plan, these rules explain how a point allowance becomes an ordered list of ordinary spawn instructions. Placement, strength, and timing operate on that result later.

05 / RANDOM STATE

Why one seed is not the whole level

The bag equations use the inspected integer stream: MT-style state, a 31-bit result, then modulo reduction for bounded draws. A zero seed becomes 4357. Different parts of generation own different stream states:77Separate random-state consumersFresh DangerRoom initialization constructs designer state, materializes waves, runs world postprocessing, installs runtime actions and loot tags, then reseeds the WaveManager. Jam uses the global RNG; Modern queue shuffling calls imported C++ machinery. The website uses reconstructed integer draws with explicit input seeds and independent scenario state.0x101d476240x101c79bec0x101ce66dc0x100121044

DecisionRandom state used
Wave description and initial pool choicesDescription-builder RNG
Materializing ordinary wave instructionsMaterializer RNG
Runtime wave actions and row samplingWaveManager RNG supplied to the action
Jam, Dinosaur, and general-loot drawsGlobal RNG
Modern family/row selectionSupplied designer RNG
Modern endpoint interpolationGlobal RNG
Portal queue shuffleImported C++ RNG machinery

GetSeed(1) reads time(NULL), but the timestamp alone does not specify every stream’s state or earlier consumption. Rejected duplicate choices, zero-probability attempts, and computed values that are later discarded can still advance a stream. The component controls expose their own input seeds so the individual rules remain reproducible.

Notes

The evidence behind each claim: the code path, and the native addresses where it was traced.

  1. 1

    Pool selection by index

    The builder adds the stage basic type, then chooses ZombieTypeCount entries from the configured pool. Each selected vector entry is removed before the next bounded draw. The baseline count is 4. Weight is not read by this selection pass.

    0x101ab6840
  2. 2

    The high-cost replacement

    Above BigZombieSureExistLevel, baseline 50, the helper checks for a selected type whose WavePointCost is at least 1500. If absent, it draws from qualifying remaining pool entries and replaces the last pool selection. The predicate concerns cost, not a particular runtime zombie class.

    0x101ab6d78
  3. 3

    The weighted integer bag

    The ordinary filler drops candidates whose WavePointCost exceeds the remaining budget, draws through the integer weighted bag, appends the chosen type, and subtracts its cost. FirstWave and the separate Cost property are not inputs to these helpers. Bounded integer draws use modulo reduction; bag shares describe interval lengths, not a claim of perfectly uniform RNG residues.

    0x101ce7f080x100366650
  4. 4

    Strict final-wave reservation

    Before normal final-wave filling, the materializer visits selected types not yet seen. A type is appended only when its cost is strictly less than the current remaining budget. The budget is reduced after each insertion, so ordering and earlier insertions affect later eligibility.

    0x101ce8598
  5. 5

    Ordering and the component example

    The native ordered-set comparator compares type-pointer values. The website uses selected display order and reconstructed integer draws. The isolated filler demonstrates budget spending; the construction and music views generate preceding waves, final reservation, per-instruction levels, and the level-wide leader attempt.

    0x100c03c8c
  6. 6

    Extra leader entries

    The materializer attempts extra entries from displayed level 4 onward. The shared baseline declares LeaderProbability = 0.4 and LeaderMinWaveCost = 100. Leader eligibility uses a strict cost-greater-than test, followed by weighted selection. Successful entries are appended outside the ordinary filler budget. Wealth probability is zero in this baseline, but its chance draw is still consumed.

    0x101ce8a540x101ab6840
  7. 7

    Separate random-state consumers

    Fresh DangerRoom initialization constructs designer state, materializes waves, runs world postprocessing, installs runtime actions and loot tags, then reseeds the WaveManager. Jam uses the global RNG; Modern queue shuffling calls imported C++ machinery. The website uses reconstructed integer draws with explicit input seeds and independent scenario state.

    0x101d476240x101c79bec0x101ce66dc0x100121044