A companion app that mostly automates the game 'Iron Nest' for you.
Go to file
Dominik Roth 186e2c4d6d Add scout flight planning: click-to-place rectangle, new dropdown category
A ScoutFlight anchors to the center of whatever large grid square the
cursor is in, with its bearing read off where in that square the
cursor actually sits, decoupling a clean anchor point from fine
direction control. The plotted rectangle extends 0.92km back and
13.04km forward along that bearing, 1.21km to each side
(solver.scout_flight_corners), previewed live while placing (see
GridCanvas.start_scout_flight_placement) and drawn as a filled
rectangle once committed.

New 'Scout Flights' header dropdown lists them with replot/hide/remove
per entry, plus a header button to plan a new one. Wired into
Board.clear() and save/load (SAVE_FORMAT_VERSION bumped to 3, old
saves load fine via the new key's default).
2026-08-08 23:32:54 +02:00
src/fenigma Add scout flight planning: click-to-place rectangle, new dropdown category 2026-08-08 23:32:54 +02:00
.gitignore Initial commit: IRON NEST Assist 2026-08-08 20:01:50 +02:00
icon_alt.png Rewrite README short, rename project to FeNigma, add icon/showcase 2026-08-08 20:15:14 +02:00
icon.png Rewrite README short, rename project to FeNigma, add icon/showcase 2026-08-08 20:15:14 +02:00
install.sh Add install.sh, run.sh uses the venv when present 2026-08-08 20:18:15 +02:00
README.md README: larger icon 2026-08-08 20:22:28 +02:00
requirements.txt Sweep em-dashes out of code, docstrings, and requirements.txt 2026-08-08 20:27:53 +02:00
run.sh Rename package/app to FeNigma consistently 2026-08-08 20:20:43 +02:00
showcase.png Rewrite README short, rename project to FeNigma, add icon/showcase 2026-08-08 20:15:14 +02:00


FeNigma

Fe (iron) + enigma, we solve the geometric puzzles.

A companion app that mostly automates IRON NEST: Heavy Turret Simulator for you. Screenshot the game's typewriter orders and it solves the geo puzzle and the trajectory math, handing you ready-to-fire commands: elevation, azimuth, number of powder charges. Screenshot the field log and it picks up kills and newly-spotted units automatically. You can also plan strikes of your own, picking a shell for the blast radius you need. Pure screen-reading, no game files touched, no input injected.

Showcase

What it does

  • Reads orders, solves the geometry. Paste/screenshot the in-game typewriter text and it parses absolute grid refs and relative bearing/distance descriptions, then resolves everything into map coordinates, chained clues ("Bearing 293 from Alpha") included. The map shows its work: the actual bearing lines/circles behind each resolved position. When a description is genuinely ambiguous (two intersections), both candidates are shown instead of guessing.
  • Calculates the shot. Every resolved target gets a live firing card: elevation, azimuth, and minimum powder charge, computed from the Nest.
  • Tracks the battle. A second screenshot of the field log marks units destroyed and folds in newly-spotted contacts, merging with what's already known instead of duplicating it.
  • Plans strikes. Drop a strike anywhere on the map and pick a shell to preview its blast radius before committing.

Install

./install.sh

Sets up a venv for the Python deps (Pillow, numpy, pytesseract) and checks for the system packages that pip can't install: GTK4/libadwaita bindings and tesseract. If either is missing it prints the package names for your distro and stops, install those and re-run.

Run

./run.sh

Uses the venv from install.sh if one exists, otherwise falls back to system python3. GTK apps with this app ID are single-instance, if a run gets killed uncleanly it can leave a zombie registered on D-Bus and silently no-op the next launch. If ./run.sh seems to do nothing, pgrep -af fenigma and kill any stragglers first.

Stack

GTK4 + libadwaita (PyGObject) for the UI, Tesseract (via pytesseract) for OCR, Pillow/numpy for preprocessing. Details on the coordinate system, OCR formats, and solver internals live in code comments (solver.py, ocr.py, models.py) rather than here.