Momir Basic Printer (MBP) is a set of Python scripts designed to run headless on a Raspberry Pi connected to a thermal receipt printer for playing the Momir Basic MTG format.
Downloads card data from the Scryfall API, including card art which is dithered to monochrome on-device, and prints a random card within a set CMC value on demand via thermal printer. All settings are configurable via config.ini, and the software can run as a background service on any Linux-based SBC with GPIO. The complete hardware setup is designed to be compact and portable, with all components housed in a waterproof case.
- Number of Players: 2
- Starting Life Total: 24
- Game Duration: 10 minutes
- Deck Size: 60+ basic lands
Each turn players discard a basic land to activate Momir Vig's ability and get a random creature from throughout Magic's history!
| Physical Card | Printed Card |
|---|---|
![]() |
![]() |
- Raspberry Pi 3 Model B+
- Adafruit T-Cobbler Plus GPIO Breakout
- REXQualis Electronics Component Kit
- Maikrt MC206H Thermal Printer
- PAPRMA 57mm x 30mm Thermal Paper
- MakerFocus 20200330-SD8V OLED Display
- KY-040 Rotary Encoder Module
- Nilight 12V 20A SPST Rocker Toggle Switch
- SHNITPWR 60W Universal Power Supply
- LM2596 Buck Converter
- KeeYees 4 Channel IIC I2C Logic Level Converter
- Clone this repository and navigate to the project directory.
git clone https://github.com/MoritzHayden/momir-basic-printer.git
cd momir-basic-printer- Open src/config.ini in a text editor and update the configuration variables to add your specific settings (like printer connection details, GPIO pins, and other hardware settings) before proceeding.
nano src/config.ini- Make the setup script executable and run it. This will automatically install dependencies and configure the systemd background service.
chmod +x setup.sh
./setup.shTip
If you are running a minimal setup and explicitly require the service to run as root, you can bypass the safety check by running: sudo ./setup.sh --allow-root
View live logs and print statements:
sudo journalctl -u momir-basic-printer.service -fCheck the current status of the service:
sudo systemctl status momir-basic-printer.serviceRestart the service (required after making code changes):
sudo systemctl restart momir-basic-printer.serviceStop the service:
sudo systemctl stop momir-basic-printer.serviceAll configuration variables are stored in src/config.ini. Update the values in this file to match your specific hardware setup and preferences. After making changes to the configuration, restart the service for the changes to take effect.
| Section | Variable | Type | Description |
|---|---|---|---|
APP |
booting_status |
string |
Status string shown while services initialize |
APP |
ready_status |
string |
Status string shown when the appliance is idle/ready |
APP |
refreshing_status |
string |
Status string shown during initial data refresh |
APP |
fetching_status |
string |
Status string shown while selecting/fetching a card |
APP |
printing_status |
string |
Status string shown while sending output to printer |
APP |
cancelled_status |
string |
Status string shown when active work is cancelled |
APP |
error_status |
string |
Status string shown when fetch/print fails |
APP |
reset_status |
string |
Status string shown after long-press reset |
APP |
done_status |
string |
Status string shown briefly after a successful print completes |
APP |
done_status_seconds |
float |
Duration in seconds to show done_status before returning to ready state |
APP |
services_unavailable_status |
string |
Status string shown when printer/Scryfall services are unavailable |
APP |
no_cmc_status_template |
string |
Template used when no card exists for selected CMC (supports {cmc}) |
APP |
shutdown_join_timeout_seconds |
float |
Max wait time for worker thread during shutdown |
FILESYSTEM |
cards_path |
string |
Directory path where card JSON files are stored |
FILESYSTEM |
art_path |
string |
Directory path where card artwork images are stored |
FILESYSTEM |
default_card_art_path |
string |
File path to default placeholder image for cards without artwork |
FILESYSTEM |
access_rights |
octal |
File system permissions for created directories (octal notation) |
HARDWARE |
serial_port |
string |
Serial device path for the thermal printer (e.g., /dev/serial0) |
HARDWARE |
serial_baud_rate |
integer |
Baud rate for the serial printer connection (e.g., 9600 or 19200) |
HARDWARE |
printer_dtr_enabled |
boolean |
Enables GPIO-based DTR flow control; disable if the printer does not wire DTR reliably |
HARDWARE |
gpio_encoder_clk |
integer |
BCM GPIO pin for rotary encoder CLK signal (default: 13) |
HARDWARE |
gpio_encoder_dt |
integer |
BCM GPIO pin for rotary encoder DT signal (default: 6) |
HARDWARE |
gpio_encoder_sw |
integer |
BCM GPIO pin for rotary encoder push-button switch (default: 5) |
HARDWARE |
gpio_printer_dtr |
integer |
BCM GPIO pin for printer DTR hardware flow control (default: 17) |
HARDWARE |
printer_dtr_active_high |
boolean |
Whether the printer asserts DTR HIGH when its receive buffer is full |
HARDWARE |
i2c_address |
hex |
I2C hex address of the SSD1306 OLED display (default: 0x3C) |
HARDWARE |
i2c_port |
integer |
I2C bus port number (default: 1) |
HARDWARE |
oled_width |
integer |
OLED display width in pixels (default: 128) |
HARDWARE |
oled_height |
integer |
OLED display height in pixels (default: 64) |
HARDWARE |
display_font_size_cmc |
integer |
Font size for the main CMC text on OLED |
HARDWARE |
display_font_size_status |
integer |
Font size for the status text on OLED |
HARDWARE |
display_status_y_offset |
integer |
Vertical Y offset (px) for status text region |
HARDWARE |
display_status_default |
string |
Default status text shown during display initialization |
HARDWARE |
display_font_cmc_path |
string |
Font file path used for CMC text rendering |
HARDWARE |
display_font_status_path |
string |
Font file path used for status text rendering |
HARDWARE |
display_cmc_prefix |
string |
Prefix label used before current CMC value (e.g., CMC:) |
HARDWARE |
display_padding_x |
integer |
Left/right OLED padding in pixels for CMC and status text layout |
HARDWARE |
display_cmc_value_gap |
integer |
Horizontal pixel gap between the CMC prefix label and numeric CMC value |
HARDWARE |
hold_time |
float |
Seconds the encoder button must be held for a long-press action |
HARDWARE |
cmc_min |
integer |
Minimum selectable CMC value (default: 0) |
HARDWARE |
cmc_max |
integer |
Maximum selectable CMC value (default: 16) |
HARDWARE |
dtr_poll_interval |
float |
Seconds between DTR pin polls when printer buffer is full |
HARDWARE |
printer_dtr_timeout_seconds |
float |
Max time to wait on DTR before bypassing hardware flow control until restart |
LOGGING |
log_level |
string |
Logging verbosity level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
LOGGING |
log_format |
string |
Format string for log messages |
LOGGING |
log_date_format |
string |
Format string for timestamps in log messages |
PRINTER |
paper_width_mm |
integer |
Physical width of thermal paper in millimeters |
PRINTER |
paper_width_chars |
integer |
Maximum number of characters per line for text wrapping |
PRINTER |
card_art_enabled |
boolean |
Whether to print card artwork images on receipts |
PRINTER |
qr_code_enabled |
boolean |
Whether to print QR codes linking to Scryfall card details |
PRINTER |
qr_code_size |
integer |
Size of QR code in printer units (larger = bigger QR code) |
PRINTER |
dpi |
integer |
Printer resolution in dots per inch for image rendering |
PRINTER |
vendor_id |
hex |
USB vendor ID for the thermal printer device |
PRINTER |
product_id |
hex |
USB product ID for the thermal printer device |
PRINTER |
printer_profile |
string |
ESC/POS printer profile name for compatibility |
PRINTER |
printer_media_width_px |
integer |
Media width in pixels for image processing and scaling |
PRINTER |
min_title_spacing |
integer |
Minimum spaces between card name and mana cost on title line |
PRINTER |
paragraph_spacing |
string |
Escaped spacing appended after wrapped oracle text paragraphs |
PRINTER |
text_replacements_json |
json |
Character replacement map for printer-safe text normalization |
SCRYFALL |
base_url |
string |
Base URL for Scryfall API requests |
SCRYFALL |
bulk_data_endpoint |
string |
API endpoint path for bulk card data download |
SCRYFALL |
header_accept |
string |
HTTP Accept header value for API content negotiation |
SCRYFALL |
header_user_agent |
string |
HTTP User-Agent header identifying the client application |
SCRYFALL |
header_accept_encoding |
string |
HTTP Accept-Encoding header for compression support |
SCRYFALL |
request_delay_seconds |
float |
Delay between consecutive API requests to respect rate limits |
SCRYFALL |
max_retries |
integer |
Maximum number of retry attempts for failed API requests |
SCRYFALL |
art_width_px |
integer |
Target width in pixels for downloaded card artwork |
SCRYFALL |
excluded_sets |
list |
Comma-separated card sets to exclude (e.g., funny, memorabilia) |
SCRYFALL |
excluded_layouts |
list |
Comma-separated card layouts to exclude (e.g., token, emblem) |
Neither this project nor its contributors are associated with Hasbro, Wizards of the Coast, or Magic: The Gathering in any way whatsoever.
Copyright © 2026 Hayden Moritz






