Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Prism Stack

A desktop falling-block marathon written in Rust, with an indigo interface, bright beveled blocks, an outlined ghost, animated clears, original sound cues, and saved personal records.

Run

Install a Rust toolchain with Cargo and provide a working desktop display. Linux builds use native X11/OpenGL and ALSA libraries.

From this directory:

cargo run --locked --release

For a reproducible piece sequence and isolated preferences:

cargo run --locked --release -- --seed 424242 --data-dir artifacts/manual-profile

Build once with cargo build --locked --release -j 4, then launch target/release/prism-stack. The font is embedded, so the executable can run from a different working directory. --help prints launch options without opening a window. Random play is the default; seeded sequences are reproducible with the retained Cargo.lock.

Controls

Input Action
Left / Right Move; hold for automatic repeat
Down Soft drop
Up or X Rotate clockwise
Z Rotate counterclockwise
Space Hard drop and lock
C or either Shift Hold
Esc or P Pause / resume; return from settings
R Restart from pause or game over
M Toggle sound
F11 Toggle fullscreen
Up / Down, Enter Select and activate menu actions
Mouse Hover and click menu buttons

Horizontal repeat begins after 150 ms and repeats every four simulation ticks, approximately 33 ms. The last pressed horizontal direction wins when both are held. Releasing it returns control to the other held direction. Rotation, hold, and hard drop respond to press edges.

Losing window focus pauses an active game. Returning focus leaves it paused until you resume. Held movement must be released before it acts again.

Marathon rules

  • The board has 10 columns and 20 visible rows, plus four hidden spawn rows. Logical X increases rightward and Y increases downward. Visible rows are 0..19; hidden rows are -4..-1.
  • All seven tetrominoes use SRS orientations and wall kicks, with the separate I kick table and stationary O geometry. Pieces spawn with their template origin at (3, -1).
  • Each shuffled seven-piece bag contains I, O, T, S, Z, J, and L once. Five upcoming pieces are visible. Preview and hold use the same sequence.
  • Hold is available once per active piece. Retrieved pieces return to their spawn position and orientation.
  • The ghost shows the greatest legal downward displacement. Hard drop locks there immediately and awards two points per traversed row.
  • Simulation runs at 120 Hz. Gravity is max(0.05, 0.8^(level - 1)) seconds per row. Soft drop accelerates to at least 30 rows per second and awards one point per player-accelerated row.
  • A grounded piece locks after 500 ms. Successful grounded moves or rotations can reset the timer up to 15 times. Failed actions do not reset it. Becoming airborne suspends grounded timing without restoring the reset allowance.
  • Completed rows remain visible for a 150 ms clear phase, then compact simultaneously. Gameplay inputs during that phase do not manipulate the successor.
  • Level starts at 1 and increases every ten cleared lines. A clear is scored at the level before it advances progression.
  • A colliding spawn ends the run. A newly locked piece also ends it if all its surviving cells remain above the visible board after any clear and compaction. Partial hidden occupancy alone does not end play; a completely cleared piece has no surviving cells to lock out.

These are this clone's documented marathon rules.

Scoring

Base clear points are multiplied by the current level:

Clear Base points
Single / double / triple / four-line clear 100 / 300 / 500 / 800
Full T-spin with 0 / 1 / 2 / 3 lines 400 / 800 / 1200 / 1600
Mini T-spin with 0 / 1 / 2 lines 100 / 200 / 400

A T-spin requires a qualifying successful rotation and at least three occupied pivot corners. Both forward corners make it full; otherwise it is mini, with the final SRS kick candidate promoting it to full. Automatic gravity preserves rotation history. Successful lateral movement and positive-distance player drops clear it. A zero-distance hard drop preserves it, and failed inputs do not replace the last successful action.

Consecutive eligible line clears—four-line clears or T-spin line clears—receive a 1.5× back-to-back multiplier after the first. Ordinary one-to-three-line clears break that chain. Locks without clears preserve the chain. Consecutive clearing locks also award 50 × combo_index × level; the first clear has index zero, and a nonclearing lock resets the combo. Drop points are separate from these multipliers.

Settings and records

Settings provides volume, mute, reduced motion, and high contrast. Reduced motion disables ambient movement and most particles. High contrast strengthens the grid, block borders, and ghost, and adds piece letters.

The interface uses a 1280 × 800 design layout with a 320 × 640 board. Resizing scales it uniformly; at 960 × 640 it uses a 960 × 600 layout with letterboxing. Smaller windows retain the complete interface through proportional scaling.

By default, preferences and records use the platform application data directory. --data-dir PATH selects another directory. The versioned settings.json contains schema_version, high_score, best_lines, and settings; settings contains master_volume, muted, reduced_motion, and high_contrast. Records update at game over. Preferences save when changed.

Missing settings use defaults. Malformed, unsupported, or unreadable settings produce a nonblocking warning and preserve the original file. Saving stays disabled for that load to avoid overwriting it. Normal saves use an exclusively created settings.json.tmp sibling followed by replacement. A write failure leaves the valid in-memory profile available.

Original short sound cues are synthesized once at startup. If the audio backend cannot initialize, the game reports the problem and continues graphical play.

Verification and graphical evidence

Run the deterministic checks from this directory:

python3 tools/check_source_layout.py
cargo fmt --all -- --check
cargo test --locked --all-targets -j 4
cargo clippy --locked --all-targets -j 4 -- -D warnings
cargo build --locked --release -j 4

The regression suite covers piece geometry and SRS kicks, collision and compaction, bags, hold, ghost and drop behavior, lock timing, scoring and spin history, top-out, input timing, screen lifecycle, persistence failures, audio synthesis, and seeded marathon invariants. tests/layout.rs directly checks that horizontal coordinates increase rightward and logical rows increase downward through the actual Macroquad camera matrix.

The successful native interface session retained its application captures under artifacts/native-final/, including active gameplay, pause, and game over. The native line-clear session retained its compacted board capture under artifacts/native-line-clear/. The interactive results, screenshot descriptions, recovery history, and qualification limits are recorded in docs/manual-test-report.md. Native input, OCR, and pixel comparisons passed; direct visual inspection of the PNGs remains unverified. Older captures under artifacts/screenshots/ are preserved as troubleshooting evidence.

Source organization

src/game/ owns deterministic rules and exposes immutable views and domain events. src/play_session.rs owns game and screen transitions. src/input.rs handles simulation input; src/native_input.rs adapts native window events. src/render/ reads game state and owns presentation only. Audio, storage, and clocks have separate boundaries. src/app.rs connects those components, and src/main.rs configures the window. Production Rust files are limited to 500 lines.

The embedded DejaVu Sans font and its license are retained in assets/fonts/DejaVuSans.ttf and assets/licenses/DejaVu-Fonts.txt. Visual geometry and sound cues are generated by the application.

About

a tetris clone in rust

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages