7.8 KiB
Spacetris — Challenge Mode (Asteroids) Implementation Spec for VS Code AI Agent
Goal: Implement/extend CHALLENGE gameplay in Spacetris (not a separate mode), based on 100 levels with asteroid prefilled blocks that must be destroyed to advance.
1) High-level Requirements
Modes
- Existing mode remains ENDLESS.
- Add/extend CHALLENGE mode with 100 levels.
Core Challenge Loop
- Each level starts with prefilled obstacle blocks called Asteroids.
- Level N starts with N asteroids (placed increasingly higher as level increases).
- Player advances to the next level when ALL asteroids are destroyed.
- Gravity (and optionally lock pressure) increases per level.
Asteroid concept
Asteroids are special blocks placed into the grid at level start:
- They are not player-controlled pieces.
- They have types and hit points (how many times they must be cleared via line clears).
2) Asteroid Types & Rules
Define asteroid types and their behavior:
A) Normal Asteroid
hitsRemaining = 1- Removed when its row is cleared once.
- Never moves (no gravity).
B) Armored Asteroid
hitsRemaining = 2- On first line clear that includes it: decrement hits and change to cracked visual state.
- On second clear: removed.
- Never moves (no gravity).
C) Falling Asteroid
hitsRemaining = 2- On first clear: decrement hits, then becomes gravity-enabled (drops until resting).
- On second clear: removed.
D) Core Asteroid (late levels)
hitsRemaining = 3- On each clear: decrement hits and change visual state.
- After first hit (or after any hit — choose consistent rule) it becomes gravity-enabled.
- On final clear: removed (optionally trigger bigger VFX).
Important: These are all within the same CHALLENGE mode.
3) Level Progression Rules (100 Levels)
Asteroid Count
asteroidsToPlace = level(Level 1 -> 1 asteroid, Level 2 -> 2 asteroids, …)- Recommendation for implementation safety:
- If
levelbecomes too large to place comfortably, still placelevelbut distribute across more rows and allow overlaps only if empty. - If needed, implement a soft cap for placement attempts (avoid infinite loops). If cannot place all, place as many as possible and log/telemetry.
- If
Placement Height / Region
- Early levels: place in bottom 2–4 rows.
- Mid levels: bottom 6–10 rows.
- Late levels: up to ~half board height.
- Use a function to define a
minRow..maxRowregion based onlevel.
Example guidance:
maxRow = boardHeight - 1minRow = boardHeight - 1 - clamp(2 + level/3, 2, boardHeight/2)
Type Distribution by Level (suggested)
- Levels 1–9: Normal only
- Levels 10–19: add Armored (small %)
- Levels 20–59: add Falling (increasing %)
- Levels 60–100: add Core (increasing %)
4) Difficulty Scaling
Gravity Speed Scaling
Implement per-level gravity scale:
gravity = baseGravity * (1.0f + level * 0.02f)(tune)- Or use a curve/table.
Optional additional scaling:
- Reduced lock delay slightly at higher levels
- Slightly faster DAS/ARR (if implemented)
5) Win/Lose Conditions
Level Completion
- Level completes when:
asteroidsRemaining == 0 - Then:
- Clear board (or keep board — choose one consistent behavior; recommended: clear board for clean progression).
- Show short transition (optional).
- Load next level, until level 100.
- After level 100 completion: show completion screen + stats.
Game Over
- Standard Tetris game over: stack reaches spawn/top (existing behavior).
6) Rendering / UI Requirements
Visual Differentiation
Asteroids must be visually distinct from normal tetromino blocks.
Provide visual states:
- Normal: rock texture
- Armored: plated / darker
- Cracked: visible cracks
- Falling: glow rim / hazard stripes
- Core: pulsing inner core
Minimum UI additions (Challenge):
- Display
LEVEL: X/100 - Display
ASTEROIDS REMAINING: N(or an icon counter)
7) Data Structures (C++ Guidance)
Cell Representation
Each grid cell must store:
- Whether occupied
- If occupied: is it part of normal tetromino or an asteroid
- If asteroid: type + hitsRemaining + gravityEnabled + visualState
Suggested enums:
enum class CellKind { Empty, Tetromino, Asteroid };
enum class AsteroidType { Normal, Armored, Falling, Core };
struct AsteroidCell {
AsteroidType type;
uint8_t hitsRemaining;
bool gravityEnabled;
uint8_t visualState; // optional (e.g. 0..n)
};
struct Cell {
CellKind kind;
// For Tetromino: color/type id
// For Asteroid: AsteroidCell data
};
8) Line Clear Processing Rules (Important)
When a line is cleared:
-
Detect full rows (existing).
-
For each cleared row:
-
For each cell:
-
If
kind == Asteroid:-
hitsRemaining-- -
If
hitsRemaining == 0: remove (cell becomes Empty) -
Else:
-
Update its visual state (cracked/damaged)
-
If asteroid type is Falling/Core and rule says it becomes gravity-enabled on first hit:
gravityEnabled = true
-
-
-
-
-
After clearing rows and collapsing the grid:
-
Apply asteroid gravity step:
- For all gravity-enabled asteroid cells: let them fall until resting.
- Ensure stable iteration (bottom-up scan).
-
-
Recount asteroids remaining; if 0 -> level complete.
Note: Decide whether gravity-enabled asteroids fall immediately after the first hit (recommended) and whether they fall as individual cells (recommended) or as clusters (optional later).
9) Asteroid Gravity Algorithm (Simple + Stable)
Implement a pass:
-
Iterate from bottom-2 to top (bottom-up).
-
If cell is gravity-enabled asteroid and below is empty:
- Move down by one
-
Repeat passes until no movement OR do a while-loop per cell to drop fully.
Be careful to avoid skipping cells when moving:
- Use bottom-up iteration and drop-to-bottom logic.
10) Level Generation (Deterministic Option)
To make challenge reproducible:
- Use a seed:
seed = baseSeed + level - Place asteroids with RNG based on level seed.
Placement constraints:
-
Avoid placing asteroids in the spawn zone/top rows.
-
Avoid creating impossible scenarios too early:
- For early levels, ensure at least one vertical shaft exists.
11) Tasks Checklist for AI Agent
A) Add Challenge Level System
- Add
currentLevel (1..100)andmode == CHALLENGE. - Add
StartChallengeLevel(level)function. - Reset/prepare board state for each level (recommended: clear board).
B) Asteroid Placement
-
Implement
PlaceAsteroids(level):- Determine region of rows
- Choose type distribution
- Place
levelasteroid cells into empty spots
C) Line Clear Hook
-
Modify existing line clear code:
- Apply asteroid hit logic
- Update visuals
- Enable gravity where required
D) Gravity-enabled Asteroids
- Implement
ApplyAsteroidGravity()after line clears and board collapse.
E) Level Completion
- Track
asteroidsRemaining. - When 0: trigger level transition and
StartChallengeLevel(level+1).
F) UI
- Add level & asteroids remaining display.
12) Acceptance Criteria
-
Level 1 spawns exactly 1 asteroid.
-
Level N spawns N asteroids.
-
Destroying asteroids requires:
- Normal: 1 clear
- Armored: 2 clears
- Falling: 2 clears + becomes gravity-enabled after first hit
- Core: 3 clears (+ gravity-enabled rule)
-
Player advances only when all asteroids are destroyed.
-
Gravity increases by level and is clearly noticeable by mid-levels.
-
No infinite loops in placement or gravity.
-
Challenge works end-to-end through level 100.
13) Notes / Tuning Hooks
Expose tuning constants:
baseGravitygravityPerLevelminAsteroidRow(level)typeDistribution(level)weightscoreGravityOnHitrule