diff --git a/tools/AetherDb/Economy/OresAndProvinces.cs b/tools/AetherDb/Economy/OresAndProvinces.cs new file mode 100644 index 000000000..8f7ddce64 --- /dev/null +++ b/tools/AetherDb/Economy/OresAndProvinces.cs @@ -0,0 +1,318 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using GameCult.Caching; + +// Economy content: ores and provinces (rulings ores-are-regional, ores-fill-metal-roles, provinces-within-regions, +// province-types-dealt-per-region, everyone-mines, new-metals-is-nickel-iron). It comes before ores-to-alloys, which is +// re-authored on top of it. +// +// The model is Dwarf Fortress's, moved to asteroids (docs/research/2026-10-27-ore-geology-prior-art.md). In DF a rock layer +// decides which ores a site holds and many named ores smelt into a few shared metals. Here a belt's field kind is its body +// class, read from real asteroid taxonomy (carbonaceous C, stony S, metallic M, basaltic V), and a province is the kind of +// ground a region's zones sit on: which body classes its belts draw and which regional ores exist there at all. The ground +// tells one story: the belts are the debris of protoplanets that differentiated and then broke, so a core province is +// metal, a crust province is basalt, and the incompatible elements (uranium, rare earths, niobium, tungsten) sit only in +// the last crust to freeze. Common ground (primitive and chondrite) is dealt most; specialty ground is dealt less, so a region +// holds a spread and the specialty ore it lacks must come by trade. +// +// Ores are named minerals, each a raw good the mining station extracts. A metal's recipe takes that metal's ore role, and an +// ore fills the role of every metal that is at least a tenth of the mineral by mass (ruling ores-fill-metal-roles: whatever else +// the ore holds is slag for that recipe). So ilmenite is both titanium ore and iron ore, and which it becomes is the smelter's +// choice. Grade is not modelled per role, by that ruling; how rich a belt is lives in its yield. +// +// This batch owns extraction and the first smelting step: every ore, the metal each role feeds, the field kinds and the +// province types. It owns nothing downstream of a metal (steel, alloys, mill products are ores-to-alloys). Every faction places +// mining (ruling everyone-mines): a Mega controls territory and the resources in it. A faction with no station model stands in on +// the supply depot (ruling faction-station-models), Aeronautics Unlimited on its trade hub (ruling station-kind-family-stand-in). +// +// Apply list (Hands makes these code changes when the batch applies; they are not in this file): +// 1. Follow-up negative-authored-weights: the catalog check refuses a negative or non-finite FieldKindData.GenerationWeight, +// ProvinceData.GenerationWeight, ProvinceKindWeight.Weight, ProvinceOre.Weight and FieldYield.Abundance, and a yield, kind +// weight or province ore naming no record; the rule is a shape invariant, so a batch that introduces one is refused. +// 2. StationKindsCatalog's mining row says what this batch writes, so a fresh catalog and an authored one agree. +// 3. The AetherDb field-kinds command (Program.cs FieldKindsCatalog) is deleted: this batch is the one writer of field kinds, +// and the command would author a second "Asteroid" beside the renamed record. +public sealed class OresAndProvinces : EconomyBatch +{ + private EconomyAuthor _a; + + // Records this batch renames, found by key so a rerun converges after the rename. + private static readonly CultRecordKey NewMetalsKey = new CultRecordKey("00b5b3b2-2fc5-4adb-a1d7-c1a35d19afd3"); + private static readonly CultRecordKey RockKey = new CultRecordKey("043997a8-0661-4206-ab8a-10215ecf4efc"); + private static readonly CultRecordKey AsteroidKindKey = new CultRecordKey("2b0deb8dd4ca44da9a36581877bf629d"); + + public override void Author(EconomyAuthor author) + { + _a = author; + + foreach (var faction in _a.Catalog.GetAll().OrderBy(f => f.Name, StringComparer.Ordinal).ToArray()) + StandIn("mining", new CultRecordRef(_a.Catalog.RefOf(faction).Key), faction.Name == "Aeronautics Unlimited" ? "trade-hub" : "depot"); + + var miningKey = StationKindData.KeyOf("mining"); + var mining = _a.Catalog.Get(miningKey); + mining.Description = "Extracts ore from belts: regolith, iron and nickel minerals everywhere, and the regional ores (copper, titanium, platinum, gold, uranium, rare earths, niobium, tungsten, potash) only where the ground holds them; consumes tools and food."; + _a.Put(mining, miningKey); + + // ---- Ores: the raw goods. Fills are metal roles; abundance is the field kinds' business, below. + + var regolith = Rename(RockKey, "Regolith", "Crushed silicate rubble and dust, the bulk of every belt: what is left when the ore is picked out, and the aggregate cast habitats and berms are made of.", 1f, 1, 14, 6, + "Regolith is what every belt is mostly made of, and nobody fights over it. Orbital Forge casts it into habitat shells on a cage of rebar, so a hauler full of regolith heading for an empty rock means someone means to live there."); + + var nickelIron = Rename(NewMetalsKey, "Nickel-Iron", "Native nickel-iron, kamacite and taenite, cut from metallic asteroids: about nine parts iron to one of nickel, with a trace of cobalt and platinum.", 1f, 10, 10, 4, + "Metallic asteroids are the cores of broken protoplanets, iron that cooled so slowly it crystallised in plates a hand wide. The cut face rings when struck, and crews price it by the cut, not the tonne.", + "iron ore", "nickel ore"); + + var troilite = Ore("troilite", "Troilite", "Iron sulphide (FeS) in grains and nodules through stony asteroids: iron ore, with the sulphur driven off as gas.", 1f, 4, 10, 4, + "Troilite is the bronze fleck in a broken chondrite, and the reason a stony-belt smelter smells of sulphur. It is poor iron, but it is everywhere, and a habitat that cannot buy iron can always roast troilite.", + "iron ore"); + + var magnetite = Ore("magnetite", "Magnetite", "Iron oxide (Fe3O4) grown in the wet clays of carbonaceous asteroids: rich iron ore that a magnet lifts straight out of the crushed rock.", 1f, 6, 10, 4, + "Carbonaceous rocks were once wet, and the water grew magnetite in them as framboids and plates. Crews in the dark belts sweep crushed rock with a magnet drum and keep what sticks; the rest of the rock is somebody else's water.", + "iron ore"); + + var ilmenite = Ore("ilmenite", "Ilmenite", "Iron-titanium oxide (FeTiO3), the black sand of basaltic crust: titanium ore and iron ore at once.", 1f, 14, 12, 4, + "Ilmenite is the dark sand of old basalt flows, and every grain is both titanium and iron. Which one a smelter takes out of it says what its owner is short of this year, so a buyer's choice of ilmenite contract is read like a budget.", + "titanium ore", "iron ore"); + + var anorthite = Ore("anorthite", "Anorthite", "Calcium plagioclase (CaAl2Si2O8), the pale feldspar of anorthosite crust: the aluminium ore that molten-salt cells take apart.", 1f, 6, 12, 4, + "Anorthosite is the pale crust of a body that once had a magma ocean, the feldspar that floated to the top. Aluminium comes out of it only at a great cost in power, so where anorthite is cheap, ask where the power is coming from.", + "aluminium ore"); + + var pentlandite = Ore("pentlandite", "Pentlandite", "Iron-nickel sulphide ((Fe,Ni)9S8), bronze-yellow grains in sulphide melt and carbonaceous rock: the richest nickel ore, and iron ore besides.", 1f, 12, 12, 4, + "Pentlandite settles out of a sulphide melt like cream, so the sulphide provinces where an impact once melted a body are where nickel is cheap. Crews call a good pentlandite seam a cream line.", + "nickel ore", "iron ore"); + + var chalcopyrite = Ore("chalcopyrite", "Chalcopyrite", "Copper-iron sulphide (CuFeS2), brassy and iridescent: the common copper ore, found only where a sulphide melt pooled.", 1f, 12, 12, 4, + "Copper is scarce in the belts, and almost all of it is chalcopyrite in a sulphide province. Every wire, coil and heat pipe draws on it, so the regions that hold one trade copper for everything else, and the regions that do not wait in yards for their wiring.", + "copper ore", "iron ore"); + + var nativeCopper = Ore("native-copper", "Native Copper", "Metallic copper in sheets and wires through the vesicles of basalt, where hot water once carried it.", 1f, 16, 10, 2, + "Native copper lies in the old lava as sheets you can peel; the oldest Belt prospectors' stories are of native copper found in a vent pipe. It is rare, rich and hand-picked, and a find is kept quiet until the claim is filed.", + "copper ore"); + + var sylvite = Ore("sylvite", "Sylvite", "Potassium chloride (KCl) crystallised from the brines of wet carbonaceous bodies: potash ore.", 1f, 2, 8, 4, + "The wet bodies left salt where their brines froze out, the way Ceres wears its white spots. Farms buy sylvite first and arsenals second: the potassium that grows a habitat's algae is the potassium in its primers.", + "potassium ore"); + + var orthoclase = Ore("orthoclase", "Orthoclase", "Potassium feldspar (KAlSi3O8) from evolved granitic crust: a lean potash ore, worked where no brine salt is.", 1f, 1, 10, 4, + "Potassium feldspar is potash the hard way, cooked out of granite. Regions with no salt flats grind it anyway, and a farm co-op that buys orthoclase is a co-op whose neighbours have closed the salt trade to it.", + "potassium ore"); + + var nativeGold = Ore("native-gold", "Native Gold", "Gold, alloyed with a little silver, in grains and nuggets through the metal of core fragments.", 0.2f, 350, 6, 1, + "Gold sank with the iron when the protoplanets melted, so it is found in their broken cores, never in their crust. It wires every contact that must not corrode, and it is still the one metal people hoard without being told to.", + "gold ore"); + + var isoferroplatinum = Ore("isoferroplatinum", "Isoferroplatinum", "Platinum-iron alloy (Pt3Fe) in grains and nuggets, with iridium, osmium and rhodium: the native platinum of core fragments.", 0.2f, 650, 6, 1, + "Platinum came down with the iron, like the gold, and sits in nuggets where a core broke. A single nugget can pay a crew's season; a platinum strike in a contested core province has started more than one war that its history books call a border dispute.", + "platinum ore"); + + var sperrylite = Ore("sperrylite", "Sperrylite", "Platinum arsenide (PtAs2), small tin-white crystals in sulphide ore: a platinum ore that comes out of the same melt as the nickel.", 0.3f, 450, 8, 1, + "Sperrylite is platinum that rode up with the sulphide melt instead of sinking with the core, so a sulphide province holds platinum as well as copper and nickel. The arsenic that comes off in the roaster is why its smelters stand downwind of everything.", + "platinum ore"); + + var uraninite = Ore("uraninite", "Uraninite", "Uranium dioxide (UO2), pitch-black and heavy, in veins through the last crust to freeze: uranium ore.", 1f, 60, 10, 2, + "Uranium is an incompatible element: it would not fit in any early crystal, so it ended up in the last melt to freeze, and only evolved crust holds it. It is mined under licence and shipped under seal, and a broken seal is a crime in every bloc.", + "uranium ore"); + + var brannerite = Ore("brannerite", "Brannerite", "Uranium titanate (UTi2O6), black and glassy: uranium ore and titanium ore in one, worked for both.", 1f, 45, 10, 2, + "Brannerite is uranium locked in titanium oxide, hard to leach and worth it twice. A refinery that buys brannerite and sells only titanium has a uranium stockpile somewhere, and the licensing offices know to ask where.", + "uranium ore", "titanium ore"); + + var monazite = Ore("monazite", "Monazite", "Rare-earth phosphate ((Ce,La,Nd)PO4) with a little thorium, honey-coloured grains in evolved crust: the rare-earth ore.", 1f, 80, 10, 2, + "Neodymium from monazite is in every strong magnet, from an actuator to a drive pump, and the rare earths are in the premium superconductor tape that Cryonix certifies. The monazite crust provinces are few, so whoever holds one has a hand on every motor in the region.", + "rare earth ore"); + + var columbite = Ore("columbite", "Columbite", "Iron niobate (FeNb2O6), black tabular crystals from the pegmatites of evolved crust: niobium ore, with iron besides.", 1f, 100, 10, 2, + "Niobium is the conductor in the coils every yard but Cryonix's can wind: niobium-tin and niobium-titanium, heavier and hungrier for cold than the premium tape, and free of its licence. Columbite is how the gray-market fusion trade stays alive.", + "niobium ore", "iron ore"); + + var wolframite = Ore("wolframite", "Wolframite", "Iron tungstate (FeWO4), dense black blades from the vein ends of evolved crust: tungsten ore, with iron besides.", 1f, 60, 10, 2, + "Tungsten faces the plasma in every reactor and lines the throat of every hot nozzle; Orbital Forge's ugly refractory hardware is mostly tungsten. Wolframite is heavy for its size, so its haulers ride low on thrust and are easy prey.", + "tungsten ore", "iron ore"); + + // ---- Metals: the first smelting step. Each takes its ore role; downstream of a metal is ores-to-alloys. + + Metal("iron", "Iron", "Reduced iron pellet and sponge, smelted from whatever iron ore the furnace was fed; the rest of the ore leaves as slag.", 1f, 22, 3, 2, 600, 14, + "Iron is the one metal every province can make, from nickel-iron, troilite, magnetite or the iron in a copper ore, and the dry-refinery stack TerraCore's patents spread across Luna and the Belt still runs on all of them. A region short of iron is short of something else: power, crews or peace.", + "iron ore"); + + Metal("nickel", "Nickel", "Carbonyl nickel pellets, drawn off as a gas from nickel ore and redeposited almost pure.", 1f, 60, 4, 1, 900, 14, + "Nickel comes off the carbonyl line as a poisonous gas and settles back as pellets: the same carbon monoxide that does it kills a crew that forgets its sensors. Every stainless fitting, hot alloy and battery plate in a habitat starts as one of these pellets.", + "nickel ore"); + + Metal("copper", "Copper", "Cathode copper: sulphide ore roasted and smelted, or native copper melted, then electrorefined.", 1f, 70, 4, 1, 900, 16, + "Copper travels further than any other base metal because so few provinces hold it. A copper smelter in a region without a sulphide province runs on ore that crossed a boss line, and its prices carry the escort's fee.", + "copper ore"); + + Metal("aluminium", "Aluminium", "Aluminium ingot, reduced from anorthite in molten-salt electrolysis cells.", 0.4f, 50, 5, 1, 900, 12, + "Aluminium is electricity made solid: the cells that win it from feldspar draw more power than the habitat beside them. Where a refinery sells aluminium cheap, its power is cheap too, and someone should ask why.", + "aluminium ore"); + + Metal("titanium", "Titanium", "Titanium sponge, reduced from ilmenite or brannerite in molten-salt cells and pressed into billet.", 0.5f, 140, 5, 1, 1200, 14, + "Titanium is reduced a few kilograms at a time in salt baths that run for days, so a sponge shipment is small, heavy with value and always insured. Basalt-crust provinces make most of it; the brannerite crust makes the rest, and pays its licence fees twice.", + "titanium ore"); + + Metal("platinum-group-metals", "Platinum Group Metals", "Platinum with iridium, palladium, rhodium and osmium, refined to sponge from platinum ore.", 0.1f, 2400, 3, 1, 1800, 10, + "Platinum is the catalyst gauze that turns ammonia into nitric acid, the electrode in a fuel cell and the contact in a sensor that must not drift. Every fertiliser plant and every arsenal in a region depends on a few kilograms of it, which is why a platinum province is guarded like a gate.", + "platinum ore"); + + Smelt("Gold", "Gold bullion, melted out of native gold and parted from its silver.", 0.2f, 900, 2, 1, 600, 6, + "Gold is refined where it is mined, under guard, because a tonne of native gold ore is a crew's lifetime of wages. It goes into contacts and connectors, and into bars that nobody uses for anything at all.", + "gold ore"); + + Smelt("Uranium", "Uranium ore concentrate: yellowcake, leached from uranium ore and sealed in drums.", 0.5f, 150, 2, 1, 900, 10, + "Yellowcake is milled at the mine head because nobody wants to haul the waste rock, and sealed there because nobody trusts the haulers. A drum's seal number is its whole history, and an unbroken seal on a drum that never reached its reactor is a better story than a broken one.", + "uranium ore"); + + Smelt("Potassium", "Potash: potassium chloride and carbonate refined from potassium ore, fertiliser and chemical grade.", 1f, 6, 2, 1, 300, 6, + "Potash feeds farms first and arsenals second: the saltpetre in a primer is made from the same salt that grows a habitat's algae. A region with no brine-salt ground grinds feldspar for it, and pays for that in power.", + "potassium ore"); + + Metal("rare-earth-oxides", "Rare Earth Oxides", "Separated neodymium, praseodymium, lanthanum and cerium oxides, cracked from monazite and split by solvent extraction.", 0.5f, 320, 3, 1, 1800, 18, + "Splitting the rare earths takes hundreds of solvent stages, each a little better than the last, and the thorium that comes off is someone's licensing problem. A separation plant is the most valuable building in an evolved-crust province, and the most watched.", + "rare earth ore"); + + Metal("niobium", "Niobium", "Niobium metal, reduced from columbite and electron-beam remelted to conductor grade.", 0.5f, 380, 3, 1, 1500, 14, + "Niobium wire is what a fusion plant without a Cryonix contract runs on. It is heavier and colder to run than the premium tape, but no inspector can take it away, so the regions that hold columbite keep the independent reactors lit.", + "niobium ore"); + + Metal("tungsten", "Tungsten", "Tungsten powder and pressed bar, reduced from wolframite.", 1f, 240, 3, 1, 1200, 14, + "Tungsten is the wall between a reactor's plasma and everything else, and it wears: every plasma-facing tile is replaced on a schedule. A region that cannot buy tungsten has a date when its reactors go dark, and its neighbours know the date.", + "tungsten ore"); + + // ---- Field kinds: a belt's body class. CrossSection is reflectivity per cell, scaled to albedo with stony at the 5 it had. + + var stony = Kind(AsteroidKindKey, "Stony", 5f, 2f, + (regolith, 6f, false), (troilite, 1.5f, false), (nickelIron, 0.8f, false), + (pentlandite, 0.6f, true), (chalcopyrite, 0.5f, true), (sperrylite, 0.1f, true)); + var carbonaceous = Kind(new CultRecordKey("field-kind:carbonaceous"), "Carbonaceous", 1.5f, 4f, + (regolith, 5f, false), (magnetite, 1.5f, false), (pentlandite, 0.5f, false), (sylvite, 1f, true)); + var metallic = Kind(new CultRecordKey("field-kind:metallic"), "Metallic", 4f, 0.5f, + (nickelIron, 5f, false), (troilite, 0.8f, false), (nativeGold, 0.15f, true), (isoferroplatinum, 0.1f, true)); + var basaltic = Kind(new CultRecordKey("field-kind:basaltic"), "Basaltic", 9f, 0.3f, + (regolith, 5f, false), (ilmenite, 1.5f, false), (anorthite, 2f, false), + (nativeCopper, 0.3f, true), (chalcopyrite, 0.3f, true), (orthoclase, 0.8f, true), + (uraninite, 0.15f, true), (brannerite, 0.15f, true), (monazite, 0.2f, true), (columbite, 0.12f, true), (wolframite, 0.15f, true)); + + // ---- Province types: dealt per region from a deck of these card counts (ruling province-types-dealt-per-region). + + Province("primitive-reach", "Primitive Reach", 3, + new[] { (carbonaceous, 2f), (stony, 0.5f), (metallic, 0.2f), (basaltic, 0.1f) }, + new[] { (magnetite, 1.5f), (sylvite, 1f), (pentlandite, 1f) }); + Province("chondrite-plain", "Chondrite Plain", 3, + new[] { (stony, 3f), (carbonaceous, 1f), (metallic, 0.5f), (basaltic, 0.3f) }, + new[] { (troilite, 1.5f), (nickelIron, 1.2f) }); + Province("shattered-core", "Shattered Core", 2, + new[] { (metallic, 12f), (stony, 1f), (carbonaceous, 0.3f), (basaltic, 0.3f) }, + new[] { (nickelIron, 1.5f), (nativeGold, 1f), (isoferroplatinum, 1f) }); + Province("basalt-shards", "Basalt Shards", 2, + new[] { (basaltic, 15f), (stony, 1f), (carbonaceous, 0.3f), (metallic, 0.3f) }, + new[] { (ilmenite, 1.5f), (anorthite, 1.5f), (nativeCopper, 1f) }); + Province("sulphide-melt", "Sulphide Melt", 1, + new[] { (stony, 2f), (metallic, 6f), (basaltic, 10f), (carbonaceous, 0.3f) }, + new[] { (pentlandite, 2f), (chalcopyrite, 1.5f), (sperrylite, 1f), (nativeGold, 0.5f) }); + Province("evolved-crust", "Evolved Crust", 1, + new[] { (basaltic, 12f), (stony, 1f), (carbonaceous, 0.2f), (metallic, 0.2f) }, + new[] { (ilmenite, 1f), (uraninite, 1f), (brannerite, 1f), (monazite, 1f), (columbite, 1f), (wolframite, 1f), (orthoclase, 1f) }); + } + + // Sets this faction's stand-in on a kind, replacing any it had, so a rerun converges. + private void StandIn(string kindId, CultRecordRef faction, string standInKindId) + { + var key = StationKindData.KeyOf(kindId); + var kind = _a.Catalog.Get(key) ?? throw new InvalidOperationException($"The catalog holds no station kind '{kindId}'."); + kind.StandIns = kind.StandIns.Where(s => !s.Faction.Key.Equals(faction.Key)).ToList(); + kind.StandIns.Add(new StationKindStandIn { Faction = faction, Kind = new CultRecordRef(StationKindData.KeyOf(standInKindId)) }); + _a.Put(kind, key); + } + + private static CultRecordKey CommodityKey(string id) => new CultRecordKey("commodity:" + id); + + // A new ore: a raw good with an extraction recipe at the mining station that fills its metal roles. + private CultRecordRef Ore(string id, string name, string description, float mass, int price, int workforce, int perCycle, string lore, params string[] fills) + { + var key = CommodityKey(id); + _a.Put(new SimpleCommodityData { Name = name, Description = description, Mass = mass, Price = price }, key); + Recipe(key, "mining", 600, workforce, perCycle, lore, fills, new List()); + return new CultRecordRef(key); + } + + // An existing raw record given its ore name and an extraction recipe; found by key so a rerun after the rename converges. + private CultRecordRef Rename(CultRecordKey key, string name, string description, float mass, int price, int workforce, int perCycle, string lore, params string[] fills) + { + var record = _a.Catalog.Get(key) ?? throw new InvalidOperationException($"The catalog holds no simple commodity {key.Value}."); + record.Name = name; + record.Description = description; + record.Mass = mass; + record.Price = price; + _a.Put(record, key); + Recipe(key, "mining", 600, workforce, perCycle, lore, fills, new List()); + return new CultRecordRef(key); + } + + // A new metal: a simple commodity whose processing recipe takes its ore role. + private void Metal(string id, string name, string description, float mass, int price, int oreCount, int outputCount, float cycle, int workforce, string lore, string role) + { + var key = CommodityKey(id); + _a.Put(new SimpleCommodityData { Name = name, Description = description, Mass = mass, Price = price }, key); + Recipe(key, "processing", cycle, workforce, outputCount, lore, new string[0], new List { new ItemRole { Name = role, Count = oreCount } }); + } + + // An existing good (Gold, Uranium, Potassium) given what it is and a processing recipe that takes its ore role. + private void Smelt(string name, string description, float mass, int price, int oreCount, int outputCount, float cycle, int workforce, string lore, string role) + { + _a.Edit(name, c => + { + c.Description = description; + c.Mass = mass; + c.Price = price; + }); + var key = _a.Catalog.RefOf(_a.Catalog.GetAll().Single(c => c.Name == name)).Key; + Recipe(key, "processing", cycle, workforce, outputCount, lore, new string[0], new List { new ItemRole { Name = role, Count = oreCount } }); + } + + private void Recipe(CultRecordKey output, string kind, float cycle, int workforce, int outputCount, string lore, string[] fills, List roles) + { + var outputRef = new CultRecordRef(output); + _a.Put(new RecipeData + { + Output = outputRef, + OutputCount = outputCount, + Inputs = new List(), + RoleInputs = roles, + Cycle = cycle, + Workforce = workforce, + Upkeep = new List(), + StationKind = new CultRecordRef(StationKindData.KeyOf(kind)), + LoreHook = lore, + Fills = fills.ToList() + }, RecipeData.KeyOf(output)); + } + + // A field kind under its key, written whole: a rerun converges, and the existing kind keeps its key so saved belts hold. + private CultRecordRef Kind(CultRecordKey key, string name, float crossSection, float weight, + params (CultRecordRef Ore, float Abundance, bool Regional)[] yields) + { + _a.Put(new FieldKindData + { + Name = name, + CrossSection = crossSection, + GenerationWeight = weight, + Yields = yields.Select(y => new FieldYield { Commodity = y.Ore, Abundance = y.Abundance, Regional = y.Regional }).ToList() + }, key); + return new CultRecordRef(key); + } + + private void Province(string id, string name, int cards, (CultRecordRef Kind, float Weight)[] kinds, + (CultRecordRef Ore, float Weight)[] ores) + { + _a.Put(new ProvinceData + { + Name = name, + GenerationWeight = cards, + Kinds = kinds.Select(k => new ProvinceKindWeight { Kind = k.Kind, Weight = k.Weight }).ToList(), + Ores = ores.Select(o => new ProvinceOre { Commodity = o.Ore, Weight = o.Weight }).ToList() + }, new CultRecordKey("province:" + id)); + } +} diff --git a/tools/AetherDb/Economy/OresAndProvinces.dry-run.txt b/tools/AetherDb/Economy/OresAndProvinces.dry-run.txt new file mode 100644 index 000000000..4fc50ef8b --- /dev/null +++ b/tools/AetherDb/Economy/OresAndProvinces.dry-run.txt @@ -0,0 +1,374 @@ +Dry run of economy author OresAndProvinces on Yggdrasil (ygg-verify, image dotnet/sdk:10.0), batch commit 371b4d04a on base 8fa1fc21b. +Aetheria.cc sha256 68b37cb55c01... before and after (unchanged). Base report: 146 faults (L-consumer-demand 4, L-recipe 124, L-source-sink 18). +Running the batch twice in one trial gives the same 66 added, 7 changed: it converges. + +===== DRY RUN (exit 0) +changed station-kind:mining +changed 043997a8-0661-4206-ab8a-10215ecf4efc +added recipe:043997a8-0661-4206-ab8a-10215ecf4efc +changed 00b5b3b2-2fc5-4adb-a1d7-c1a35d19afd3 +added recipe:00b5b3b2-2fc5-4adb-a1d7-c1a35d19afd3 +added commodity:troilite +added recipe:commodity:troilite +added commodity:magnetite +added recipe:commodity:magnetite +added commodity:ilmenite +added recipe:commodity:ilmenite +added commodity:anorthite +added recipe:commodity:anorthite +added commodity:pentlandite +added recipe:commodity:pentlandite +added commodity:chalcopyrite +added recipe:commodity:chalcopyrite +added commodity:native-copper +added recipe:commodity:native-copper +added commodity:sylvite +added recipe:commodity:sylvite +added commodity:orthoclase +added recipe:commodity:orthoclase +added commodity:native-gold +added recipe:commodity:native-gold +added commodity:isoferroplatinum +added recipe:commodity:isoferroplatinum +added commodity:sperrylite +added recipe:commodity:sperrylite +added commodity:uraninite +added recipe:commodity:uraninite +added commodity:brannerite +added recipe:commodity:brannerite +added commodity:monazite +added recipe:commodity:monazite +added commodity:columbite +added recipe:commodity:columbite +added commodity:wolframite +added recipe:commodity:wolframite +added commodity:iron +added recipe:commodity:iron +added commodity:nickel +added recipe:commodity:nickel +added commodity:copper +added recipe:commodity:copper +added commodity:aluminium +added recipe:commodity:aluminium +added commodity:titanium +added recipe:commodity:titanium +added commodity:platinum-group-metals +added recipe:commodity:platinum-group-metals +changed 36746041-a5bd-4b95-aa18-294acaaeae62 +added recipe:36746041-a5bd-4b95-aa18-294acaaeae62 +changed 08c07793-bc06-48dc-adc2-c7e61ef2cb2b +added recipe:08c07793-bc06-48dc-adc2-c7e61ef2cb2b +changed a8e259fc-fbf1-477a-8248-0277611f1859 +added recipe:a8e259fc-fbf1-477a-8248-0277611f1859 +added commodity:rare-earth-oxides +added recipe:commodity:rare-earth-oxides +added commodity:niobium +added recipe:commodity:niobium +added commodity:tungsten +added recipe:commodity:tungsten +changed 2b0deb8dd4ca44da9a36581877bf629d +added field-kind:carbonaceous +added field-kind:metallic +added field-kind:basaltic +added province:primitive-reach +added province:chondrite-plain +added province:shattered-core +added province:basalt-shards +added province:sulphide-melt +added province:evolved-crust +66 added, 7 changed, 0 removed, 0 unchanged +154 faults +L-consumer-demand (5) + recipe:0b449ae1-7eab-47e8-ac3c-2b6f6ff01f00: 'Ballistic Powder' leads into thruster and Ammo but no use leads into a consumer good. + recipe:a8e259fc-fbf1-477a-8248-0277611f1859: 'Potassium' leads into thruster and Ammo but no use leads into a consumer good. + recipe:commodity:nitric-acid: 'Nitric Acid' leads into thruster, warhead and Ammo but no use leads into a consumer good. + recipe:commodity:nitrocellulose: 'Nitrocellulose' leads into thruster and Ammo but no use leads into a consumer good. + recipe:commodity:potassium-nitrate: 'Potassium Nitrate' leads into thruster and Ammo but no use leads into a consumer good. +L-recipe (119) + 03ff4335-fa65-4a89-8cea-68f70de01d60: Commodity 'Dashboard Ornament' has no recipe. + 0caaa08c-e0b6-4eaf-a9fd-7e03088371ea: Commodity 'Reaction Chamber' has no recipe. + 0d6a518d-24e9-40bf-9861-301de17b5161: Commodity 'Heat Sink Tile' has no recipe. + 11d9fd0c-c0dd-482f-8e2a-f7c289ed6a3d: Commodity 'AI Pilot' has no recipe. + 17032840-c285-4f33-82ae-6b03f1e1e56b: Commodity 'Cargo Pod' has no recipe. + 1af83f0b-11ae-4d03-acc3-c5d478d55f14: Commodity 'Spacesuit' has no recipe. + 1ea0df17-aba1-45bc-8d6e-a430c110e38d: Commodity 'Geiger Counter' has no recipe. + 20376ecd-77fa-4ffe-9be6-185158ee1bfc: Commodity 'All-Surface Stylus' has no recipe. + 2055f611-ef5d-4791-b1ad-f1757c081a99: Commodity 'Holo-desk' has no recipe. + 214fe497-cda4-4cdb-a7c4-fe656e5ff61c: Commodity 'Methane' has no recipe. + 22917d5e-313a-4470-a91e-0c78f1e08044: Commodity 'Spacewalking Boots' has no recipe. + 2aa99b2d-80ed-4640-9350-9affcfe6d8cd: Commodity 'Construction Rebar' has no recipe. + 2e08445d-c130-497c-9fb3-8d752a24e654: Commodity 'Algae' has no recipe. + 32934bf0-d7e9-432f-8863-e07c092b67f6: Commodity 'Inertial Compensating Seatbelt' has no recipe. + 33944941-5bd1-43ca-91a4-348c253f7e8b: Commodity 'Stealth Coating' has no recipe. + 34b16da9-1e5e-4fba-b256-eb8a38274b39: Commodity 'Neural Lace' has no recipe. + 35f02735-1993-4467-b3de-028c2d6e2276: Commodity 'Emergency Personal Life Support System' has no recipe. + 3689a855-9264-40f0-91b3-8b235dac80b6: Commodity 'Sure Bet Sherbet Fountain' has no recipe. + 3987140a-19c3-4b0b-8fa5-528f43a83afb: Commodity 'Magnetic EVA Boots' has no recipe. + 3a33da73-ba06-4574-afec-d529097408b5: Commodity 'Universal Translator' has no recipe. + 3acbb2bf-19fb-4591-bef1-dc9d5dde7e7a: Commodity 'Water' has no recipe. + 3c6bb1cc-70d8-400b-8d69-9c81339758f3: Commodity 'Bacteria' has no recipe. + 3c8b2b3d-ca1a-405f-966f-c64662a64418: Commodity 'Circuit Board' has no recipe. + 3ddbbb28-c166-4ab3-8a0b-c7b77c372f32: Commodity 'Mouth Adapting Gummy Molars' has no recipe. + 40004417-d242-47d2-9f27-1bbcf8548779: Commodity 'Trigger' has no recipe. + 4081eb4c-3376-4912-a230-c43096d90ad1: Commodity 'Travel Permit' has no recipe. + 421e9788-d094-4c17-88cc-0d820e3cfeca: Commodity 'Sheet Metal' has no recipe. + 4486cfad-3063-4667-80ae-5e4d615ee501: Commodity 'Hydrogen' has no recipe. + 452bbd60-11df-449b-a4b7-a4ca22527123: Commodity 'Secret Storage Compartment' has no recipe. + 4681d1af-1a6d-4c7e-b10d-5ee8295b9a79: Commodity 'Ship Fins' has no recipe. + 4810a43b-bbb9-447d-b62e-b723e4d88afc: Commodity 'Antireflective Coating' has no recipe. + 498c664d-05ff-45a0-b3b6-2b98feec8611: Commodity 'Super Tough Toffee' has no recipe. + 4b3fc716-d362-4379-8c65-f2c471647ed1: Commodity 'Crash Test Dummy' has no recipe. + 4c82acfa-b8e4-4601-9465-2fad107b1eff: Commodity 'Insulation' has no recipe. + 4d5929a9-5cb1-470c-a0b7-12f8abaf4497: Commodity 'Ship Decal' has no recipe. + 502a6ed8-73aa-4554-ae89-a50b67cfa9e0: Commodity 'Rope' has no recipe. + 515734e6-4287-470c-bf56-188c4b257420: Commodity 'Trousers' has no recipe. + 51e4dc3b-0107-4ab5-a2c6-02d34a1035b2: Commodity 'Mining Rights' has no recipe. + 5383d6b6-083b-4721-8f6b-426dba0beaeb: Commodity 'Hat' has no recipe. + 5449f7d3-b250-41cd-9e7e-ab2a7037cacb: Commodity 'Knife' has no recipe. + 5837ec5e-036b-4f73-9098-dbe11339909f: Commodity 'Safety Goggles' has no recipe. + 5bcddae5-10fe-4316-9dca-6dc5d53c899e: Commodity 'Local Newscast' has no recipe. + 5e2950d6-02df-461e-a35e-a4123c6a5639: Commodity 'Big Red Button' has no recipe. + 601a345d-6f0b-4bdb-8171-be4befaf9a33: Commodity 'Daily Feed Ad Slot (5ms)' has no recipe. + 63abe46b-ad99-4ac9-b5e4-d83a40465065: Commodity 'Joystick' has no recipe. + 64bccb57-3aa8-4e5f-829d-07e62295b0c7: Commodity 'Fungi' has no recipe. + 6713c2b2-d886-4440-b076-dd206c22848a: Commodity 'SpaceCast' has no recipe. + 675a1ebe-868c-4b27-a2eb-bee2fe5e356b: Commodity 'Paparazzi Drone' has no recipe. + 6821495a-4875-4350-a8e8-e813c3576aa8: Commodity 'Fuel' has no recipe. + 6d20c298-281e-46fc-be33-dbcc575d49d7: Commodity 'Cockpit' has no recipe. + 6d4c9e32-7ffd-45f6-8e08-86d544793774: Commodity 'Dials' has no recipe. + 6dc76b7c-65c3-4cc1-bc2a-eace8e4f58d2: Commodity 'Support Strut' has no recipe. + 6f0ed812-01b0-4767-90c5-0b6857bc2e29: Commodity 'Memory Download' has no recipe. + 7e9783b7-ab6c-4c50-bb99-4f1f3a3e240d: Commodity 'Animal Products' has no recipe. + 86d11f6a-9ddd-478d-8192-f047d38a7c6a: Commodity 'Moo-ed Lighting' has no recipe. + 8776c2fd-45f6-4ca6-8ef0-5214be830182: Commodity 'Diamond' has no recipe. + 8b026aea-1d79-49a0-b843-abdfcca31bab: Commodity 'Helmet' has no recipe. + commodity:actuator: Commodity 'Actuator' has no recipe. + commodity:ammonia: Commodity 'Ammonia' has no recipe. + commodity:cellulose-pulp: Commodity 'Cellulose Pulp' has no recipe. + commodity:oxygen: Commodity 'Oxygen' has no recipe. + commodity:steel: Commodity 'Steel' has no recipe. + 03740fd6-158d-43e9-b070-9a40e0b9bc45: Offered design 'Secure Cargo Bay' has no recipe. + 03a842b2-295e-4cf7-9faa-ecc4bc54eb76: Offered design 'Heavy Beam Laser' has no recipe. + 04255796-db68-48d2-81e5-8cfdab150706: Offered design 'Burn Drive' has no recipe. + 08226a8cb09844919c9922fbd7b76bef: Offered design 'Station Reactor' has no recipe. + 0d499d62-3b92-454b-9498-37d12616167f: Offered design 'Charged Scatter Blaster' has no recipe. + 106179618b054e8da61650bbec486c18: Offered design 'Fire Control Array' has no recipe. + 1c0cff5d-8668-45ea-9726-8b08c81d0267: Offered design 'Short-Range Missile Rack' has no recipe. + 205efba0-16af-477b-80e9-c9597cead5b4: Offered design 'Ring Reactor' has no recipe. + 20e9f41a-6bd2-4f6c-9740-7b707614509c: Offered design 'Cryogenic Heat Pump' has no recipe. + 291a01746063494fbfcb8c96f82aa8d3: Offered design 'Muon Fusion Station Reactor' has no recipe. + 2933c4ce-bf41-459c-b0d6-9583466b393d: Offered design 'Long Laser' has no recipe. + 2935b4d4-2ad5-4b90-8416-a85bbb38171b: Offered design 'Adaptive Radiator' has no recipe. + 2b2777c0-b756-4e19-9bf6-e5bac3cc385c: Offered design 'Turret Control Module' has no recipe. + 2c911da4-fad0-4a38-be5b-5e327c0c9e43: Offered design 'Industrial Thermostatic Heater' has no recipe. + 2e4c7753e0a24c13849818ac1dcfdba0: Offered design 'Passive Array' has no recipe. + 2e5193aa-3703-4ecc-911d-4d8394ce4c2f: Offered design 'Incendiary Rocket Pod' has no recipe. + 31325c3d-0537-40ec-9e5e-80930ea01496: Offered design 'Cockpit 2x2' has no recipe. + 32157982-b015-461e-ba4e-d321a23c2748: Offered design 'Long-Range Missile Rack' has no recipe. + 34b15c33-c01f-4712-ac75-5fcf779f0685: Offered design 'Capacitor' has no recipe. + 372d23cc-5ef0-42b5-9d96-807f2e412b0d: Offered design 'Muon Fusion Reactor' has no recipe. + 394612a6-9198-4797-a69b-c70cd0ee3273: Offered design 'High-Yield Reactor' has no recipe. + 3baa2c43-b389-4438-94cb-fbb04489cd77: Offered design 'Heavy Reactor' has no recipe. + 3e930a2c-ac72-4385-98aa-1c5b0b90db46: Offered design 'Medium Docking Bay' has no recipe. + 457ac901-aa54-4ba7-9df6-fbacdfb40b3f: Offered design 'Cell Blaster' has no recipe. + 46b66f9a-5c72-4e7a-ac9b-4dd7904cc4a1: Offered design 'Large Cargo Bay' has no recipe. + 480d6cc4-cd8a-49b6-9c89-211033e7c1d5: Offered design 'Compact Sensor' has no recipe. + 499f7891-c5df-4cbe-8431-9db7108102ec: Offered design 'Charged Blaster' has no recipe. + 49b4c15a-c10b-49c0-9dad-31dfb9b3a9b9: Offered design 'Cargo Bay' has no recipe. + 4a41dec8-6b65-46ee-b578-ba805f112c0c: Offered design 'Light Laser' has no recipe. + 4b019503-1865-4bad-a6e9-c85b558aacea: Offered design 'Long Radiator' has no recipe. + 4bc1fe6f-347a-425e-be1b-997920175bee: Offered design 'Compact Reactor' has no recipe. + 542169f2-363c-41f7-8d6d-60a5bd7578bd: Offered design 'Heat Pump' has no recipe. + 5cd802dd-ef0e-4303-bd87-c30988326e4b: Offered design 'Large Drive' has no recipe. + 5ee2ff03-0ac4-4cdd-89bc-81e29223900b: Offered design 'Guided Missile Launcher' has no recipe. + 632420a6-4419-4647-a92b-5e22ea289025: Offered design 'Lightning Projector' has no recipe. + 67111f5b41d5464e958ffc62bb3249da: Offered design 'Coolant Vent' has no recipe. + 726c1403ced34c2497693bf0f269c898: Offered design 'Inspection Scanner' has no recipe. + 72859489-677a-47a4-ae04-550e582ba29e: Offered design 'Sensor Array' has no recipe. + 7d14649c-a3b6-47c5-ab74-201b90072e2c: Offered design 'Tractor Beam' has no recipe. + 88e81a2b-45fd-49de-830f-c896adae8d5b: Offered design 'Racing Drive' has no recipe. + 8d84faaae78c490cb762289fd362bb0a: Offered design 'Launch Suppressor' has no recipe. + 9013c312-f37f-42a8-9efc-3d699759923b: Offered design 'Small Drive' has no recipe. + a0478430-3ec5-445d-94a7-f30e61b2b8d3: Offered design 'Swarm Rocket Pod' has no recipe. + a2ce2da35eff4f4aa6ec220449427a0d: Offered design 'High-Yield Station Reactor' has no recipe. + a828a676cc9e492f86ea7e08d75c4687: Offered design 'Launch Baffle' has no recipe. + ae05f4cb-0dd5-4f37-af96-cc61c9d61e1f: Offered design 'Small Cargo Bay' has no recipe. + b1403776e5fc4bd9bd0ed17d7e2a5e6e: Offered design 'Heavy Station Reactor' has no recipe. + b24ee1740ae04cdf9a07fff4105069f2: Offered design 'Thruster Overdrive' has no recipe. + bb5d9f73-612f-4060-8fb4-f72d6b93b616: Offered design 'Djinni' has no recipe. + bc3870ae-8e31-45ec-99d9-745a4262f78a: Offered design 'Radiator' has no recipe. + c07ea205005d423bb70d3bed899fdedd: Offered design 'Targeting Computer' has no recipe. + c4b20032-8cd3-4206-807f-97b296797425: Offered design 'Longinus' has no recipe. + d6e1b44396494e39a4e0a1b51c92a0ef: Offered design 'Ring Station Reactor' has no recipe. + d706ff66-c98c-4e60-a8e5-5dceb8dc3742: Offered design 'Rugged Drive' has no recipe. + ebfb35b5-3905-4510-a8cf-c09528f27172: Offered design 'High-Thrust Drive' has no recipe. + ef0f782e-9fa8-4059-bb8c-f16e1d3de100: Offered design 'Medium Drive' has no recipe. + fa568d572eec4969aad07599444a3892: Offered design 'Point Defense Laser' has no recipe. +L-source-sink (30) + recipe:043997a8-0661-4206-ab8a-10215ecf4efc: 'Regolith' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:08c07793-bc06-48dc-adc2-c7e61ef2cb2b: 'Uranium' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:0b449ae1-7eab-47e8-ac3c-2b6f6ff01f00: 'Ballistic Powder' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:3085fc8a-ec0d-4f6f-a339-ea43edb573e6: 'Ammo' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:36746041-a5bd-4b95-aa18-294acaaeae62: 'Gold' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:commodity:aluminium: 'Aluminium' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:commodity:autoloader: 'Autoloader Mechanism' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:copper: 'Copper' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:commodity:explosive-fill: 'Explosive Fill' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:fragmentation-case: 'Fragmentation Case' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:fuze: 'Fuze' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:gun-barrel: 'Gun Barrel' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:gun-forging: 'Gun Forging' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:he-warhead: 'High-Explosive Warhead' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:hexamine: 'Hexamine' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:iron: 'Iron' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:commodity:mine-dispenser: 'Mine Dispenser' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:nickel: 'Nickel' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:commodity:niobium: 'Niobium' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:commodity:nitric-acid: 'Nitric Acid' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:nitrocellulose: 'Nitrocellulose' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:platinum-group-metals: 'Platinum Group Metals' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:commodity:potassium-nitrate: 'Potassium Nitrate' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:primer: 'Primer' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:projectile: 'Projectile' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:rare-earth-oxides: 'Rare Earth Oxides' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:commodity:rocket-motor: 'Rocket Motor' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:shell-casing: 'Shell Casing' has no source: no chain of recipes reaches raw goods and no gate sells it. + recipe:commodity:titanium: 'Titanium' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + recipe:commodity:tungsten: 'Tungsten' has no sink: no recipe takes it or a role it fills, no design names a role it fills, no weapon draws it, no gate buys it. + +Depth + 00b5b3b2-2fc5-4adb-a1d7-c1a35d19afd3 depth 0 + 0271bb97-4ce8-4d64-97c3-8bfd3f76b2c6 depth none + 03ff4335-fa65-4a89-8cea-68f70de01d60 depth none + 043997a8-0661-4206-ab8a-10215ecf4efc depth 0 + 08c07793-bc06-48dc-adc2-c7e61ef2cb2b depth 1 + 0b449ae1-7eab-47e8-ac3c-2b6f6ff01f00 depth none + 0caaa08c-e0b6-4eaf-a9fd-7e03088371ea depth none + 0d6a518d-24e9-40bf-9861-301de17b5161 depth none + 11d9fd0c-c0dd-482f-8e2a-f7c289ed6a3d depth none + 13116166-f0c8-43cf-a35f-8fd448bc630c depth none + 17032840-c285-4f33-82ae-6b03f1e1e56b depth none + 1af83f0b-11ae-4d03-acc3-c5d478d55f14 depth none + 1b4a2bb358eb432eb1cfc0ccf3317303 depth none + 1ea0df17-aba1-45bc-8d6e-a430c110e38d depth none + 20376ecd-77fa-4ffe-9be6-185158ee1bfc depth none + 2055f611-ef5d-4791-b1ad-f1757c081a99 depth none + 214fe497-cda4-4cdb-a7c4-fe656e5ff61c depth none + 22917d5e-313a-4470-a91e-0c78f1e08044 depth none + 2aa99b2d-80ed-4640-9350-9affcfe6d8cd depth none + 2e08445d-c130-497c-9fb3-8d752a24e654 depth none + 2fd0d88b-f565-4021-85b4-02d9eae7be58 depth none + 3085fc8a-ec0d-4f6f-a339-ea43edb573e6 depth none + 32934bf0-d7e9-432f-8863-e07c092b67f6 depth none + 33944941-5bd1-43ca-91a4-348c253f7e8b depth none + 34b16da9-1e5e-4fba-b256-eb8a38274b39 depth none + 35f02735-1993-4467-b3de-028c2d6e2276 depth none + 36746041-a5bd-4b95-aa18-294acaaeae62 depth 1 + 3689a855-9264-40f0-91b3-8b235dac80b6 depth none + 3987140a-19c3-4b0b-8fa5-528f43a83afb depth none + 3a33da73-ba06-4574-afec-d529097408b5 depth none + 3aa1ac05-6d55-4569-8a4b-e1c3c6e07c61 depth none + 3acbb2bf-19fb-4591-bef1-dc9d5dde7e7a depth none + 3c6bb1cc-70d8-400b-8d69-9c81339758f3 depth none + 3c8b2b3d-ca1a-405f-966f-c64662a64418 depth none + 3ddbbb28-c166-4ab3-8a0b-c7b77c372f32 depth none + 40004417-d242-47d2-9f27-1bbcf8548779 depth none + 4081eb4c-3376-4912-a230-c43096d90ad1 depth none + 421e9788-d094-4c17-88cc-0d820e3cfeca depth none + 4486cfad-3063-4667-80ae-5e4d615ee501 depth none + 452bbd60-11df-449b-a4b7-a4ca22527123 depth none + 4681d1af-1a6d-4c7e-b10d-5ee8295b9a79 depth none + 4810a43b-bbb9-447d-b62e-b723e4d88afc depth none + 498c664d-05ff-45a0-b3b6-2b98feec8611 depth none + 4b3fc716-d362-4379-8c65-f2c471647ed1 depth none + 4c82acfa-b8e4-4601-9465-2fad107b1eff depth none + 4d5929a9-5cb1-470c-a0b7-12f8abaf4497 depth none + 502a6ed8-73aa-4554-ae89-a50b67cfa9e0 depth none + 515734e6-4287-470c-bf56-188c4b257420 depth none + 51e4dc3b-0107-4ab5-a2c6-02d34a1035b2 depth none + 5383d6b6-083b-4721-8f6b-426dba0beaeb depth none + 5449f7d3-b250-41cd-9e7e-ab2a7037cacb depth none + 5837ec5e-036b-4f73-9098-dbe11339909f depth none + 5bcddae5-10fe-4316-9dca-6dc5d53c899e depth none + 5e2950d6-02df-461e-a35e-a4123c6a5639 depth none + 601a345d-6f0b-4bdb-8171-be4befaf9a33 depth none + 63abe46b-ad99-4ac9-b5e4-d83a40465065 depth none + 64bccb57-3aa8-4e5f-829d-07e62295b0c7 depth none + 6713c2b2-d886-4440-b076-dd206c22848a depth none + 675a1ebe-868c-4b27-a2eb-bee2fe5e356b depth none + 679fb6a1-cefb-4adc-a49c-71942602196b depth none + 6821495a-4875-4350-a8e8-e813c3576aa8 depth none + 6af6446e40cb4cdd90d7a3fee04394d4 depth none + 6d20c298-281e-46fc-be33-dbcc575d49d7 depth none + 6d4c9e32-7ffd-45f6-8e08-86d544793774 depth none + 6dc76b7c-65c3-4cc1-bc2a-eace8e4f58d2 depth none + 6f0ed812-01b0-4767-90c5-0b6857bc2e29 depth none + 7e9783b7-ab6c-4c50-bb99-4f1f3a3e240d depth none + 86d11f6a-9ddd-478d-8192-f047d38a7c6a depth none + 8776c2fd-45f6-4ca6-8ef0-5214be830182 depth none + 8ac84e31-f0cf-43b2-8611-3316adfa4010 depth none + 8b026aea-1d79-49a0-b843-abdfcca31bab depth none + a8e259fc-fbf1-477a-8248-0277611f1859 depth 1 + commodity:actuator depth none + commodity:aluminium depth 1 + commodity:ammonia depth none + commodity:anorthite depth 0 + commodity:autoloader depth none + commodity:brannerite depth 0 + commodity:cellulose-pulp depth none + commodity:chalcopyrite depth 0 + commodity:columbite depth 0 + commodity:copper depth 1 + commodity:explosive-fill depth none + commodity:fragmentation-case depth none + commodity:fuze depth none + commodity:gun-barrel depth none + commodity:gun-forging depth none + commodity:he-warhead depth none + commodity:hexamine depth none + commodity:ilmenite depth 0 + commodity:iron depth 1 + commodity:isoferroplatinum depth 0 + commodity:magnetite depth 0 + commodity:mine-dispenser depth none + commodity:monazite depth 0 + commodity:native-copper depth 0 + commodity:native-gold depth 0 + commodity:nickel depth 1 + commodity:niobium depth 1 + commodity:nitric-acid depth none + commodity:nitrocellulose depth none + commodity:orthoclase depth 0 + commodity:oxygen depth none + commodity:pentlandite depth 0 + commodity:platinum-group-metals depth 1 + commodity:potassium-nitrate depth none + commodity:primer depth none + commodity:projectile depth none + commodity:rare-earth-oxides depth 1 + commodity:rocket-motor depth none + commodity:shell-casing depth none + commodity:sperrylite depth 0 + commodity:steel depth none + commodity:sylvite depth 0 + commodity:titanium depth 1 + commodity:troilite depth 0 + commodity:tungsten depth 1 + commodity:uraninite depth 0 + commodity:wolframite depth 0 + d02bcf71f2c8420b878f036cd1a33bea depth none + +Dry run. Pass "apply" to write Aetheria.cc. +YGG-SUMMARY/30c5f45eb83442b6: after 68b37cb55c012c9d1df97bbf0de5c0a56d1804ce5f16f498738cd4de51c88e4b GameData/Aetheria.cc +YGG-SUMMARY/30c5f45eb83442b6: BASE 146 faults +YGG-SUMMARY/30c5f45eb83442b6: BASE L-consumer-demand (4) +YGG-SUMMARY/30c5f45eb83442b6: BASE L-recipe (124) +YGG-SUMMARY/30c5f45eb83442b6: BASE L-source-sink (18) +YGG-SUMMARY/30c5f45eb83442b6: dry-run exit 0 +YGG-SUMMARY/30c5f45eb83442b6: 66 added, 7 changed, 0 removed, 0 unchanged +YGG-SUMMARY/30c5f45eb83442b6: 154 faults +YGG-SUMMARY/30c5f45eb83442b6: L-consumer-demand (5) +YGG-SUMMARY/30c5f45eb83442b6: L-recipe (119) +YGG-SUMMARY/30c5f45eb83442b6: L-source-sink (30) +YGG-SUMMARY/30c5f45eb83442b6: Dry run. Pass "apply" to write Aetheria.cc. +===== TWICE (exit 0)