Replay video generator for sliding puzzles
Project description
SlidyReplay
Generates MP4 videos of sliding puzzle replays from slidysim replay URLs, input files, or manual solution strings.
Installation
pip install slidyreplay
pip install torch --index-url https://download.pytorch.org/whl/cu124 # optional GPU
Quick Start
GUI
slidyreplay
Launches a fully functional GUI with nearly all custom options, backed by the same CLI interface.
CLI
slidyreplay --solution R2D2L2U2 --size 3x3 --tps 10 # auto-named in replays/
slidyreplay -u "https://slidysim.github.io/?replay=..." # auto-named in replays/
slidyreplay -f input.txt # auto-named in replays/
slidyreplay -b solutions.txt -q 2160 # batch, auto-named in replays/
slidyreplay --solution R2D2L2U2 --time 30 -c 28 --slow-render -o small.mp4
slidyreplay --solution R2D2L2U2 --no-layout --no-numbers -o clean.mp4
slidyreplay --solution R2D2L2U2 --upscale --encoder libx265 -o high_quality.mp4
slidyreplay --solution R2D2L2U2 -q 720 -s 2.0 -o fast.mp4
slidyreplay --solution R2D2L2U2 --no-header # hide timer bar, keep stats panel
slidyreplay --solution R2D2L2U2 --no-details # hide stats panel, keep timer
slidyreplay --solution R2D2L2U2 --dynamic-md # show right-side MD timer
slidyreplay --solution R2D2L2U2 --no-header --no-details # puzzle grid only (= --no-layout)
slidyreplay --solution R2D2L2U2 --saturation 0.5 # set both min/max saturation to 0.5
slidyreplay --solution R2D2L2U2 --saturation-min 0.3 --saturation-max 0.9 # gradient across tiles
slidyreplay --solution R2D2L2U2 --brightness-min 0.2 --brightness-max 0.8 # brightness gradient
slidyreplay --settings my_settings.json --solution R2D2L2U2 # load settings from JSON
slidyreplay --solution R2D2L2U2 --font-family Arial --font-bold --font-size 36 # custom tile font
slidyreplay --image --size 4x4 # solved puzzle image
slidyreplay --image --size 4x4 --scramble "4 1 2/7 8 3/6 5 0" # custom scramble image
slidyreplay --image --solution R2D2L2U2 --size 3x3 # scrambled + solved images
slidyreplay --image --size 5x5 --no-numbers --main-scheme rows
slidyreplay --image -f replay.txt --size 4x4 -o output.png # explicit output path
CLI Reference
| Category | Flag | Short | Description |
|---|---|---|---|
| Input | --solution |
Solution string | |
--url |
-u |
Replay URL | |
--file |
-f |
File containing a replay URL or solution string | |
--batch |
-b |
File with solutions/URLs (one per line) | |
--image |
Render PNG image(s) instead of video. Requires --size. See Image Mode below |
||
| Puzzle | --size |
Puzzle size (e.g. 3x3, 10x10) |
|
--scramble |
Scramble string | ||
| Timing | --tps |
Tiles per second (omit if using --time) |
|
--time |
Total time in seconds (omit if using --tps) |
||
--movetimes |
File with move timings in ms, one per line or comma-separated (overrides --tps/--time) |
||
--speedup |
-s |
Speed multiplier (e.g. 2.0 = 2× faster, 0.5 = half speed) (default: 1.0) |
|
| Output | --output |
-o |
Output file path (default: auto-generated name in replays/ folder) |
--quality |
-q |
Render quality — canvas height (720, 1080, 1440, 2160) | |
--fps |
Output framerate (default: 60) | ||
| Encoder | --compression |
-c |
Video encoder quality 10–40, lower = fewer artifacts but larger file (default: 18) |
--slow-render |
Slower encode, ~33% smaller file (p7 for NVENC, slow for libx264). Auto-enabled on CPU. | ||
--encoder |
Force video encoder (choices below). Auto-detected if not set. | ||
--upscale |
Re-encode to 2K (2560×1440). Only applies when quality < 1440p. Keeps original too. | ||
| Render | --no-layout |
Shortcut for --no-header --no-details (puzzle grid only) |
|
--no-header |
Hide the timer header bar (time/moves/tps and MD display) | ||
--no-details |
Hide the stats panel on the right side of the puzzle | ||
--dynamic-md |
Show MD/predicted/MMD timer on the right of the header (off by default — timer centered instead) | ||
--adjust-height |
Crop canvas height to puzzle content instead of fixed quality preset. Useful when big puzzle doesn't fill the frame due to small tile size | ||
--no-border |
Suppress tile border outlines | ||
--no-secondary-border |
Suppress secondary color bar borders | ||
--no-grid-bars |
Suppress secondary grid bar indicators inside tiles | ||
--no-numbers |
Suppress tile number text (improves compression) | ||
--main-scheme |
Color scheme: fringe, rows, or columns (default: fringe) |
||
--force-main |
Force main scheme everywhere (disable grids detection) | ||
--animate-moves |
Animate tile sliding between moves (smooth transitions) | ||
--cursor-dance |
Path to cursor image (PNG recommended) that dances along tile moves. Cursor traces the blank's path via Bézier arcs, timed by movetimes. Transparency is preserved. | ||
--cycles-detection |
EXPERIMENTAL: detect and display cycling tiles in grid stats (may increase analysis time) | ||
| Font | --font-family |
Tile number font family (system font name, e.g. Arial). Default: Roboto |
|
--font-bold |
Use bold variant of the tile number font | ||
--font-size |
Override font size in px (auto-computed by default). ⚠ Numbers may overflow tiles | ||
| Colors | --grid1-color |
Grid 1 (red sections) color as hex, e.g. FF0000 |
|
--grid2-color |
Grid 2 (blue sections) color as hex, e.g. 0000FF |
||
--tile-bg-color |
Tile background color as hex, e.g. 969696 |
||
--hue-start |
Hue range start (0–330, default: 0) | ||
--hue-end |
Hue range end (0–330, default: 330) | ||
--saturation |
Saturation, sets both min and max (0–1). Overrides --saturation-{min,max} |
||
--saturation-min |
Saturation minimum for tile gradient (0–1, default: 0.78) | ||
--saturation-max |
Saturation maximum for tile gradient (0–1, default: 0.78) | ||
--brightness |
Brightness, sets both min and max (0–1). Overrides --brightness-{min,max} |
||
--brightness-min |
Brightness minimum for tile gradient (0–1, default: 0.6) | ||
--brightness-max |
Brightness maximum for tile gradient (0–1, default: 0.6) | ||
| Hardware | --no-gpu |
-g |
Disable GPU acceleration (GPU is auto-detected by default) |
| Settings | --settings |
Load settings from a JSON file saved from the GUI. Explicit CLI flags override file values | |
| Debug | --log |
-l |
Enable debug logging to logs/debug_\<timestamp\>.log |
Cursor Dance
The --cursor-dance <path> option places a cursor image over the puzzle that moves
from tile to tile along the blank's path. The cursor follows a smooth Bézier arc,
arriving at each tile at the exact moment that tile moves (or starts animating if
--animate-moves is set). The cursor always moves in time with the move timings
(movetimes speed).
- The image is converted to RGBA — transparency is preserved.
- If no cursor file is provided, no cursor is rendered.
- The cursor scales proportionally to tile size (min 24px).
- In the GUI, use the CURSOR section to Browse... or Clear the cursor image.
Example
slidyreplay --solution R2D2L2U2 --size 3x3 --tps 10 --cursor-dance my_cursor.png -o replay.mp4
Settings Management
The GUI includes three settings controls at the bottom of the Settings panel:
- Reset to Defaults — resets all controls to their default values (render options, colors, sliders, etc.)
- Save Settings... — exports all current settings to a JSON file. Output folder is excluded.
- Load Settings... — imports settings from a previously saved JSON file and applies them to the GUI.
CLI --settings
Use a settings file saved from the GUI directly on the command line:
slidyreplay --settings my_settings.json --solution R2D2L2U2 --size 4x4
Explicit CLI flags override values from the settings file, so you can use a base config and tweak individual parameters:
slidyreplay --settings base.json --solution R2D2L2U2 --fps 120 --hue-start 180
JSON format
Settings files use a simple flat JSON structure. Example:
{
"quality": "1080p",
"fps": 60,
"compression": 18,
"speed_factor": "1",
"use_gpu": true,
"slow_render": false,
"upscale": false,
"encoder": "Auto",
"main_scheme": "fringe",
"force_main": false,
"no_layout": false,
"no_border": false,
"no_secondary_border": false,
"no_grid_bars": false,
"no_numbers": false,
"no_header": false,
"no_details": false,
"dynamic_md": false,
"cycles_detection": false,
"adjust_height": false,
"animate_moves": false,
"hue_start": 0.0,
"hue_end": 330.0,
"saturation_min": 78,
"saturation_max": 78,
"brightness_min": 60,
"brightness_max": 60,
"grid1_color": "C86767",
"grid2_color": "8DB3FF",
"tile_bg_color": "454545",
"font_family": "",
"font_bold": false,
"font_size_override": 0
}
Saturation and brightness values are stored at GUI scale (0–100), they are automatically converted to the 0–1 range when used via --settings.
Encoder Options
Available encoders are auto-detected in priority order — the first supported encoder is used:
| Priority | Encoder | GPU Required | Quality Flag |
|---|---|---|---|
| 1 | hevc_nvenc |
NVIDIA | -cq (CRF-like, 21–51) |
| 2 | hevc_amf |
AMD | -qp_p (CQP, 18–48) |
| 3 | hevc_qsv |
Intel | -global_quality (CQP, 18–48) |
| 4 | libx265 |
— | -crf (0–51) |
| 5 | h264_nvenc |
NVIDIA | -cq (CRF-like, 22–52) |
| 6 | h264_amf |
AMD | -qp_p (CQP, 18–48) |
| 7 | h264_qsv |
Intel | -global_quality (CQP, 18–48) |
| 8 | libx264 |
— | -crf (0–51, default fallback) |
--compression(-c) maps to the encoder's quality flag with an offset to normalize across encoders (the value 10–40 is translated per-encoder).--slow-renderswitches to a slower preset:p7for NVENC,qualityfor AMF,veryslowfor QSV,slowfor libx264/libx265. This typically reduces file size by ~33% at the cost of ~33% longer encode time.--encoderoverrides auto-detection to force a specific encoder. Useful when multiple GPUs are present or you want software encoding on a GPU-capable system.
Debug logging is disabled by default. Pass --log (-l) to enable:
slidyreplay -l # GUI with logging
slidyreplay --solution R2D2L2U2 -l # CLI with logging
Logs are written to logs/debug_YYYYMMDD_HHMMSS.log.
Image Mode
The --image flag renders single-frame PNG images rather than videos. Images always render the puzzle grid only.
Behavior by input
| Input | Output |
|---|---|
--size 4x4 only |
One image: solved puzzle → 4x4_puzzle.png |
--size 4x4 --scramble "..." |
One image: that custom scramble → 4x4_scramble.png |
--size 3x3 --solution R2D2L2U2 |
Two images: 3x3_scrambled.png (first state) + 3x3_solved.png (solved with analysis colors) |
--url / --file + --size |
Two images, same as solution. Replay URL is parsed for the solution |
GUI "Render Image" button
Located in the Override section of the GUI (next to the Scramble and Movetimes fields). Behavior:
- With a queue item selected: generates two images (scrambled + solved with analysis) using current color/display settings, saved to the output folder and listed in the Generated Replays panel
- No queue item selected: generates a single image from the override fields — custom scramble if entered, otherwise a solved puzzle of the given size
Output Format
By default, files are saved to the replays/ folder with auto-generated names following the pattern: <size>_<total_time>_<moves>_<tps>_movetimes.mp4
Example: 8x8_23.564_707_30.003_movetimes_5.mp4
Use -o <path> to save to a custom location with a specific filename.
GPU Acceleration
The GUI shows the GPU name when available, or "Not available — install CUDA" when PyTorch/CUDA is missing. GPU is enabled by default when available and falls back to CPU automatically.
Benchmarks (NVIDIA GeForce GTX 1660 SUPER)
Settings: quality=720, 60 FPS.
| Puzzle | Moves | Unique | GPU Layout | GPU No Layout | CPU Layout | CPU No Layout |
|---|---|---|---|---|---|---|
| 4×4 | 26 | 25 | 0.9s | 0.7s | 0.8s | 0.7s |
| 5×5 | 98 | 95 | 1.1s | 0.9s | 1.2s | 0.9s |
| 6×6 | 213 | 208 | 1.5s | 1.2s | 1.7s | 1.4s |
| 7×7 | 425 | 401 | 2.2s | 1.7s | 2.9s | 2.2s |
| 8×8 | 707 | 652 | 3.0s | 2.3s | 4.5s | 3.1s |
| 9×9 | 1251 | 1079 | 4.8s | 3.3s | 7.6s | 4.7s |
| 10×10 | 1569 | 1362 | 6.9s | 4.5s | 9.7s | 6.1s |
| 12×12 | 2883 | 2470 | 11.2s | 8.1s | 16.5s | 10.7s |
| 16×16 | 7132 | 5692 | 20.7s | 18.8s | 39.4s | 23.6s |
| 20×20 | 14203 | 11177 | 43.6s | 32.3s | 78.0s | 43.0s |
Run your own benchmarks with python benchmark.py.
"Unique" = number of distinct puzzle states rendered (video may duplicate frames via frame mapping).
Installing GPU support
-
Check your NVIDIA driver supports CUDA 12.x:
nvidia-smiLook for "CUDA Version" in the output (top-right).
-
Install PyTorch with CUDA:
pip install torch --index-url https://download.pytorch.org/whl/cu124 -
Verify:
python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))"
Benchmark script
python benchmark.py # full benchmark run
python benchmark.py --gpu-only # GPU only (both layout and no-layout)
python benchmark.py --cpu-only # CPU only
python benchmark.py --layout # layout only (both GPU and CPU)
python benchmark.py --no-layout # no-layout only
python benchmark.py --quality-test # test 10×10 at all quality presets
All outputs saved to logs/<timestamp>/ folder.
Build (Windows)
Builds a standalone dist\slidyreplay.exe (CPU-only):
build_no_gpu.bat
Requires ffmpeg\ffmpeg.exe.
For GPU acceleration, use the repository directly (python main.py) instead of the standalone build.
Dependencies
- Python 3.9+
ttkbootstrap,Pillow,tabulate,numpy,psutil(optional — for RAM logging with--log)torch(optional — for GPU acceleration)ffmpeg— must be installed and available in your PATH (or same folder as the script)
Tested on Windows 11 with Python 3.13.5.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file slidyreplay-8.0.8.tar.gz.
File metadata
- Download URL: slidyreplay-8.0.8.tar.gz
- Upload date:
- Size: 551.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac3981151d3e35f6b4ff3ee8704f99ceacde582a2ad62542a92ebf9bb03f1503
|
|
| MD5 |
3df71f514962869f465a7d7b22ca6577
|
|
| BLAKE2b-256 |
796e021702d64350b893425d3d85fe6865fcb2421b2588344d22d28b3fbc3b5a
|
Provenance
The following attestation bundles were made for slidyreplay-8.0.8.tar.gz:
Publisher:
publish.yml on dphdmn/slidyreplay
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slidyreplay-8.0.8.tar.gz -
Subject digest:
ac3981151d3e35f6b4ff3ee8704f99ceacde582a2ad62542a92ebf9bb03f1503 - Sigstore transparency entry: 1703968312
- Sigstore integration time:
-
Permalink:
dphdmn/slidyreplay@e056c25622709f95d5999eee9417521bd252fcc9 -
Branch / Tag:
refs/tags/pypi-v8.0.8 - Owner: https://github.com/dphdmn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e056c25622709f95d5999eee9417521bd252fcc9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file slidyreplay-8.0.8-py3-none-any.whl.
File metadata
- Download URL: slidyreplay-8.0.8-py3-none-any.whl
- Upload date:
- Size: 557.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e5d87c72127f170dc3bd8431c3d1f7ea7b9c13fb0e1244f475f452f191a5786
|
|
| MD5 |
6eccc29670dbcc07d6cedba97dd579ad
|
|
| BLAKE2b-256 |
ff6672260b39b4a01a8ce63c11be96b50f447bcd456e80001b14546c80b1a256
|
Provenance
The following attestation bundles were made for slidyreplay-8.0.8-py3-none-any.whl:
Publisher:
publish.yml on dphdmn/slidyreplay
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slidyreplay-8.0.8-py3-none-any.whl -
Subject digest:
9e5d87c72127f170dc3bd8431c3d1f7ea7b9c13fb0e1244f475f452f191a5786 - Sigstore transparency entry: 1703968352
- Sigstore integration time:
-
Permalink:
dphdmn/slidyreplay@e056c25622709f95d5999eee9417521bd252fcc9 -
Branch / Tag:
refs/tags/pypi-v8.0.8 - Owner: https://github.com/dphdmn
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e056c25622709f95d5999eee9417521bd252fcc9 -
Trigger Event:
push
-
Statement type: