-
Notifications
You must be signed in to change notification settings - Fork 0
Contributing
This is a personal learning project (it is alpha — the steady-state jump
loop is live-validated over hundreds of consecutive jumps, but docking and the
rarer recovery paths are still under live validation). Contributions are welcome
as pull requests against master. The architecture is built so that adding
behavior — new procedures, new steps — does not require modifying existing code.
The repository is a six-package workspace under projects/: ed-core (the
engine), ed-vision (the perception leaf), ed-autojump (the one shippable
tool + the editable TOML procedures), ed-explore (in-system body tour), and
ed-combat / ed-trading (Phase-1 scaffolds that register nothing yet). Each
is an editable install.
Only the jump loop in ed-autojump is validated against the live game.
ed-explore is non-functional (the body tour never completes a body), and
ed-combat / ed-trading are not implemented. Live testing is currently
blocked, so those three are frozen where they are — treat them as unfinished
scaffolding rather than as behaviour to preserve.
-
Repository root: MIT (
LICENSE). -
ed-autojumpdistribution: AGPL-3.0-or-later (projects/ed-autojump/LICENSE). It bundles the nav-compass model whose Ultralytics weights are AGPL-3.0, so the whole distribution that ships those weights carries AGPL obligations. The OpenCV fallback backend needs no weights, so that obligation does not attach if you do not ship the bundled model.
Code touching the shippable ed-autojump distribution falls under AGPL; the rest
of the workspace root is MIT. Keep this in mind for where you add code.
cd projects\ed-autojump
.\.venv\Scripts\Activate.ps1
pytestThe offline unit + replay suite runs without the game; one @requires_game test
is deselected by default (it needs the live game running).
To run a specific test file:
pytest tests/test_cli_flow.py -vTo include the requires-game tests (live game must be running):
pytest -m "requires_game"- Add a function
step_<name>(ctx: StepContext, *, <params>) -> bool. Autojump step impls live inprojects/ed-autojump/src/ed_autojump/flow/steps.py; shared primitives reused across domains live inprojects/ed-core/src/ed_core/flow/steps_shared.py. - Register it by name with
register_step("<name>", step_<name>)into the one core-ownedSTEP_REGISTRY(ed_core.flow.step_registry). Registration is fail-on-duplicate — a colliding name raises rather than silently shadowing. - Document it in
projects/ed-autojump/procedures/procedures.md(the canonical action reference). - Write a unit test in
tests/. - Use the new step in a procedure TOML.
Steps must return True on success and False on failure. A False on a required step triggers the procedure's [on_required_fail] policy. Steps catch KeyError from the sender (an unbound bind) and return False cleanly — they never raise from a missing bind.
Procedures live in projects/ed-autojump/procedures/ as TOML files — there are
11 scenes (startup, arrival, traversal, smack_recovery, exploration, sc_resume,
dock, dock_resume, route_complete_park, honk, connection_recovery). They are
editable data, not code: reorder steps by moving lines, adjust timings and
counts in place. The loader validates every procedure at startup — unknown
action, unbound key, or an invalid skip_to / loop_to / retry_from /
retry_from_if_supercruise reference → the bot refuses to run. Because the
procedures are data validated at load, they carry no shape-pinning tests;
behavior changes to the steps they call still need tests.
Procedure structure:
parallel_tracks = ["honk"] # optional: names of parallel tracks to launch at start
[on_required_fail]
retry_from = "action_name" # action name of the step to jump back to
max_retries = 3
backoff_s = 2.0
steps = [
{ action = "wait", s = 1.0 },
{ action = "orient_compass", required = true },
{ action = "engage_jump", required = true },
]See procedures/procedures.md for the full action reference and required semantics.
- The default branch is
master; PRs targetmaster. - Feature / fix branches:
feat/<description>,fix/<description>. - Docs branches:
docs/<description>. - Keep changes small and well-scoped so any single commit is cleanly revertable — prefer many small labelled commits over few large ones. Open an issue first for anything large so the design can be discussed before you build.
The engine lives in ed-core (ed_core.flow); the autojump domain
(ed_autojump.flow) supplies its steps, boot routes, and the TOML procedures;
perception lives in ed-vision (the leaf). Dependency direction:
ed-autojump → ed-core → ed-vision.
The main loop (ed_core.flow unless noted):
-
flow/dispatcher.py— maps journal events to procedure names, and fires the real-time preempts (FSDJump → arrival, star-smack → smack_recovery, CONNECTION ERROR modal → connection_recovery) -
flow/interpreter.py— runs an ordered step list; handlesrequiredfailures, retry-from, retry_anchor,skip_to/loop_to, and parallel tracks -
flow/loader.py— loads and validates TOML procedures at startup -
flow/step_registry.py— the one core-ownedaction → fnregistry;register_stepis fail-on-duplicate -
flow/steps_shared.py— shared flight primitives reused across domains -
ed_autojump/flow/steps.py— the autojump step impls (theyregister_stepon import) -
ed_autojump/flow/boot_routes.py— boot-scene determination + the never-strand re-dispatch driver
Supporting modules:
-
ed_core/journal/— journal file tail + pydantic event models -
ed_core/status/—Status.jsonpoller +NavRoute.jsonreader -
ed_core/keys/— DirectInput scancode sender +.bindsparser +NullSender+LoggingSender -
ed_vision/— screen capture + nav-compass reader backends (cyan, yolo-onnx, ultralytics, opencv) + widget-ring fine pass + nav-panel/HUD/target-panel OCR -
ed_core/fsd/— danger-class list + FSD constants (from EDCD/coriolis-data) -
ed_core/launcher/— MinEdLauncher spawn + dryrun + menu navigation + credential wizards -
ed_core/recorder.py— session JSONL writer (keypress + journal event + outcome rows) -
ed_core/anonymizer.py— scrubs CMDR/FID/AccountID from session JSONLs (python -m ed_core.anonymizer in.jsonl out.jsonl) -
session_audit— pure functions for safety assertions over recorded sessions -
ed_core/panic.py— thread-safe trip flag; listeners callswitch.trip()from any thread -
ed_core/doctor.py— pre-flight environment checks
The project uses three test tiers:
-
Offline unit tests (
tests/test_*.py) — no game, no file I/O beyond fixtures; the bulk of the suite -
Recorded-session regression tests — auto-discovered from
~/ed-afk-sessions/; assert safety invariants: noHullDamage, no engagement on a dangerStarClass, no fuel starvation, no abandoned routes -
@requires_gamestub — one test requiring the live game; deselected by default
Behavior changes should come with a unit or replay-based test, since live
testing is not always available. Safety invariants are pure functions
(session_audit) individually unit-tested without any session file.