Repository navigation
Crafting Planner
AE2Enhanced replaces AE2's native crafting calculation with an LP-based planner. Instead of expanding a recursive tree one craft at a time, it solves the whole request as a linear program, which lets it handle recipes that the native calculator cannot — including cyclic and self-referencing recipes such as A + 2B -> 2A or A -> 2B, B -> A.
The planner is not a separate UI or a new machine: it plugs into the normal "request a craft" flow. Whatever it produces is materialized back into a native crafting plan tree, so submission, the plan confirmation GUI and execution all reuse AE2's own paths.
- SCC condensation — the recipe graph is condensed into strongly connected components. Every condensed output of a pattern belongs to the same solve unit, so each pattern belongs to exactly one unit and the condensed graph is acyclic by construction.
-
Per-unit LP — units are solved in condensation topological order (consumers first) with a three-phase lexicographic linear program:
- Phase 1: minimise the total deficit — least missing material.
- Phase 2: under a cap on phase 1, minimise deficit on the requested rows — maximum delivery.
- Phase 3: under a cap on phase 2, minimise total pattern executions, with a small priority weight (
1 + ε·rank) so pattern priority is respected — fewest crafts. - Shared inventory and raw materials are counted once; deficits from one unit propagate to upstream units as demand.
-
Integerization and replay — the real-valued LP counts are rounded up (
⌈count − 1e-6⌉) and replayed against a simulated inventory in a feasible schedule order. Tail differences of ±1 surface as input gaps and are attributed precisely to a missing-material list. -
Materialization — the integer counts are attached to a native
CraftingTreeNode/CraftingTreeProcesstree, structurally identical to what the native calculator produces.
Any failure falls back to the native calculator. If the model is unusual, the LP declines, a unit is unresolved, or an exception is thrown, the request is handed to the vanilla recursive calculation (under a configurable time budget so a pathological plan cannot stall the server) and the player simply sees the native result.
A plan that actually executes a cycle pattern is tagged as a special plan. Special plans are routed exclusively to the Supercausal Computation Core — they are never handed to a normal crafting CPU, which would mis-execute them. If no computation core is available, submission fails and it is logged instead of silently running elsewhere.
Special plans are annotated in the plan confirmation GUI: self-propagation and cycle-chain entries show their round counts and per-round produce/consume figures, next to the sample-call count.
A plan with unresolved units cannot be submitted at all — the GUI shows it as unresolved rather than printing a misleading missing-material list.
All settings live in the Crafting section of config/ae2enhanced.cfg:
| Key | Default | Meaning |
|---|---|---|
specialCrafting |
true | Master switch for the enhanced planner (see the runtime toggle below) |
dagPlannerMode |
DEFAULT | Planner mode — OFF, FALLBACK or DEFAULT (see below) |
specialDetectorBudgetMs |
1000 | Time budget for the cycle detector on the server thread; over budget, the request conservatively skips special routing |
nativeCalcBudgetMs |
30000 | Time budget for the vanilla fallback calculation; on expiry the calculation is aborted and the plan is pinned to simulation state (cannot be submitted). Keep this below your server watchdog's max tick time |
cycleBoundarySolveBudgetMs |
1500 | Wall-clock budget for solving one cycle boundary inside the graph; on expiry that boundary is treated as unsolvable |
dagMaxNodes |
300000 | Graph-node ceiling before the planner declines and falls back to native calculation |
-
DEFAULT— every non-special request goes through the LP engine; the vanilla calculator is only used as an internal fallback. -
FALLBACK— the vanilla calculator runs first. If it reports missing materials (a simulation plan), the LP engine recomputes; if the LP result is better (non-simulation), it is adopted, otherwise the vanilla missing-material report is kept. -
OFF— the vanilla recursive calculator only.
/ae2e specialcrafting enable|disable|status
disable stops the enhanced planner and routes everything to the vanilla calculator; enable restores it. The switch is the Crafting.specialCrafting config value, so it persists.
/ae2e plan stats # per-path execution counts and compute-time distribution, plus conservation-check totals
/ae2e plan running # all busy crafting CPUs: output, progress, co-processors, elapsed time
plan stats breaks results down by path — special, dag, dagFallback and native — with average / max / p95 compute time, and shows the plan conservation check totals (passed / violated / skipped). A non-zero violation count means a planner produced an inconsistent tree; during normal play it should stay at 0.
Both commands are available to everyone by default; see Diagnostics and Performance for the permission key.
The crafting plan confirmation GUI is aware of the planner:
- Special-plan annotations for self-propagating and cycle entries.
- Sort modes — missing first (default), total demand, to-craft count, or special plans first.
- Search — filter the plan item list by name.
Sort preferences are stored in the client-side CraftingDisplay config section.