Basics-Only Window
The opening seconds of every non-hard level run on a restricted spawn pool. Enemies are filtered to the swarm archetype of the active enemy set — orbs for bugs-flavored sets, gunners for the city set — so the player meets only the simplest mover before any pressure variety enters. Once the window expires, the full archetype roster (chargers, mortars, snipers, shooters, fields, racers, plus elite packs) unlocks.
Window length
The window covers the first 60 seconds of every tier, defined by BASICS_ONLY_TIER_SECONDS = 60 in engine/enemies/spawner.ts. The clock is missionTimerMax - missionTimer — the elapsed time within the current level. Because missionTimer resets on every tier advance, the basics-only window re-arms at the start of each new level (1, 2, 3, 5), not just the first.
Hard-mode opt-out
Hard levels (level 4 in normal-mode runs; levels 7 and 8 in Challenge Mode) explicitly skip this window. isBasicsOnlyPhase() short-circuits to false whenever game._hardMode is set, so the full enemy pool is live from frame 1. The level is meant to read as “peak” for its entire 4-minute duration, with no on-ramp.
The hard-mode flag is set during tier advance in engine/bridge.ts based on resolveLevelKind() returning 'hard'. Run sequences live in data/level-progression.ts:
- Normal run (5 levels):
normal, normal, mini_boss, hard, boss - Challenge run (10 levels):
normal, normal, mini_boss, normal, normal, mini_boss, hard, hard, mini_boss, boss
How the filter works
pickTypeForProgress() (spawner.ts) builds the candidate pool from the active enemy set, then — if isBasicsOnlyPhase() is true and a swarm archetype is registered for the set — filters the pool to entries whose id starts with <archetype>_. The swarm-archetype mapping (SET_SWARM_ARCHETYPE in data/enemies/index.ts) pins:
bugs,bugs_mortar,bugs_shooter,bugs_charger,bugs_sniper,bugs_field,bugs_racer,bugs_mixed→orbcity→gunner
If the filter would empty the pool (defensive — shouldn’t happen with current data), the unfiltered pool is used so a spawn is always available.
Coupled effects
Two other systems honor the same window so the early-game read stays consistent:
- Elite packs are gated off. The elite-pack timer in
spawner.ts(~line 639) only runs when!isBasicsOnlyPhase(game), so no pack telegraphs land in the first 60s even if the progress gate would otherwise allow them. - Early trickle mode. The first 60s also uses a dedicated close-range trickle path (3s grace → first enemy → steady ~2/sec → full pressure at 60s), with a global spawn-rate multiplier of 7.84× during the window vs 4.9× after. The pool restriction means every one of those spawns is a basic swarmer.
Why
The 60-second window is the new player’s onboarding ramp inside every level. They face only the archetype’s “default” enemy — easy to read, easy to kill — while picking their first level-up cards and getting reoriented after a tier advance. Hard mode breaks this contract on purpose: by level 4 the run has earned the right to dump the full roster on the player from the first second.
Related
enemy-spawn-zones.md— zone-based pool overridesengine/enemies/spawner.ts—BASICS_ONLY_TIER_SECONDS,isBasicsOnlyPhase,pickTypeForProgressdata/enemies/index.ts—SET_SWARM_ARCHETYPEdata/level-progression.ts—RUN_LEVEL_SEQUENCE,CHALLENGE_LEVEL_SEQUENCE,resolveLevelKind