Skip to content

Retiring the Legacy Converter ​

Once you are done with it, delete the whole convert-legacy one-off migration tool in the fixed order below

convert-legacy is one-off migration scaffolding, not plugin behaviour. Treat the list below as its retirement contract: once every server has migrated, follow it to delete the converter without re-investigating the call sites

The decision-site convergence itself is documented in Item Matcher

Why this has its own page ​

The converter spans 6 packages (the shared CoreLib engine plus each module's own target definitions), and they have a deletion-order constraint. Get the order wrong and every other module's converter stops compiling, and that dependency is not visible from the code — LegacyMessageSink is still implemented by two classes that have nothing to do with migration

Deletion order ​

CoreLib's corelib.legacy is the shared engine and is depended upon by all 5 modules. Delete it on its own and every module's converter breaks, so it must be retired in the same change as the module-level legacy packages, never before

Full retirement list ​

Delete all of the following in one change:

  1. EmakiCoreLib's corelib.legacy package;
  2. each of the 5 modules' legacy packages (Cooking / Forge / Gem / Level / Strengthen);
  3. the single case "convert-legacy" -> ... line in each module's command router, plus the "convert-legacy" string in its tab completion list;
  4. the command.convert_legacy.* keys in both language files of each module; Gem and Strengthen also have command.help.desc.convert_legacy;
  5. each module's load-time reportLegacyItemSources() call (Strengthen has none);
  6. the implements LegacyMessageSink clauses on AbstractMessageService and LevelMessageService

Item 6 is the easy one to miss: LegacyMessageSink is the only member of the shared engine with a non-migration consumer, so those two implements clauses become dangling references when the package goes

Per-module layout ​

ModuleMigration targetCommand entryOther sites to edit after deletion
CoreLibshared engine, no targets of its ownnonethe implements on AbstractMessageService, LevelMessageService
Cookingnone left; the old flat station keys are handled by load-time fallback reads/emakicooking convert-legacyCookingCommandRouter, EmakiCookingPlugin
Forgenone left; the old and new key names coincide/emakiforge convert-legacyForgeCommandRouter, EmakiForgePlugin
Gemthe legacy match block in items/*.yml; no key-rename targets left/emakigem convert-legacyGemCommandRouter, EmakiGemPlugin
Levelresult_item_sources → item_sources in sources/*.yml/emakilevel convert-legacyLevelCommand, EmakiLevelPlugin
Strengthenthe legacy match block in recipes/*.yml/emakistrengthen convert-legacyStrengthenCommandRouter

Cooking, Forge, Gem, Level, and Strengthen still expose migration targets or compatibility conversion paths. Cooking's targets cover flat matcher keys across station settings and recipe inputs, retaining the fermentation-barrel input key needed for persisted slot identity. Forge's targets cover legacy source entries in materials and blueprint requirements, retaining the material key. Level still renames result_item_sources to item_sources; Strengthen converts the legacy match block; Gem handles its legacy source fields

Shared safety properties ​

These properties are what make deletion safe:

  • it is reached only from the command entry point and the load-time scanner warning; no runtime matching, loading, forging, cooking or inlay path calls into it;
  • it reads no runtime state, writes no persistent data container entry, and touches no player data; it only reads and rewrites configuration files inside the plugin data folder;
  • once the whole package is gone, the rest of the plugin still compiles apart from the sites listed in the table above

Module-specific boundaries ​

Cooking's four prefixed station keys are not converter targets. tool_matcher, spatula_matcher, container_matcher, and moisture_rules[].input_matcher are read at load time as a fallback for the nested tool / spatula / container / input nodes, so old configs keep working without the command. The fermentation-barrel item_sources key is retained because it shares a key space with persisted slot state

Gem's gems/*.yml construction base is now base_item_source. The parser still falls back to the old item_sources key for that value, and the sibling item_sources is the recognition condition, so no key rename is needed

Gem's match-block converter promotes item sources to the top level. The legacy match.item_sources becomes the top-level item_sources field rather than a type: item_source node inside matcher, so a converted items/*.yml needs no manual pass

Level's warning must not be removed ahead of the package. A rule carrying only result_item_sources has no recognised condition left and therefore matches every item, so the load-time warning is the operator's only signal until the converter runs

Strengthen has no item_sources rename to migrate. Its material tokens already use the sibling item_sources + matcher shape, and top-level recipe matching expresses item sources through source_patterns; only the legacy match block needs conversion here. Its converter turns match.source_ids into anchored, escaped regexes (^\Qemakiitem-xxx\E$) merged into the top-level source_patterns, so the output is directly usable

Telling when migration is done ​

You only need to watch the warnings: Cooking, Forge, Gem, and Level scan for leftover legacy syntax at startup and warn. Strengthen has no such call, so its leftovers only surface through an explicit /emakistrengthen convert-legacy preview. Once several consecutive releases pass without an operator reporting that warning, the migration period is over and the facility can be retired using the list above