Teaching model · Germany 2045 · provisional edition · v0.36.0

The Net Zero Game

Build a national 2045 pathway. Transport, building heating and industry are driven by the detailed game engine; agriculture, energy and waste complete the national inventory through transparent first-order modules. Play it with a dozen coarse controls in the simple view, or with all of them in the detailed view — the model, the reference scenario and the score are the same in both.
An open-source teaching model by Robin Girard, MINES Paris — PSL · about & other versions

Map of the model

2045 scenario dashboard

National view, on the UBA's KSG-sector inventory and its 2026 projection to 2045. Since this edition carries the land and food module, the agriculture line and the natural sink are computed from German land rather than read off a pathway — and the game perimeter grew by the whole agriculture sector, from 135.6 to 192.8 MtCO₂e.

Reference scenario

Emissions

Six emitting sectors, plus natural and technological carbon sinks.

Resource and system constraints

Three limited renewable molecule and biomass pools, plus the winter electricity peak.

Modal shares always add up to 100%. Use the − / + buttons or sliders to change the pathway.

How far, and by what

Four questions about mobility: how much of it there is, what the cars run on, what pulls the freight, and how much of it flies. Each one moves several detailed settings at once — the annex lists exactly which, and by how much.

Current fuel-car travel: destination in 2045

Allocation of passenger-kilometres currently supplied by fuel cars.

Passenger mobility

Current fuel-truck freight: destination in 2045

“Residual thermal” follows the classification convention used in the workbook.

Freight and fuels

The stock says how much heat the country needs; these say what covers it. Gas has no slider — it absorbs whatever the targets leave uncovered.

How much heat, and where it comes from

Ask for less heat, lose less of it, then change what produces it. Watch the winter peak on the dashboard as you electrify: it is the constraint that bites first.

Targets

Two settings, three numbers. You set how much of the heat runs on electricity and how much wood is burned; gas takes whatever is left, so it is read out below rather than set. The three always close on the heat the stock needs, which is why only two of them can be free.

How the electric heat is produced

Rebalanced to 100% of the electric heat above. The differences are not cosmetic: on the coldest evening an air-air or air-water pump falls to a COP of 2, a network heat pump to 1.5, a resistance stays at 1, and a hybrid moves 70% of its load onto gas.

Heat networks

Declared in TWh. With the network heat pumps set above, these say how much of a network is decarbonised; gas absorbs the rest along with everything else.

Building-stock performance

What the country builds

Not carried in this edition. The floor area a country starts each year, the cement and the structural steel it carries, and the timber frame that displaces part of them are the reference edition's. This package declares no construction intensities, so its cement volume rests on the intensity slider alone, and the four controls this paragraph introduces are not drawn.

What this does not do yet: the new floor area consumes cement and heats nothing. The heated stock is still frozen at its base-year surface, which is why the heating bill above does not move when you build more. That is the next stage, and it is named in the annex.

Everything that is not space heating

Hot water, cooking, air conditioning and the specific electrical uses — lighting, appliances, screens, and the servers behind them. Roughly as much energy again as heating, and until v0.8.0 none of it was in the account. Appliance efficiency and equipment growth pull against each other on the same usage, which is why both are here.

Air conditioning makes a summer peak, and the only peak this model constrains is a winter one — the number is carried, the asymmetry is not scored. Fuel switching in hot water and cooking is not a lever yet: their carrier mix is carried forward as observed.

What the heat balance and the stock do

Algebraic port of the five value chains represented in Excel: steel, ammonia, olefins, food and cement.

How much material, and made how

The three ways an industrial sector decarbonises: make less of the material, change the process that makes it, or use less energy for the same output. They are separate here because they cost different things and are argued about separately.

Steel and ammonia

How the hydrogen is made

Every tonne of hydrogen in the model — steel, ammonia, freight, chemistry, refining — comes from this mix. Until v0.12.0 all of it was electrolytic by assumption, which was a strong claim wearing no clothes: 87 TWh of electricity, and no way to ask what a reformer would cost instead.

Reforming trades electricity for methane, and in this edition the methane is mostly fossil: the gas emission factor starts at 175 gCO₂/kWh, built from dena's own figures as a 25% biogenic share of German 2045 methane against 227 for the fossil molecule. The colour of the hydrogen follows the colour of the gas, and here that colour is mostly grey, while the reformer still competes for the same pool the buildings and the power stations want. Only the biogenic quarter goes carbon-negative with capture, which is real physics and the most contested line in the model. Read the Controversy tab before leaning on it.

Plastics and industrial heat

The rest of industry

The manufacturing branches the game does not model as value chains, grouped into five: metals and machinery, minerals, the rest of chemistry, paper, and a diverse remainder. Together about 370 TWh of final energy, 140 of it electricity — 2.1 times the French block, which is roughly what the two industrial bases differ by. Output and processes would move separately; here only the process axis is offered, and the note below says why.

The output axis is not shown in this edition. The German block has an observed 2019 corner from JRC-IDEES and no national output index to 2045, so the output lever would move nothing at all and is hidden; the annex names it and says so. What is left is the process axis, and its meaning is narrower than its label: it is how much of the French per-branch process change is applied to German branch energy. The reference scenario sits at today's output and 100% process change.

Cement

One account, read four ways. Every hectare sits in exactly one of seven classes and the total never moves; the forest's carbon sink is an identity in cubic metres rather than a number somebody chose; what the country eats sizes its herd, and the herd and the fields are the agriculture sector's emissions; and the biogas, liquid fuel and wood the scoreboard scores are what this same land can supply. Nothing on this tab is a trajectory drawn between two points.

The land, the plate and what grows on the rest

Four questions about the same territory: what is eaten off it, what is planted on it, what is spread on it, and how much of it grows energy. Each one moves several detailed settings at once — the annex lists exactly which, and by how much — and they pull against each other on purpose, because they share one account, whose size the land table below states.

The land account

Seven classes, one fixed total: every hectare one of these levers takes out of a class arrives in another. Nothing absorbs a residual, because there is none — and what a hectare is worth depends entirely on which class it left.

Where the hectares are, and where they go

The same territory twice: as the land survey measured it, and as these levers leave it at the horizon. The two bars are the same length because the account closes — a partition, not a budget — so every gain you can see is a loss somewhere else in the same bar.

The legal reference. The Deutsche Nachhaltigkeitsstrategie asks for land take below 30 hectares a day by 2030 — about 11 thousand hectares a year, which is where this slider starts — and a Flächenkreislaufwirtschaft, net zero land take, by 2050. Germany took 50 hectares a day in 2024, down from 53 in 2023 and 77 in 2010. The comparison is exact in a way the reference edition's is not: the German indicator and this account are the same statistic, the Flächenerhebung, so the daily figure and the 19.2 thousand hectares a year the account is calibrated on are the same measurement read two ways. What the account adds is where the hectares come from — three quarters farmland, a sixth grassland, 8 % forest — and what each costs.

The forest and what is cut from it

The sink is growth, less mortality, less what is harvested, times a carbon coefficient per cubic metre. Cutting more wood therefore costs the sink what it gains the boiler — and the climate the forest lives through moves the answer further than any of these levers do.

The six pools of the sink

Positive absorbs, in both columns. The inventory writes a sink negative and this module writes it positive; the sign is applied once, where the national account needs it, so a pool shown here as a source really is one. Two of the six are sources today, and the artificial pool is a source because building on a hectare releases what was in it.

What the country eats, and what it sells

Demand sets production, production sets the herd. Trade sits in the middle: cut the milk and the dairy herd shrinks, but a large share of the beef is a by-product of that herd, so the suckler herd grows to meet a beef demand that has not moved. How large a share is a national number, and the annex gives this edition's.

The fields, the nitrogen and the farm's fuel

Mineral nitrogen is the longest lever here: it sets the nitrous oxide the soils give off, the carbon dioxide of urea and liming, and the ammonia the industry chain has to make — which is where the hydrogen goes.

The farm account — emissions, herd, plates and nitrogen

The agriculture sector is no longer a position on a published trajectory: it is this account, and it is built forwards. The inventory publishes three blocks and this module splits the livestock one into enteric and manure methane on its own authority, which is worth knowing before quoting the split.

What the land can supply

Manure that goes to a digester emits less than manure that sits in a store, and it produces methane while it is there. These levers, the manure one above and the harvest one further up decide all three biomass resources at once — and the scoreboard's biogas, biofuel and wood bands are now those resources rather than a rule. Cover crops share their hectare with the spring crop that follows; the fuel crops do not, and come out of the same arable land the food chain wants.

Biomass, supply against demand

Three pools, each built feedstock by feedstock and each drawn against what the rest of the scenario asks of it, on one scale. The supply bar is what this land makes; the demand bar is what the transport, building, industry and power levers have ordered. The scoreboard's three biomass bands are these same numbers, so a card and a chart cannot disagree.

How much CO₂ a kilowatt-hour carries in 2045. These are scenario assumptions, not measurements, and in a decarbonised pathway they decide almost everything that is left. They were editable in the source workbook and are editable here.

2045 emission factors

Observed 2020 values, for comparison: electricity 366, methane 227, liquid fuel 264, wood 27 gCO₂/kWh. The German electricity figure is combustion at the stack where the French edition's 79 is life-cycle, so the real gap between the two grids is wider than these two numbers show. Coal is fixed at 340 gCO₂/kWh because that is a property of the fuel, not a choice. Hydrogen and e-fuels carry no factor of their own — they are converted back into the electricity that made them.

Try this in class. Set methane back to 227 and liquid fuel to 264 and watch what happens: the scenario relies on every molecule being biogenic. The whole difference between a decarbonised transport sector and today's is carried by two numbers nobody in the game ever chose to produce.

What makes the electricity, and what the gas plants burn when the wind drops. Everything else in this model asks the power system for kilowatt-hours; this is the only tab that answers with what. The hydrogen share below is also the single largest methane lever in the game — every point of it takes gas out of a resource the buildings, the trucks and the factories are all competing for.

The electricity mix

One of six published German mixes: the three 2045 scenarios of the Netzentwicklungsplan Strom 2037/2045, and three built from the TYNDP 2024 capacity trajectories. It selects a set of shares, not a quantity: the mix is scaled to whatever electricity the rest of the model needs, so it answers with what and never how much. Every German mix has no nuclear at all — the last three reactors closed in April 2023 — so what the set spans is electrification and the split between domestic electrolysis and hydrogen imports. Capacity follows from energy through a load factor, and what has to be built each year follows from capacity through a lifetime, which is what the material account below reads.

TechnologyShareTWh/yGWGW built/ybn€/y

This does not check that the mix works. There is no hourly balance, no adequacy calculation and no storage: a 100%-renewable share structure is applied exactly as a nuclear-heavy one is, and the winter peak the building module computes is a demand-side number that nothing here has to meet. The cost is plant only — no fuel, no carbon, no network, no storage.

What the pathway weighs. A satellite account: it reads the scenario, nothing reads it back — the steel a wind farm needs is not charged to the steel industry the model already has, and none of it emits. Wiring it back would double-count against an industry whose output is set by its own levers.

Battery chemistry

The sharpest trade-off in the account, and there is no chemistry that is cheap in every metal at once.

Annual material demand of the transition, 2045

MaterialGenerationVehiclesBatteriesBuildingsTotal

Annualised cost in real euros, from the point of view of whoever pays: the industrial producer, the building owner, the household. Read the deltas rather than the levels — the levels carry all the parameter uncertainty, the deltas are what the game is about. Several of the unit costs behind them are French figures carried across and labelled as such in the sources annex; the German electricity and gas prices are Eurostat's.

Financing

Two separate rates, because an industrial investor and a household do not face the same cost of capital. This single choice moves retrofit economics by about a factor of two, which is why it is a lever and not a hidden constant.

Prices and provisional assumptions

The last two are flagged provisional: no primary source has been secured for them yet.

Industry — cost per tonne of product

Product and routeOutput (kt/y)Capital + fixedEnergy and feedstockCarbonTotal €/t

Carbon capture — what the two capture levers draw and cost

A capture plant takes every molecule up the stack, so it is powered and paid for on the fossil and the biogenic tonnes alike, while only the fossil ones lower the total. The last column divides the whole bill by the fossil tonnes alone: it is what a tonne off the national total costs through each lever.

WhereFossil captured (Mt/y)Biogenic captured (Mt/y)Electricity (TWh/y)Cost (M€/y)€ per fossil tonne

Aviation — what a ticket costs when the kerosene is synthetic

Flight categories and traffic are JRC-IDEES-2021's for Germany in 2019, on a departing-flight basis. The energy is the one the emissions account already charges, so the ticket and the carbon describe the same flight. These are costs, not fares: no margin, no tax, no yield management.

FlightDistanceCost todayof which fuelCost in 2045of which fuelChangekgCO₂ todaykgCO₂ 2045

Every flight gets the same relative increase, and that is a limit of the model, not a result. Everything that is not fuel is derived from today's ticket through a single fuel share of operating cost, so the non-fuel cost is proportional to distance. In reality a short flight carries far more per-flight cost — airport charges, crew, turnaround — so short-haul is much less exposed to the fuel price than long-haul, and its ticket here is understated. Correcting this needs a per-flight versus per-kilometre cost split that no source in hand provides.

Buildings — annualised cost of retrofit, equipment and energy

ComponentInvestment (bn€)Annualised (bn€/y)€/m²/y
The two segments are split by their energy mix, not by floor area. The residential stock takes 87% of the wood but only 54% of the gas, so a floor-area split would have misstated both — which is why the two €/m² figures now differ. The retrofit and equipment annuities are still split by area, because the model has no separate stock for them. That is the remaining approximation, and the reason to split the building module properly rather than its cost.

Households — annualised car mobility cost

Component€/household/yBasis
Purchase, insurance and maintenance are technology-neutral by decision. The electric-versus-thermal purchase premium and maintenance saving are not yet sourced, so they are excluded: only the size of the car fleet moves this block. A scenario that electrifies without changing mobility demand will therefore show its saving on energy only, and understate or overstate the true household cost.
What this cost layer does not include

Freight, aviation and public-transport costs; the counterfactual boiler avoided when a heat pump is installed; grid reinforcement; CO₂ transport and storage; the cost of the CO₂ feedstock for synthetic olefins; industrial equipment for food-industry heat; and any subsidy, tax or transfer. Nothing here says who actually pays.

Prices mix reference years — 2017 for the household mobility budget, 2025 for household energy, 2050 for industrial commodities — with no deflator applied. Treat cross-sector comparisons of levels with caution.

The published inventory and the government's own projection, side by side with the sectors the model does not compute. Germany has had no sector target since the 2024 amendment to the Klimaschutzgesetz, so the forward column is a projection with existing measures, not a promise. The reconciliation that ties both to the model is under the results, on the right.

The published inventory and the UBA's 2045 projection

Official sector1990Model coverage
Last observed year: 2024 is consolidated in the UBA's 2026 reporting round. The 2025 figure, 648.9 MtCO₂e gross, is a preliminary estimate and may still be revised.

What becomes of what the model does not compute

0% keeps the consolidated 2024 value; 100% reaches the UBA's 2026 projection for 2045. These are inputs, not results: at 100% waste and energy production sit exactly on the projected value, so two of the six national lines are a copy of the thing they are compared against. Agriculture is no longer among them. Since this edition carries the land and food module the agriculture line is a constructive account — a herd, a nitrogen balance and 1.95 million hectares of drained peat — and the pathway slider that used to set it is declared, hidden and inert. Read the two lines that remain as an assumption about the rest of the economy, and remember that for Germany the endpoint is what the government expects to happen, not what the law requires.

The industry lever is a coverage defect, not a pathway. The model computes five value chains — steel, ammonia, olefins, cement and food-industry heat. Glass, paper, non-ferrous metals and the rest of chemistry are not among them. The size of that hole is computed from the official total rather than assumed, and this lever only decides how fast it closes.
Official sources and perimeter caveats

The consolidated 2024 values come from the Umweltbundesamt's KSG-sector inventory, 2026 reporting round, on the Klimaschutzgesetz's own six sectors.

The 2030 and 2045 columns come from the UBA's Treibhausgas-Projektionen 2026 with existing measures. They are a projection, not a target. The 2024 amendment to the Klimaschutzgesetz replaced the per-sector annual budgets with one national path ending at 438 MtCO₂e in 2030; there is no statutory sector figure for 2030 or 2045 to compare a pathway against.

Three of the six 2045 sector values — agriculture, waste and energy production — are not published. The report gives the 2045 gross total of 212.5 MtCO₂e and three sectors; the other three are reconstructed here from the report's own qualitative statements and a residual, and the arithmetic is in DE.official.yaml.

The land-use line is positive: German LULUCF has been a net source in every year since 1990, +57.8 MtCO₂e in 2024, against a statutory requirement of at least −40 MtCO₂e by 2045. Engineered removals are the UBA's projected 6.2 MtCO₂e, not a closure residual.

A model that shows its sources still hides which of them are argued over. This names them. Everything here is visible elsewhere in the annex — a reader should not have to reverse-engineer which numbers are settled and which are live.

This is open source, and the point of it is that you can check it. If a number looks wrong to you, that is a contribution, not a complaint.

Where it came from

It started as a home-made Excel workbook — the kind every teacher builds and nobody else can read. Rebuilding it with the help of AI made it something else: every formula is declared in a YAML file, not buried in a cell, and every assumption carries its value, its bounds, its provenance and its sources. The engine that runs in your browser, the annex you are reading and a Python checker are all compiled from those same two files, and a test fails the build if the two engines ever disagree. A value shown and a value used cannot differ.

That is the whole argument for the rewrite. Not that it is more accurate than the spreadsheet — in places it is the same numbers — but that you can audit it.

Who made this, and where it lives

Built by Robin Girard, MINES Paris — PSL. The project page, with every published version kept at its own permanent link, is at robingirard.eu/TheNetZeroGame.html — a scenario shared with a class still opens against the model it was built on.

It is open source. Everything, including the model, its sources and this page:

Tell us what is wrong

In English, French or German, whichever you prefer. Bugs, remarks, a figure you disagree with, or a source we should have used and did not — this German edition is provisional and the list of what is still a French value is in the package's NOTES.md.

What happens to it. Every disagreement about a number gets one of three answers, and we will tell you which: the assumption changes, or we explain why it does not, or — when the honest answer is that reasonable people differ — it goes into the Controversy tab so the disagreement is visible to everyone rather than settled quietly.

Before you start

Strategy prompts — not solutions

Four ways in, none of them an answer. A winning combination does exist — every band can be met at once — but there is more than one, and the interesting part is which trade-offs you accept to get there: emissions against electricity, molecules against demand, this decade's peak against the next one's materials.

Start with demand

Ask which services must grow, which can stabilise, and where efficiency or sufficiency can reduce energy before changing technologies.

Electrify selectively

Prioritise direct electricity where it is efficient, while watching the building-heating peak and electricity used indirectly for H₂ and e-fuels.

Reserve scarce molecules

Biogas, biofuels and wood are limited pools. Consider which uses have few credible alternatives and which can switch to direct electricity.

Build a balanced portfolio

Combine modal shift, renovation, process change, material efficiency and carbon capture rather than relying on one lever.

How complete is the calculation engine?

ModuleCoverageWhat is recalculatedMain limitation
TransportDetailed algebraic portNeeds, modal shifts, unit energy, fuel split, H₂/e-fuel electricity and emissionsTwo legacy Excel double counts removed; the Excel edition still has them
Building heatingStock, allocated by target16 segments give the heat need and the 2020 peak anchor; targets allocate it across five electric technologies, biomass, networks and a gas residualOne-shot 2019→2045, no conversion-rate trajectory
Building, other usagesObserved levels, moved by leversHot water, cooking, cooling and specific electricity, by carrier, with efficiency, growth and electrificationNo stock and no technology detail; cooling makes a summer peak the model does not score
IndustryDetailed algebraic portFive value chains plus the remaining manufacturing branches, production routes, vector consumption, process emissionsInherits the French workbook's accounting conventions, and the horizon corners of the rest-of-industry table are French process assumptions on German structure
HydrogenProduction mixElectrolysis, steam reforming and autothermal reforming with capture, serving every consumerNo capture-train capital cost, no CO₂ transport or storage cost
Electricity supplyMix follows demandOne of six published German mixes — three from the Netzentwicklungsplan, three from TYNDP 2024 — sets shares; capacity, annual build, fuel and plant cost followNo hourly balance, no storage, no adequacy check — a 100%-renewable mix is applied exactly as a nuclear-heavy one
MaterialsSatellite accountSteel, concrete and critical metals for the generation build, vehicles and batteriesOne-way: nothing reads it back. Heat pumps absent, nothing recycled
National inventory bridgeScope 1, shared with the inventorySix sectors, both carbon sinks, gross and net totalsInternational aviation and shipping are the one remaining difference
Agriculture and wasteFirst-order trajectoriesLinear interpolation from observed 2024 to the German projection to 2045 order of magnitudeNo bottom-up physical drivers yet
Energy productionComputed from the mixThe fuel the chosen electricity mix burns, at the model's own emission factorsPower generation only — refining and fugitive emissions are outside the model
Carbon sinksSet directlyNatural and technological absorptions, each on its own sliderThe technological sink is 6 MtCO₂ a year that nothing here builds, powers or pays for, and the control is flagged above 20
Model-risk statement: this version is suitable for teaching and scenario comparison, and not for forecasting. The three limitations that would matter most if anyone tried: there is no adequacy check on the electricity supply, so no scenario here is shown to be buildable hour by hour; the building transition is a single jump from 2020 to 2045 with no rate; and agriculture and waste are interpolations rather than physical models. Each is stated where it applies rather than only here.

Transport levers

Modal destination shares redistribute the 2020 service demand of a source mode among 2050 modes. Existing activity in other modes remains in the calculation.

Passenger or freight demand reduction is applied to all passenger-kilometres or tonne-kilometres before modal allocation.

Biofuel share splits liquid fuel between biofuel and e-fuel. E-fuel production uses electricity with a 40% conversion efficiency.

Building-heating levers

The stock — 3 655 Mm² across 24 segments, 8 heating systems × 3 building types — says how much heat the country needs and anchors the winter peak. What covers that heat is set by target, and gas has no slider: it absorbs whatever the targets leave uncovered. That is what makes the account close by construction, and what makes the cost of not choosing visible.

Biomass is a target in TWh of wood burned, not a share, so it can be read straight against the biomass limit on the dashboard instead of being reconstructed from two shares. Electrification is a share of the heat need — of heat, not of energy; how that heat is produced is the next question down, and it is where the peak is won or lost.

The five electric technologies are not interchangeable. Over a year an air-water pump returns 3 kWh of heat per kWh of electricity, an air-air or network pump 2.5, a resistance 1. On the coldest evening both air pumps fall to 2, a network pump to 1.5, a resistance stays at 1, and a hybrid moves 70% of its load onto gas while running 95% electric over the year. Electric resistance is a slider rather than a stock that can only shrink, because a scenario may genuinely install more of it: it is cheap to fit and the worst thing that can happen to the peak.

Heat networks are declared in TWh of wood and of recovered heat. With the network heat pumps set above, those say how much of a network is decarbonised; gas absorbs the rest along with everything else. Recovered heat has no emission factor and adds nothing to the peak, which makes it the cheapest thing a network can run on — and the model does not check it against the waste-heat gisement the industry module computes, so raising it far is optimistic in a way nothing here will stop you being.

Retrofit improvement is an average demand reduction across the whole stock, not the percentage of buildings renovated. It acts on the heat need before any system sees it, so it benefits every vector alike and is the only lever that lowers the peak without changing a single technology.

If the targets over-subscribe — more heat allocated than the stock needs — gas floors at zero and the surplus is reported beside the sliders rather than absorbed. A scenario that has quietly allocated more heat than exists is one whose numbers should not be trusted.

What this replaced, twice. Until v0.5.0 building heating was an aggregate fitted at a single point: three linear regressions, one COP of 3, one peak COP of 2. Its three carriers each implied a different total heat demand — 332 TWh via electricity, 366 via wood, 229 via gas — so the shares were not a partition and substitution did not conserve heat: on a path to 95% electric, 41 TWh appeared from nowhere. The 60% cap on electric heating existed to hide that. v0.5.0 replaced it with a transition of surfaces, which conserved heat properly but could only ever shrink electric resistance and split the biomass a scenario used between "leaving" and "arriving" shares nobody could add up. v0.7.0 keeps the stock for the heat need and the peak anchor, and sets the allocation by target.

What it still does not carry: domestic hot water, cooking, cooling and the specific electrical uses — this is space heating only, roughly half of what a building consumes. The allocation is national, so it cannot say that a heat network needs density and a detached house will not get one; the residential/tertiary split of each vector follows the heat need rather than a separate stock.

The winter electricity peak constraint

The peak indicator is the additional winter power demand created by electric space heating. It is the constraint that makes electrification a trade-off rather than a free win: a scenario can be excellent on emissions and still be unbuildable because it asks the power system for too much capacity on the coldest evenings.

It is built from the stock: every segment's heat need, at its system's peak efficiency rather than its seasonal one, counting only the share of that system actually running on electricity on the coldest evening. Those three things differ by technology in ways a single COP cannot express. Air-air and air-water heat pumps fall from 2.5 and 3.0 seasonal to 2.0 apiece at peak; district-heating electricity falls from 2.5 to 1.5; electric resistance is 1 in both, which is why retiring it is the strongest single lever here. A hybrid heat pump runs 95% on electricity over the year but 70% on gas at peak, so it is by some distance the cheapest way to electrify heat without buying winter capacity — and the gas shows up in the emissions.

The 2020 figure of 40 GW is an anchor, not an output: the same expression is evaluated for the 2020 and the 2050 stock and their ratio scales it, so freezing the stock returns the anchor. Thresholds are 35 GW (target) and 45 GW (limit).

The reference scenario is over the limit, at 51 GW, and that is the finding rather than a slip. The workbook's own peak formula divided by the peak efficiency twice, and anchored its 40 GW against the 2020 useful heat instead of the 2020 peak load — two different quantities, so running its own 2020 stock through it returned 36.8 GW rather than 40. Its answer, 39.45 GW, is the number the old aggregate module was fitted to reproduce, and the 35/45 band was set against it. Corrected, the transition the workbook describes does not hold the winter peak flat: it multiplies it by about 1.27. The band was deliberately left where it was, because a scenario that meets its carbon targets and still cannot be built is the thing this indicator exists to show. The levers out of the red are real ones — retrofit, hybrid heat pumps, district heating, and not replacing electric convectors with more electric convectors.

Scope limitation: only building heating is counted, as in the workbook. Electricity used by transport, industry, hydrogen and e-fuels changes the annual energy but is not added to this peak, even though electrolysers and industrial loads do interact with system adequacy in reality.

Building usages other than heating

Space heating is about half of what a building consumes. This is the other half — hot water, cooking, air conditioning, and the specific electrical uses: lighting, appliances, screens and the servers behind them. For Germany it is 374 TWh, against 264 in France.

Two sources, because no single one covers both halves. The residential half is Eurostat's disaggregated household survey for 2023 — the same instrument for every Member State. The tertiary half is JRC-IDEES-2021 for 2021, because nothing harmonised covers the service sector by end use at all.

How well each half travels. Run the same extraction on France and every residential cell lands within 6% of the value the French edition carries from its own national survey. The tertiary half does not: hot water and specific electricity agree, but catering is out by a factor of 2.2 and air conditioning by a factor of 4.6. So German commercial catering is probably overstated here by about half, and German commercial cooling understated by about three quarters. Both are left as measured rather than corrected with a French ratio.

Heat-pump ambient heat and solar thermal are excluded — 9.4 TWh of German household hot water. The source reports them beside the electricity that drives the pump; counting both would double the energy.

It is a weaker model than the heating one, deliberately. There is no stock and no technology choice: each usage is its observed energy carried to 2045 and moved by efficiency, growth, or both. Fuel switching is not a lever, so a scenario cannot electrify a German gas water heater here — which matters, because hot water is the German building sector's quietest large gas use at 66 TWh. Air conditioning makes a summer peak and the only peak this model constrains is a winter one.

The accounting scope — read this before comparing anything

This model is a scope-1 account. Emissions are booked where the combustion happens. A power station's emissions belong to the power station; they are not spread back over everyone who used a kilowatt-hour. Electricity therefore carries nothing where it is consumed — a building that electrifies its heating shows zero emissions for that electricity, and the emissions appear in Electricity generation instead, computed from the fuel the chosen mix actually burns.

The consequence to hold onto: electrification moves emissions rather than removing them. Where they land depends on the electricity mix, which is a separate choice on the Supply tab. In Germany that consequence is larger than in France by a factor of six, because the German grid emitted 366 gCO₂/kWh in 2020 where the French grid emitted about 52.

This is the convention the UBA inventory and the Klimaschutzgesetz use, which is why the national reconciliation is a short page: the only difference left between the two accounts is international aviation and shipping, which the inventory reports as a memo item outside the national total.

The German electricity factor is a combustion figure, and the French one is not. 366 gCO₂/kWh is what German power stations emit at the stack; the French edition declares 79 gCO₂/kWh on a life-cycle basis. Adding the upstream of coal and gas would put the German figure nearer 400 to 420. So the gap between the two grids is wider than the two numbers shown, not narrower — which is the opposite of the mistake a reader is likely to make.

What the grid factor is and is not. For the horizon year the model derives it from the mix rather than declaring it. That is a combustion figure — no construction, no fuel chain, no decommissioning — so it is not comparable with a life-cycle study of the same grid. Comparing the two is the most common way to make this model say something it does not say.

The electricity mix

The supply follows the demand rather than standing beside it: whatever electricity the rest of the model turns out to need is served by the share structure of one of six published German mixes. Three are the 2045 scenarios A, B and C of the Netzentwicklungsplan Strom 2037/2045, ordered from low electrification with heavy hydrogen import to high electrification with large domestic electrolysis. Three are built from the ENTSO-E TYNDP 2024 capacity trajectories for Germany. Choosing a mix answers with what, never how much.

There is no nuclear axis. Germany closed its last three reactors on 15 April 2023 and no published German scenario rebuilds any, so nuclear is zero in all six mixes. The TYNDP confirms it per scenario: nuclear capacity for Germany is 0 MW in Distributed Energy, National Trends+ and Global Ambition alike, where France ranges from 28 to 66 GW.

Capacity follows from energy through a load factor — the Netzentwicklungsplan's own, read back out of its 2045 capacity and generation tables. German solar at 10.7% is below the French 14%, which is latitude and is the clearest single reason a German pathway needs more installed capacity per kilowatt-hour. German onshore wind at 30.8% is far above today's fleet, near 20%, and encodes the plan's assumption of repowering to taller machines. German hydro at 44.9% is above the French 29.5% because German hydro is run-of-river on the Rhine, Danube and Inn rather than reservoir.

Three conventions that are declared rather than sourced. Solar is split between ground and rooftop — halved in the three NEP rows, and on the TYNDP's own German rooftop share of about 53% in the other three. Offshore wind is entirely fixed-bottom: German offshore is North Sea and Baltic, both shallow, and no scenario has floating capacity. And the shares are taken over domestic generation, while the plan has Germany importing 180 to 215 TWh net in every 2045 path — worth about a fifth of supply, and not represented here.

This does not check that the mix works. There is no hourly balance, no adequacy calculation and no storage. The cost shown is plant only — capital recovered over each technology's own life, plus fixed operating cost — and its capital and material intensities are carried from the French package, so they are not a German cost study.

How the hydrogen is made

One mix serves every hydrogen consumer in the model. Three routes: electrolysis, which buys hydrogen with electricity at the 60% conversion the rest of the model uses; steam methane reforming, which buys it with methane; and autothermal reforming with capture, which does the same and puts 94% of the carbon underground — ATR concentrates the CO₂ in one stream, which is why it captures where a reformer with post-combustion capture struggles past 60%.

Ammonia no longer owns a route. It used to be two rows — 700 kt from electrolytic hydrogen, 200 kt from a reformer — which put the hydrogen decision inside the ammonia lever and nowhere else. Now every tonne consumes the same 5.94 MWh of hydrogen and the mix decides how it was made, which is where that decision belongs: the same reformers serve steel and everything else.

The capture credit is charged against the physical carbon, not against the emission factor. Those are different numbers and both are needed: efGas — 175 gCO₂/kWh for Germany, where France assumes 25 — answers "what does burning this count as?", while carbon_in_methane at 202 gCO₂/kWh answers "how much carbon is there to capture?". A capture plant removes molecules, not conventions.

Hence the negative number, and hence the warning. Reforming biomethane with capture takes carbon out of the air and puts it underground, so the route reads about −13 MtCO₂ a year at full deployment — enough to close three quarters of the gap to the German projection on its own. That is the physics of BECCS. It is also the point at which this model will most easily mislead: it says nothing about whether the biomethane exists, what land it came from, or whether the storage holds. The Controversy tab says so too.

What is missing. No separate capital cost for the capture train — the ATR route uses the reformer's annuity, which understates it. No transport or storage cost for the CO₂. And the methane a reformer needs is charged to the biogas pool, which at full reforming is well past anything Germany could supply.

Materials of the transition

A decarbonisation pathway is usually argued in TWh and MtCO₂. This says what the same pathway weighs: the steel, concrete and critical metals it asks for each year in 2045.

It is a satellite account, and deliberately a one-way one. It reads the scenario; nothing reads it back. The steel a wind farm needs is not charged to the steel industry the model already has, the concrete is not charged to cement, and none of it emits. Wiring it back would double-count against an industry whose output is set by its own levers — so the honest thing is to compute the demand and put it beside the supply rather than inside it. A test pins that no material lever moves emissions, energy or cost.

What drives it. Generation is a declared build rate in MW per year, because the model has no electricity supply module: it computes demand, not a mix. Vehicles are a declared annual production, but the share of it carrying a battery follows the player's own electrification levers for cars and trucks. Those levers are shares of demand rather than of production; over thirty years the two converge, and the approximation is stated rather than hidden.

The chemistry lever is the sharpest trade-off here. LFP carries almost no cobalt — 7 grams per MWh against 27 kilogrammes — and a quarter of the nickel, but 4.4 times the lithium, 490 kg per MWh against 111. There is no chemistry that is cheap in every metal at once.

Two comparisons worth reading. The transition's steel against the steel this scenario's own industry produces: both sides move with the player, so electrifying harder raises the steel needed and, if the industry levers are left alone, does not raise the steel made. And its concrete against clinker — a ratio above one would not be an error, since concrete is mostly aggregate.

What is missing, and it is named rather than filled. Heat pumps are absent: no source in hand gives their material content per unit, and inventing one would put a number in the annex that nothing supports. Closing it needs a per-unit steel, copper and refrigerant intensity from an LCA or from ADEME. Flat glass, plastics and rubber are carried by the source for vehicles but not totalled here. Nothing is recycled: this is primary demand, so a scenario with a serious secondary-metal loop would need less than the account says.

Industry levers

Steel production change is the relative change in 2050 steel output compared with the country’s 2020 route volumes. The coefficient is used as 1 + g: +30% means a multiplier of 1.30, while −20% means 0.80.

H-DRI steel share splits primary steel between the BF-BOF and hydrogen direct-reduction routes. Recycled EAF steel is scaled by the same production-change coefficient.

Green ammonia is entered in kt/y. The workbook reference also contains 200 kt/y of grey ammonia; its treatment is documented as an accounting limitation.

CO₂ + H₂ olefins combines a new production-route share with plastic-demand reduction and an optional biogenic-CO₂ credit.

Clinker ratio and capture separately affect cement production-process emissions — the decarbonation of the limestone, about 0.53 tCO₂ per tonne of clinker. The kiln burns 1.064 MWh a tonne on top of it, and waste-derived fuel sets how much of that heat is waste, about half of it biomass. Capture takes the whole fossil stack, calcination and fuel; the biogenic CO₂ of the waste goes up the same stack and is not credited.

The land account, the forest and the carbon sink

German land emits. The account below is a partition of 35 768 293 hectares — the land survey of 31 December 2023, one nomenclature, one published national total — and the six inventory pools it drives were a net source of 57.84 MtCO₂e in 2024. France's absorbed 51.9. The whole difference is peat.

The seven classes come from the Flächenerhebung: arable land and permanent crops from the farm survey (11.656 and 0.198 Mha), forest from the survey's Wald (10.689), semi-natural land from Gehölz, Heide, Moor, Sumpf and Unland together (1.058), water and wetlands (0.825), settlements and transport (5.207), and grassland as the residual of the survey's own agricultural class (6.135). Two reconciliations travel with them. The survey's agricultural class is 1.42 Mha wider than the farm survey's utilised agricultural area, so the herd grazes the farm survey's 4.714 Mha and grassland_rough is negative here where it is positive in the reference edition. And the forest identity runs on the Bundeswaldinventur's 10.8 Mha of Holzboden rather than on the survey's forest class, because the two are different perimeters.

1.945 million hectares of drained organic soil — 5 % of the territory — are declared row by row as peat_area and peat_ef, from Table 325 of the National Inventory Report and the pools that go with it: cropland 0.339 Mha at 28.0 tCO₂e a hectare a year, grassland 1.062 at 27.1, forest 0.285 at 11.6, wetlands and water 0.171 at 21.9, settlements 0.089 at 18.3. Together they are 46.9 MtCO₂e inside the land-use pools, and a further 3.3 MtCO₂e of nitrous oxide from the same soil is booked in agriculture, which is where the inventory books it — the Thünen Institute's independent mapping gives the same 1.93 Mha. Peatland is not a detail of the German land account; it is most of it. Rewetting is the lever, and it is a share of a state rather than a rate: a hectare put back under water stays wet, and it still emits about 5 tCO₂e a year, mostly methane, so the lever buys roughly 40 of the 50 megatonnes rather than all of them.

The forest identity is k · (P·A − M·A − H) on the fourth Bundeswaldinventur: a gross increment of 9.4 m³ a hectare a year, 16 % below the previous decade, a mortality of 1.8 left standing or lying, 10.8 Mha of wood-producing area, and a carbon coefficient of 1.18 tCO₂ per cubic metre from the inventory's own stock pair — 1 184 Mt of carbon in 3.67 billion cubic metres. Two German particulars. The harvest is published in Erntefestmeter ohne Rinde and the increment in Vorratsfestmeter, so the lever is in the statistic's own unit and forest_harvest_volume_factor = 1.25 converts it; and the harvest statistic reports 3.1 Mm³ of nicht verwertetes Holz — felled and left in the forest — which is a fifth harvest row, a removal for the forest and a fuel for nobody.

What is calibrated, and how much. Three per-hectare coefficients are fitted on the 2024 pools they reproduce: mineral grassland +0.74 tCO₂/ha absorbed, mineral cropland −0.69 emitted, and 157 tCO₂ per thousand hectares of annual land take. The largest fit is forest_litter_soil_sink at +9.41 MtCO₂/y against published mineral-soil lines worth +0.28: it reconciles a forest identity built on a ten-year inventory mean — which contains the 2018–2020 bark-beetle catastrophe — with a single quiet year's category total. The constant's own why says so, names the three alternatives that were tried and rejected, and names what would close it: the 2024 pool split of the 2026 inventory submission, which was not available when this package was written.

In the simple view. Plant forest and protect soil moves five of these levers at once — new forest to 30 kha a year, the harvest down to 40 Mm³, the long-lived share up to 55 %, land take to zero and the rewetting to 100 %. Two of the five segments are re-pointed for Germany, because the German sliders are not the French ones; the annex lists every segment.

The farm — diet, herd, nitrogen and ammonia

Agriculture is computed here, not set. A chain runs from what Germany eats and exports to what its farms produce, from production to the herd, and from the herd and the fertiliser to the emissions: 34.92 MtCO₂e of livestock, 18.39 of crops and soils and 7.50 of farm and forestry engines in 2024, which is the 60.8 the Klimaschutzgesetz books for the sector.

The herd is the November 2024 survey: 10.5 million cattle of which 3.6 million dairy cows and 0.62 million suckler cows, 21.2 million pigs, 167.3 million poultry places and 1.66 million sheep and goats. The per-head factors are the inventory's own implied methane — a dairy cow 142.8 kg enteric and 24.2 kg from manure — with the 2.88 MtCO₂e of manure nitrous oxide spread by nitrogen excretion so the six factors reproduce the published total. Four fifths of German beef is a by-product of the dairy herd, against two fifths in the reference edition, because 0.62 million suckler cows cannot supply 1.05 Mt of beef. The consequence is counter-intuitive and it is the module's: cutting dairy consumption alone makes the suckler herd grow.

The fields. The arable area is asked for rather than held. The base-year arable area net of the fuel and methane crops — 9.49 of the 11.66 Mha — is split into four uses and each is scaled: food by the population, feed by the herd, exports by their own lever, the rest held. German arable land is far more feed-oriented than French: 61 % of it grows feed. Divide by the yield index — the organic share, at 65 % of a conventional hectare, and the mineral dose once it falls below the plateau; the reference keeps the base-year dose, so only the first moves here — and compare with what the account holds. The reference is 0.84 Mha short, and it is reported rather than clamped. The reason is the Bio-Strategie 2030: it sets 30 % of farmland organic, this module reads that on arable land, and organic farming in Germany is over-represented on grassland, so the reading is more demanding than the target.

Nitrogen, and the two lines that do not answer to it. 1 037 kt of mineral nitrogen, 930 of manure spread, 131 grazed and 149 fixed. The mineral factor implies a direct emission factor of 0.61 % rather than the IPCC's 1 %, because Germany uses regionalised factors. Two German lines are deliberately outside the dose: liming, 2.06 MtCO₂ driven by soil pH and area, and the nitrous oxide of drained agricultural peat, 3.26 MtCO₂e driven by drainage. Leaving either inside the nitrogen factor would have let a fertiliser cut switch off five megatonnes it has no effect on. A third German line, the digestion of energy crops, is 1.54 MtCO₂e and is booked on the energy-maize area, so it moves with the lever that causes it.

The ammonia link. The same mineral nitrogen sets what the industry chain has to make: 2 950 kt of ammonia at the base year, of which about a fifth is for German fields. A fertiliser decision is a hydrogen decision. The domestic share behind it is a labelled placeholder — the German import share was not published in the sources this package read — and the residual non-fertiliser tonnage carries that uncertainty one for one.

In the simple view. Eat less animal produce moves the three diets and the food waste; Fertilise less moves the dose, the legumes, the soil practices and the organic share together, because they are one decision about the same hectares. Two segments are re-pointed for Germany.

What the land can supply — biogas, liquid fuel and wood

The three biomass bands on this page are not targets. They are the methane, the liquid fuel and the wood the German land actually makes, computed from the same herd, the same forest and the same arable account as everything else on this tab.

Methane, 89.3 TWh at the base year. The German digester runs on a main crop: 1.35 million hectares of silage maize, cereal silage, grain and beet, yielding 15.2 tonnes of dry matter a hectare — 57 TWh of raw gas, more than half the whole pool. That is why this edition has a lever the reference edition does not. A cover crop grows between two main crops and costs no hectare; a field of silage maize cut for a digester is that field's whole season, so it enters the arable requirement and competes with the plates. Manure adds 15 TWh — 53 % of the collectable dry matter already goes to a digester, against a tenth in France — the 53 kha of cover crops add 0.7, and the residual is 15.7 TWh. That residual is 17.6 % of the base year where the reference edition's is 78 %, and the reason is not a better model: Germany publishes its digester feedstock as an area and a tonnage.

Wood, 148.8 TWh. The harvest is split between material and fuel at a share the long-lived-products lever moves one for one, at 2.14 MWh a cubic metre, plus the sawmill and pulp-mill fuel that comes back from the material half, plus 28.5 TWh of end-of-life wood and 5 of landscape wood. A fifth of the German wood supply comes out of a demolition skip rather than out of a forest, and no lever moves it. What the boiler does not see is the 3.1 Mm³ of felled wood left in the forest: it is a removal in the sink identity and a fuel for nobody, and folding it into the informal firewood would have handed this supply 6.7 TWh that does not exist.

Liquid fuel, 31.9 TWh. 0.81 Mha of rapeseed and ethanol crops at 15.9 MWh a hectare, plus waste fats, plus a net import of 15.9 TWh. The gross trade is much larger and runs both ways — the quota year's own accounting puts 81 % of the feedstock and two thirds of the fuel outside Germany, because German rapeseed biodiesel is exported while imported used cooking oil is burned here — and the band carries the net, because a supply band should score what the country actually has.

Cutting more wood costs the sink what it gains the boiler, from one harvest figure and one identity, so no scenario can have both. And the residue pool is split exhaustively between the digester and the second-generation liquid plant: a tonne of straw is methane or a liquid and never both.

In the simple view. Grow energy on the fields moves the cover crops, the straw mobilisation and the fuel-crop area together; two of its three segments are re-pointed for Germany. The energy-maize area is a detailed-view lever only, because raising it is a contested decision rather than an effort.

National reconciliation — method

The game and the national inventory do not measure the same thing. Reconciling them by a ratio, as earlier versions did, transfers relative change but hides two differences and any sub-sector the game does not model. Each difference is now its own line.

Both accounts are scope 1. The game books emissions where the combustion happens, which is what the UBA's KSG-sector inventory does: power-station emissions sit in the Energiewirtschaft sector, at stack level, and not in the sector that used the kilowatt-hour. That matters more in Germany than in France, because the German energy sector is 189.7 MtCO₂e against France's 31.2 — six times as much — so electrifying a German building moves a great deal more emissions than it removes.

International bunkers. International aviation and shipping are in the game and are a memo item outside the national inventory total; German international aviation alone was 27.4 MtCO₂e in 2024 against 12.1 in 1990. The deduction is computed from the model's own international rows, so it follows the scenario instead of being asserted.

The coverage gap. The game models five industrial value chains. Everything else the inventory calls industry is a named line whose size is the difference between the official industry total, 149.8 MtCO₂e in 2024, and what the model represents, 136.5 MtCO₂e computed bottom-up from JRC-IDEES for 2019 — see the constant industry_covered_2020 in the generated annex.

First-order sectors. Agriculture, waste and energy production interpolate linearly between observed 2024 and the UBA's 2026 projection for 2045. At 100% they sit exactly on the projected value, so those three rows are an input, not a result — and the value they sit on is a projection with existing measures, not a target.

Carbon sinks, and the sign. Germany's land-use balance is positive: it emitted 57.8 MtCO₂e in 2024 and has been a net source in every year since 1990. The sink lever is therefore signed and its default is zero — a land account that neither emits nor absorbs. §3a of the Klimaschutzgesetz requires at least −40 MtCO₂e by 2045 and the UBA's own projection is +26, a gap of 66. Engineered removals are that projection's 6.2 MtCO₂e, not a closure residual as in France.

Emission factors — today and in 2045

These were editable assumptions in the source workbook and are restored here as levers, because they are scenario choices rather than measurements, and because in a decarbonised pathway they decide almost everything that is left.

Carrier2020, observed2050, assumedWhat the 2050 value assumes
Electricity79 gCO₂/kWhderived No longer a slider. Under a scope-1 account the grid factor is a result of the generation mix, so the model computes it — about 1.7 gCO₂/kWh at the reference. That is a combustion figure and is not comparable with the 79 beside it, which is life-cycle: comparing the two is the most common way to make this model say something it does not say.
Methane227 gCO₂/kWh25 gCO₂/kWh That all 2050 methane is biomethane. Raising the slider back towards 227 shows what a failure of that assumption costs.
Liquid fuel264 gCO₂/kWh25 gCO₂/kWh That no fossil liquid fuel is left: every litre is biofuel or e-fuel.
Wood27 gCO₂/kWh0 gCO₂/kWh The biogenic-carbon convention. Note the workbook is not internally consistent here — it uses 27 for 2020 and 0 for 2050 for the same fuel.
Coal340 gCO₂/kWh, both years Coking coal at the IPCC default, 94.6 kgCO₂/GJ. Not a lever: it is a measured property of the fuel, not a scenario choice.
HydrogenDerived, not declared Hydrogen carries no factor of its own. It is converted back into the electricity used to make it, at 60% efficiency, and that electricity carries the electricity factor. The same holds for e-fuel at 40%.
Three corrections were made to the workbook's own accounting. Coal was charged at the hydrogen factor, 66.7 gCO₂/kWh, while the workbook's factor table declared it at zero and its 1.76 tCO₂ per tonne of steel already contained that same carbon — the coal was counted twice, and is now counted once, as energy. Gas used by steel and by grey ammonia was counted in the biogas resource but charged no emissions at all; all gas is now charged. And two legacy transport aggregations created about 32 TWh of electricity that no vehicle consumed; they are gone. Together these move the reference scenario from 47.2 to 40.6 MtCO₂. The Excel edition still contains all three.

Aviation — method, sources and what it leaves out

The ticket is built from the bottom: the energy the model already charges the flight, multiplied by a synthetic-fuel price, plus everything else derived from today's economics.

Distance comes from JRC-IDEES-2021's German traffic for 2019, on a departing-flight basis: passenger-kilometres divided by passengers, category by category — 490 km within Germany, 1 223 to the rest of Europe, 4 610 intercontinental. It is an average over each category, so "Germany ↔ Europe" blends a Vienna hop with a Lisbon sector.

Energy is the model's own aviation consumption, not a separate figure — 0.72 kWh per passenger-kilometre for domestic flights, 0.37 intra-European and 0.39 intercontinental. These are two to four times the figures the French edition shows for the same table, and the German ones are the physical values. The French rows carry twice the traffic at half the intensity, which is right in the product and wrong in both factors; the German rows carry the departing-flight traffic at the intensity that actually reproduces German kerosene — 107 TWh of passenger fuel in 2019. A German player therefore sees a long-haul return cost roughly twice the carbon a French player sees for the same distance, and that is not a modelling error.

For comparison, the raw German statistic is 38.5 g of kerosene per passenger-kilometre, because it also carries the freight in the holds and reflects actual load factors. A real ticket therefore emits more than the figure in the table.

Fuel price. The published estimates for sustainable aviation fuel disagree by a factor of six, and the two sliders span that range. The defaults sit mid-range and the ranges are the honest answer, which is why they are sliders. They are not German figures — no German SAF cost study was used — and the underlying technology costs are shared with the French edition.

Efficiency. The horizon carries the same consumption per passenger-kilometre as today, so the default gain is zero. Published trajectories converge on about 1%/year. The compounding window is 26 years for Germany against 30 for France, because the German horizon is 2045 — a small difference with a real effect at the top of the slider.

The rest of industry — how output and processes were separated

The manufacturing branches the game does not model as value chains: 370 TWh of final energy in Germany against 174 in France, more than the five modelled chains use between them.

What is German here and what is not

The observed corner is German — energy by branch and carrier from JRC-IDEES-2021 for 2019, on the Eurostat energy-use perimeter, which excludes the naphtha and gas that enter the chemical industry as feedstock. The three horizon corners are not: they apply the French scenario's per-branch process change to the German branch totals. Only the industrial structure is German.

The volume lever does nothing in Germany. France's output index is a national reindustrialisation scenario — textiles ×8.5, electronics ×3.1, naval and aerospace ×0.56 — with no German counterpart. Inventing one would be worse than admitting it, so the German output index is 1 at both ends and the slider moves nothing.

The decomposition is exact, not fitted

Energy is output × unit consumption, so it is bilinear in the two levers and four corners reproduce every combination exactly: E00 the observed 2019 situation, E11 the horizon scenario, E10 the horizon output at 2019 processes, E01 the horizon processes at 2019 output. At today's output, the horizon processes take the electricity of these branches from 139 to 301 TWh while cutting coal and fuel oil to zero.

Two group definitions differ from the French edition

Minerals is the non-metallic minerals branch minus cement, which the game models as a chain; checked against France, that construction is within 3%. Chemicals, other is the chemical industry minus the whole of basic chemicals, which removes more than the two chains the game models — chlorine, soda, methanol and fertilisers go with it — so that row is a lower bound. Against France the same construction under-counts by a quarter, and the German row probably does the same.

Conventions and what is still missing

Purchased steam is carried with gas, non-renewable waste fuel with coal, and residual fuel oil with the model's liquid-fuel carrier. Process emissions follow the same two levers. The cross-cutting efficiency and waste-heat ceilings are French ratios applied to German fuel; they are ratios rather than stocks, which is why they travel at all, and replacing them with German branch potentials is the first thing a German industry review should do.

Waste heat — a resource that decarbonisation consumes

Industrial processes reject heat. Some of it can be recovered and used instead of burning more fuel. The usual way to model this is a fixed reserve in TWh, and that is wrong in a way that matters here.

Why the gisement shrinks

Waste heat is a by-product of combustion and of process inefficiency. An electric furnace or a heat pump rejects far less of it, and at lower temperature. So the more a scenario electrifies industrial heat, the smaller the waste-heat resource it has left to recover. Recovering waste heat and electrifying heat compete for the same physics, and a model that treats the gisement as a constant lets a player count the same energy twice.

ADEME's study of French industry makes the coupling possible because it expresses the gisement against the fuel each sector burns, not as a bare total: 15.6 TWh recoverable on French 2019 industry out of 248 TWh of fuel — 6.3% on average, but from 1.2% in metals to 31% in paper, where drying dominates. Those percentages are what travels; the terawatt-hours do not. Applied to German fuel they give a German gisement, which is larger because German industry burns more, and no German excess-heat study was used to check it. The model attaches those intensities to the fuel, post by post, so the gisement follows whatever the scenario actually burns.

Conventions

Recovered heat displaces gas, the marginal fuel, and cannot displace more than the post burns. The second-order feedback — less gas means a slightly smaller gisement in turn — is neglected; at full recovery it is under half a percent. Transport and buildings carry no gisement because the ADEME study is industrial. Glass is listed by ADEME under both chemistry and non-metallic materials; it is assigned to materials here, its furnaces being the hotter of the two contexts.

What this does not say

That the heat can be used where it is produced. Above 100 °C it can displace process heat directly; below, it needs a heat pump to upgrade it or a district network to carry it somewhere useful, and neither is costed here. Roughly half the gisement is below 100 °C, so a recovery rate above 50% implicitly assumes one of those. Nor is the capital cost of recovery represented anywhere in the cost layer.

Energy efficiency — a ceiling, not a wish

Motors, drives, compressed air, insulation, heat integration: the cross-cutting savings that need no change of process. The danger with a lever like this is that it lets a player invent efficiency, so it is bounded by what a published study actually found.

The ceiling

RTE, after CEREN, identifies for French industry — this ceiling is a ratio carried into the German model, not a German study — a potential of 21.1% on industrial electricity and 19.8% on fuels, of which about 58% pays back in under three years. The electricity ceiling is branch-specific and applied as such, which matters because the spread is wide:

PostElectricity ceilingof which under 3 years
Steel11.4%68%
Metals and machinery15.5%73%
Paper and board19.3%47%
Other industries23.6%66%
Minerals, cement24.1%40%
Food industry25.0%60%
Chemistry, ammonia, olefins31.1%38%

The lever says how much of that identified potential is captured, not how much exists. At 100% every branch reaches its own ceiling and no further; at about 58% the scenario is taking roughly the part that pays back in under three years, which is the honest "no-regrets" anchor to argue from in class.

Efficiency also destroys waste heat

Fuel that is never burned rejects no heat. So the efficiency effort shrinks the waste-heat gisement exactly as electrification does — in the reference scenario, from 10.7 TWh to 8.6 at full effort. Efficiency, electrification and waste-heat recovery all draw on the same combustion, and the model makes them compete rather than letting a scenario bank all three.

What is not represented

Only direct electricity carries the electricity ceiling: the electricity that goes into hydrogen and e-fuel is governed by conversion efficiencies declared elsewhere. The study gives no branch breakdown on the fuel side, so one ceiling applies across industry. The whole ceiling is a French measurement applied to German fuel, which is defensible only because it is expressed as a fraction; a German industry review should replace it with the Fraunhofer ISI branch potentials. Transport and buildings are untouched, their own levers already carrying demand and equipment efficiency. And nothing here costs the investment that buys the efficiency — the cost layer prices energy and plant, not retrofit of motors and heat exchangers.

Every input, with its provenance

This annex is generated from the model specification itself — model/technology.yaml, model/countries/DE/DE.yaml and model/equations.yaml — so what is documented here and what the engine executes are the same thing. The model has 121 levers, 233 constants, 25 data tables and 591 equations.

Published external statistic or study, cited · Workbook inherited from the teaching workbook, not independently re-sourced · Calibrated fitted so the module reproduces a reference baseline · Provisional plausible and widely quoted, but no primary publication secured · Game rule chosen by the teaching team to make the game work · Derived computed from other declared values, not an input in its own right

Levers — what the player can move

LeverDefaultRangeProvenanceWhy, and where it comes from
Fuel car
carFuel
10%0 … 100Game rule

Share of 2020 private-car demand still served by a liquid-fuelled car in 2050. The four car shares are rebalanced to 100% as the player moves them.

Biogas car
carGas
10%0 … 100Provisional

PLACEHOLDER — French value carried, not German data: 10% is the French teaching workbook's horizon share for gas-fuelled cars. Germany's compressed-natural-gas fleet is small and shrinking — the tax advantage runs out in 2026 — so the German figure is probably lower, not higher. It cannot be moved from here alone. The four car shares must sum to 100% at their defaults and only this one is national, so changing it needs carFuel, carElectric and carRail marked national as well, and the simpleElectricCars coarse control re-pointed with them. What would close it: a German 2045 passenger-car scenario with a fuel split — the UBA RESCUE or the Langfristszenarien.

  • countries/FR/FR.yaml, carGas — carried unchanged — Not a German source. See NOTES.md under Placeholders.
Electric car
carElectric
70%0 … 100Game rule—
Shift to short-distance rail
carRail
10%0 … 100Game rule

Car demand transferred to short-distance rail, at the occupancy and unit consumption of the rail row rather than the car row.

Passenger mobility reduction
passengerReduction
0%0 … 45Game rule—
Domestic aviation → rail
domesticAviationRail
50%0 … 100Game rule—
Hydrogen truck
truckH2
20%0 … 100Game rule—
Residual thermal
truckThermal
10%0 … 100Game rule—
Electric truck
truckElectric
40%0 … 100Game rule—
Shift to rail freight
truckRail
30%0 … 100Game rule—
Freight-demand reduction
freightReduction
0%0 … 45Game rule—
Air freight → maritime
freightAviationSea
20%0 … 100Game rule—
Biofuel share
biofuelShare
40%0 … 100Game rule

In 2050 the model leaves no fossil liquid fuel at all: every litre is either biofuel or e-fuel made from electricity. This is a scenario assumption, and it is why liquid fuel carries a low emission factor.

Heat covered by electricity
bldgElectricShare
49%0 … 100Game rule

The headline decarbonisation choice for buildings, and the one that drives the winter peak. It is a share of heat need, not of energy: how that heat is produced is the next question down.

Biomass for heating
bldgBiomassTwh
60 TWh/y0 … 150Game rule

A target in the unit the resource constraint is written in. Germany burns about 90 TWh of wood in buildings today — 69.9 TWh in dwellings and 20.4 TWh in service buildings, JRC-IDEES-2021 for 2021 — against roughly 75 TWh in France, so the German slider starts from a larger stock and runs further. The default of 60 TWh is a rule, not a measurement: it is a modest reduction on today, which is what the ENSPRESO forestry potential and the shrinking German forest sink together argue for. The maximum of 150 TWh is above the low-mobilisation German forestry potential (110 TWh in 2050) on purpose, so a player can see the scoreboard band go red rather than be prevented from crossing it.

Air-air heat pump
bldgElecAirAir
47%0 … 100Game rule

Seasonal COP 2.5, falling to 2.0 at peak.

Air-water heat pump
bldgElecAirWater
31%0 … 100Game rule

Seasonal COP 3.0, falling to 2.0 at peak.

Electric resistance
bldgElecResistance
15%0 … 100Game rule

A slider rather than a stock that can only shrink, because a scenario may genuinely install more electric convectors — they are cheap to fit and terrible for the peak. Efficiency 1 in both seasons, so this is the one electric option that buys no COP at all.

Hybrid heat pump
bldgElecHybrid
4%0 … 100Game rule—
Heat pump on a network
bldgElecDistrictHP
3%0 … 100Game rule—
Wood in heat networks
districtWoodTwh
20 TWh/y0 … 80Game rule

Wood in German heat networks. The observed level is 10.7 TWh of fuel input in 2021, derived in extract/extract_district_heat.py from the Eurostat transformation-input balances with the CHP fuel split by energy allocation. The default doubles it, which is a rule: the Wärmeplanungsgesetz requires every network to be fed from renewables or unavoidable waste heat by 2045 and does not say from which.

Recovered and waste heat
districtWasteTwh
25 TWh/y0 … 100Game rule

Recovered heat, waste incineration and geothermal in German networks. This lever matters far more in Germany than in France and its French default of 0 would be wrong: Germany already puts about 24 TWh of non-renewable and renewable municipal waste, geothermal and recovered heat into its networks, against a French network a third of the size. The default is set at that observed level; the maximum is a rule.

Average retrofit improvement
bldgRetrofit
30%0 … 65Game rule

One slider conflates retrofit depth and retrofit rate, which have very different costs. Separating them is a documented next step.

Temperature-related sufficiency
bldgSobriety
5%0 … 25Game rule—
New housing built
newHousing
Hidden
0 Mm²/y0 … 36Game rule

Not shown in this edition. This country's package hides the control; the model reads the lever at the default in the next column.

Hidden and inert: this edition carries no cement intensity per square metre, so no floor area can reach its cement. Zero rather than the observed rate, because a number that moves nothing would invite a reader to quote it.

New non-residential built
newNonResidential
Hidden
0 Mm²/y0 … 36Game rule

Not shown in this edition. This country's package hides the control; the model reads the lever at the default in the next column.

Hidden and inert, for the same reason as newHousing.

Built in timber
timberShare
Hidden
0%0 … 80Game rule

Not shown in this edition. This country's package hides the control; the model reads the lever at the default in the next column.

Hidden and inert: with no floor area reaching cement, a timber share has nothing to displace.

Roads, networks and civil works
civilWorksVolume
Hidden
100%50 … 130Game rule

Not shown in this edition. This country's package hides the control; the model reads the lever at the default in the next column.

Hidden and inert: this edition's cement is all in the residual row, which no lever drives, so there is no civil-works tonnage for this index to multiply.

H-DRI steel share
steelDRI
50%0 … 100Game rule—
Steel production change
steelGrowth
30%-40 … 50Game rule—
Ammonia production
ammoniaProduction
Hidden
2 950 kt/y0 … 4 000Provisional

Not shown in this edition. This country's package hides the control; the model reads the lever at the default in the next column.

German ammonia production in 2020, read off the UBA production line of a published Agora Industrie figure to about ±50 kt. Germany makes roughly three times France's 900 kt, at four sites: SKW Piesteritz, BASF Ludwigshafen, INEOS Köln and Yara Brunsbüttel. The maximum is raised from the French 1 400 to 4 000 kt so the slider spans a German range. One thing a German player should be told and a French one need not be: this industry is in the middle of a gas-price shock, and German output fell to about 2 Mt in 2022. Retired here since the land module arrived, and hidden. The ammonia the chain builds hydrogen for is now derived — the mineral nitrogen the German fields receive, times the share made in Germany, divided by the nitrogen fraction of ammonia, plus what the chemical industry makes for something else — so this slider moves nothing in this edition. It stays declared because the British and Spanish editions read it, and a test asserts that it is inert. The derived base-year tonnage lands on the 2 950 kt above by construction, because ammonia_non_fertiliser is the residual of it.

CO₂ + H₂ olefin route
olefinRoute
50%0 … 100Game rule—
Biogenic CO₂ share
biogenicCO2
10%0 … 50Game rule

Only the biogenic fraction of the CO₂ fed to the synthetic-olefin route counts as a removal, which is why this lever alone can turn the olefin process term negative.

Plastic-demand reduction
plasticReduction
30%0 … 70Game rule

How much less plastic the country asks for, against the base year — a demand reduction and not a recycling rate. It scales the olefin tonnage the crackers make and, since 0.28.0, the plastic the country's incinerators burn — which is where most of its effect now lies, and why it finally lowers emissions rather than raising them. It is the one lever in this chain that answers "how much of this do we need" rather than "how do we make it". The two French reference scenarios cannot anchor it. ADEME's Transition(s) 2050 publishes material-demand trajectories for steel, aluminium, cement and glass and none for plastics; its plastics content is an 80% recycling rate, and négaWatt does the same. Both express plastics as a rate of recycling, which since 0.33.0 is read on plasticRecycling, not here. What can is SYSTEMIQ's ReShaping Plastics, the one published pathway that separates the wedges. European plastic demand grows in its baseline, 37 to 48 Mt by 2050; its Circularity scenario takes 25% off that baseline by reducing demand and 4% more by substituting materials. Against 2050 that is 29%; against today it is under 10%, because a quarter of a growing baseline is a tenth of the present. This slider is written against the base year, so the two readings are the two ends of what one study supports — and the reference, 30%, sits at the far edge of the more generous one. The sectors move in opposite directions underneath: packaging can lose 38% (an eighth eliminated, a further three tenths reused), vehicles 22%, while construction plastic grows by half in every scenario published. A single national share hides that, and a player moving this slider is assuming the packaging wedge does all the work.

  • SYSTEMIQ (2022), ReShaping Plastics: Pathways to a Circular, Climate Neutral Plastics System in Europe, for Plastics Europe — EU27+UK, baseline 37→48 Mt by 2050; Circularity scenario 25% reduce + 4% substitute
  • ADEME, Transition(s) 2050 — material-demand trajectories for steel, aluminium, cement and glass; plastics carried as a recycling rate
  • See docs/waste/olefins_and_plastic_demand.md for the legal instruments (PPWR, SUP, loi AGEC, décret 3R) and why they do not bound this slider
Plastic kept out of the incinerators by recycling
plasticRecycling
0%0 … 75Game rule

The share of the plastic that reaches the incinerators in the base year which is sorted out and recycled instead. It is how the French reference scenarios express plastics: ADEME's Transition(s) 2050 and négaWatt both carry an 80% recycling rate, against 20% for all French plastic waste in 2022. If what is not recycled is burned, going from 20% to 80% leaves a quarter of today's burned plastic, which is 75 on this slider; the default, 0, is today's rate. Applied after plasticReduction: plastic not consumed is not there to recycle. Each tonne recycled costs 0.5 MWh of electricity, the middle of the 0.3–0.7 the JRC gives for mechanical recycling, booked on the waste-to-energy post because the model has no post for sorting and recycling. Three things it does not do. The recycled polymer does not displace any virgin olefin: the territorial inventory credits nothing unless French crackers actually make less, and the JRC discounts most recycled polymers to 0.6 of a virgin tonne. Sorting losses are not modelled — a recycling line rejects part of what it receives, and that refuse is burned or landfilled. And the plastic still in the residual bin is the hardest to recover: films, soiled and multilayer packaging, and the plastic in textiles and nappies.

  • SDES (September 2025), Bilan 2022 de la production de déchets en France, p. 4 — plastics recycling rate 20%
  • ADEME, Transition(s) 2050 — plastics carried as an 80% recycling rate
  • JRC (2023), Environmental and economic assessment of plastic waste recycling, EUR 31423, p. 54 — mechanical recycling 0.3–0.7 MWh of electricity a tonne; pp. 29–30, substitution factors (PP 0.6, HIPS 0.65, food-grade PET 1)
  • See docs/waste/plastics_and_incineration.md, §2.2
Capture on incinerators
wteCapture
0%0 … 90Game rule

The share of an incinerator's stack CO₂ that is captured and stored. A capture plant does not sort the molecules, so it takes the fossil and the biogenic CO₂ together — and about 60% of what leaves a French incinerator is biogenic. Capturing on an incinerator is therefore mostly bioenergy with carbon capture, which is the point worth teaching. Only the fossil part lowers the national total here. The biogenic part is shown and not counted: a captured biogenic tonne is a removal, and removals are what techSink already stands for — counting them here as well would book the same tonne twice. The hydrogen route does count its biogenic capture as negative, and the controversy table says why that is contested. 90% is the top because it is what the plants being built claim: 85% in the techno-economic literature, 87% at Oslo's Klemetsrud, 90% announced at Le Mans. Since 0.32.0 the capture is powered and paid for: 0.315 MWh of electricity a tonne captured, fossil or biogenic, which the mix has to produce, and 100 € a tonne for the plant plus 50 for transport and storage, in the cost tab. The biogenic tonnes are paid for and not counted, which is why a fossil tonne avoided here costs two and a half times a tonne captured.

Heat pumps for steam
foodHPSteam
60%0 … 100Game rule—
Heat pumps for direct heat
foodHPDirect
25%0 … 100Game rule—
Food-industry efficiency
foodEfficiency
20%0 … 50Game rule—
Less cement per unit of works
cementReduction
10%0 … 60Game rule

Renamed in v0.20, because it finally has a driver. Until then it was "cement-demand reduction" with no why, no help and nothing behind it: a scenario could take 60% off the country's cement without saying which building it had not built, and the annex could not say what the slider meant. How much is built is now the construction module's business. What is left here is the intensity of the works: leaner mixes, thinner slabs and post-tensioned structures, a design that uses the concrete it pours. It is not clinkerRate, which replaces clinker inside the cement with slag or fly ash; this one asks for less cement in the first place. The two multiply, and a scenario that pushes both is asking for a lot from the same building twice over. The range is a rule. The published levers for the sector are the clinker ratio and capture, and nobody has assessed how far structural design alone can go — so 60% is a bound on an argument rather than on an assessment.

Clinker ratio
clinkerRate
73%35 … 78Published

Germany's observed clinker-to-cement ratio: 25 069 kt of clinker for 34 185 kt of cement in 2019 gives 0.733. The 2021 pair — 25 736 kt for 35 000 kt — gives 0.735, so the figure is stable. The French default of 60 % is a scenario choice; putting Germany's default at its own observed ratio means the German reference scenario starts where German kilns actually are, and the whole range of the lever is then the reduction on offer. The maximum of 78 % is not changed: German practice already sits just under it.

CO₂ capture
carbonCapture
20%0 … 95Game rule

The share of a cement kiln's fossil stack that is captured: the decarbonation of the limestone and, since 0.29.0, the fossil part of the kiln fuel, because a capture plant on a cement stack does not sort the molecules. The biogenic CO₂ of the waste the kiln burns goes up the same stack and would be captured too; it is not credited, for the reason wteCapture gives. Until 0.27.0 the term this lever multiplied carried the kiln fuel under the name of calcination, and the same fuel was also charged through the energy account — emitted twice, captured once. In 0.27.0 it captured the calcination alone and was a floor; now it is the whole fossil stack. Since 0.32.0 it is powered and paid for: 0.54 MWh of electricity a tonne of clinker at 95%, which the mix has to produce, the capture plant's capital in the cost of clinker, and 50 € a tonne for transport and storage on everything it stores, biogenic included.

Waste-derived fuel in cement kilns
kilnAltFuel
85%0 … 95Published

The share of a kiln's heat that comes from waste rather than from petroleum coke and coal. French kilns were at 38% in 2015, 44% in 2021 and 52% in 2023, burning over a million tonnes of waste a year; the sector's roadmap takes it to 80% in 2030 and 85% in 2050, the default. About half of that waste is biomass, so the lever cuts the kiln's fossil CO₂ roughly half as fast as it moves: at 0% the whole heat is fossil, at 85% still 56% of it is. It does not take waste from the incinerators, and since 0.33.0 that is a finding rather than a gap. The refuse-derived fuel French kilns burn is made from the refuse of sorting lines — commercial waste, separate collection, bulky waste — and French policy keeps residual household waste out of it. Its alternative is landfill, not the incinerators, which are full and turned away half a million tonnes in 2022. The two would compete for the same tonne only once landfill is close to zero.

Output of the rest of industry
otherIndustryVolume
Hidden
0%0 … 100Published

Not shown in this edition. This country's package hides the control; the model reads the lever at the default in the next column.

How much the branches the game does not model produce, between today's output and the source workbook's 2050 scenario. That scenario is a reindustrialisation: measured branch by branch it multiplies textile output by 8.5, electronics by 3.1, mineral extraction by 2.5, while mineral chemistry falls to 0.52 and naval and aerospace to 0.56. Growth of that size is not decarbonisation, and separating it from the process lever is the whole point — otherwise a player could appear to clean up industry while assuming an eightfold textile sector.

Less output from the rest of industry
otherIndustrySobriety
0%0 … 40Provisional

Less of everything the rest of industry makes, branch by branch in the same proportion — metals, minerals, chemistry, paper and the rest — with its fuel, its electricity and its process emissions going down together. Added in 0.30 after students found that the rest of industry could only grow: otherIndustryVolume runs from today's output towards a reindustrialisation, and nothing ran the other way, although these branches carry two thirds of the methane a scenario cannot otherwise get rid of. The top of the range is the one French pathway that contracts industry: ADEME's Génération frugale cuts industrial production by 38% by 2050, because people buy fewer, longer-lived goods. Provisional, because that figure is read from summaries of the study rather than from its industry chapter. And one thing this lever cannot tell apart: a scenario in which France buys less, and one in which France makes less and imports the rest. The territorial account cannot tell them apart either; the first is sufficiency, the second is leakage.

  • ADEME (2021), Transition(s) 2050, scenario S1 Génération frugale — industrial production −38% by 2050, as reported in summaries of the study
Processes of the rest of industry
otherIndustryProcess
100%0 … 100Published

How much energy each unit of output takes, between today's processes and the 2050 ones. This is where electrification lives: at constant output it takes the electricity of these branches from 68 to 138 TWh while cutting coal and fuel oil to zero. The default is 100% and the volume default is 0%, so the reference scenario reads "the rest of industry modernises at today's output" — the neutral reading, with growth added explicitly.

  • Offre_et_demande.xlsx, branch sheets E18–E38 — unit consumption in MWh per tonne, 2019 and 2050
Waste-heat recovery
wasteHeatRecovery
0%0 … 100Published

Heat rejected by industrial processes and recovered instead of vented. ADEME puts the recoverable gisement at 15.6 TWh on the 2019 industry, of which 7.7 TWh above 100 °C, and — this is what makes it a real constraint — expresses it against the fuel each sector burns. So the gisement is not a fixed reserve: it shrinks as processes electrify, because there is no combustion left to reject heat from. Recovering waste heat and electrifying heat compete for the same physics, and the model makes them compete.

Energy-efficiency effort
industryEfficiency
0% of the identified potential0 … 100Published

Cross-cutting energy efficiency — motors, drives, compressed air, insulation, heat integration. RTE, after CEREN, identifies a potential of 21.1% on industrial electricity and 19.8% on fuels, of which about 58% pays back in under three years. The ceiling is branch-specific and applied as such: 11.4% for steel, 15.5% for metals and machinery, 19.3% for paper, 24.1% for minerals, 25.0% for the food industry, 31.1% for chemistry. This lever says how much of that identified potential is actually captured, not how much exists — so it cannot invent efficiency beyond what the study found, which is the point of a ceiling.

Methane (biogas), 2050
efGas
175 gCO₂/kWh0 … 250Provisional

The single most consequential German departure from the French file, and it is a decision rather than a lookup. France declares 25 gCO₂/kWh, which encodes "all 2050 methane is biomethane". In Germany that assumption is indefensible as a default: German gas demand is around 864 TWh today, German biomethane production was 12.3 TWh in 2025 plus 1.5 TWh imported — about 1.6 % — and dena puts the exploitable domestic potential from waste and residues above 50 TWh against a 2045 demand case of 200 TWh. Taking dena's own two numbers, the biogenic share of German 2045 methane is about 50/200 = 25 %, and 0.25 × 25 + 0.75 × 227 = 176 gCO₂/kWh, rounded onto the slider's step at 175. A player who thinks Germany will import synthetic or biogenic methane instead can move the slider down; that is the argument the lever exists to have, and starting it at the French 25 would settle it silently.

Liquid fuel (bio and e-fuel), 2050
efLiquid
25 gCO₂/kWh0 … 300Provisional

PLACEHOLDER — French value carried, not German data: 25 gCO₂/kWh is the French assumption that horizon-year liquid fuel is biofuel or e-fuel. No German life-cycle factor for a 2045 liquid-fuel mix was secured. What would close it: the UBA/DBFZ life-cycle factors behind the German THG-Quote (38. BImSchV), which publish a per-pathway factor for every biofuel and e-fuel route, weighted by the pathway mix a German 2045 scenario assumes. Unlike efGas, this one is not obviously wrong for Germany — German liquid demand in 2045 is small in every published pathway — but it is not German either.

  • countries/FR/FR.yaml, efLiquid — carried unchanged — Not a German source. Listed in NOTES.md under Placeholders.
Wood, 2050
efWood
27 gCO₂/kWh0 … 60Provisional

PLACEHOLDER — French value carried, not German data: 27 gCO₂/kWh is the fossil energy of the French wood chain. It is not a biogenic zero and it is not transferable without checking: Germany imports a larger share of its pellets, and haulage is most of this factor. What would close it: the UBA ProBas life-cycle database entries for Holzpellets and Scheitholz, or the DEPV's own chain analysis.

  • countries/FR/FR.yaml, efWood — carried unchanged — Not a German source. Listed in NOTES.md under Placeholders.
Aviation efficiency gain
aviationEfficiency
0%/y0 … 2Published

Kerosene per passenger-kilometre, improving each year through aircraft renewal, seat density and load factor. Published trajectories converge tightly on 1%/year: ICAO 1.0, ADEME 1.0, T&E 0.9, the UK Committee on Climate Change 0.9, the World Economic Forum's Clean Skies for Tomorrow 1.0, against 2.5 in the more optimistic ICSA figure. The default is 0 because the source workbook uses today's consumption for 2050 — moving the slider to 1 shows what a quarter-century of fleet renewal is worth, and it is worth less than most people expect.

Air-traffic growth
aviationDemandGrowth
0%/y-1.5 … 3.5Published

Passenger-kilometres, compounded over thirty years. The source workbook carries 2020 demand straight through to 2050, which is a growth assumption of zero and a very strong one — no published trajectory says that. For flights departing France the DGAC roadmap gives 1.62%/year falling to 1.19, or 1.8 without a price effect and 0.8 with one; ADEME spans −1.3 to +3.0 depending on scenario and price effect; Eurocontrol gives 3.3 then 1.7. World figures are higher still: ICAO 1.1 to 3.4, Airbus 2.6, Boeing 5.6 falling to 2.5. At 1.5%/year over thirty years traffic grows by 56%, which is worth more than every efficiency gain in the sector combined.

Bio-jet fuel
safBioPrice
2 000 €/t600 … 4 000Published

Sustainable aviation fuel from biomass. The published estimates disagree by a factor of six, and which route is assumed matters as much as who estimated it: HEFA from waste oils 600–1 900 €/t, biomass-to-liquid 1 400–2 900, alcohol-to-jet 750–3 900. The default sits mid-range across the three. The width of that range is the honest answer, which is why this is a slider and the range is printed beside it.

E-jet fuel (power-to-liquid)
safEfuelPrice
5 000 €/t1 500 … 10 000Published

Synthetic kerosene from electrolytic hydrogen and captured CO₂. Estimates range from 1 820 €/t (European Commission) to 10 000 (DGAC), with the review's central band at 3 700–6 200. Direct air capture costs more than biogenic CO₂: EASA gives 7 300–8 700 €/t for atmospheric CO₂ against 6 600–7 975 for biogenic.

Fuel share of airline operating cost
fuelShareOperating
30%15 … 40Published

Everything that is not fuel — aircraft, crew, airport charges, maintenance, overheads — is assumed unchanged in 2050 and is derived from today's ticket through this share. It is the weakest link in the ticket calculation: a 2050 airline may well have a different cost structure, and nothing here models that.

Agriculture pathway position
agriPathway
Hidden
100%0 … 100Game rule

Not shown in this edition. This country's package hides the control; the model reads the lever at the default in the next column.

Position on the German agriculture pathway: 0 keeps the 2024 inventory value of 60.85 MtCO₂e, 100 reaches the UBA 2026 projection for 2045. Read it as an assumption about the rest of the economy, not as a result — and note that for Germany the endpoint is a projection with existing measures, not a target, because the Klimaschutzgesetz has had no sector targets since the 2024 amendment.

Waste pathway position
wastePathway
100%0 … 100Game rule

Same convention: 0 keeps the 2024 value of 5.28 MtCO₂e, 100 reaches the 2045 projection. Germany's waste sector has already fallen by 87 % since 1990 — the 2005 ban on landfilling untreated organic waste is the single most effective instrument in the German inventory — so this pathway moves very little either way.

Natural carbon sink
naturalSink
Hidden
0 MtCO₂e/y absorbed-60 … 40Game rule

Not shown in this edition. This country's package hides the control; the model reads the lever at the default in the next column.

The German land account is a net source, and the slider has to run through zero. The lever is a signed magnitude of absorption: positive absorbs, negative emits. German LULUCF was +36.5 MtCO₂e in 1990, +57.8 in 2024 and +26.9 in the 2025 proxy — a net source in every year of the series, which is what the negative minimum is for. The bounds are the German argument in one line. −60 is worse than any year yet observed and is where a continued forest die-back leads; +40 is exactly what KSG §3a requires by 2045, as a four-year average. The default of 0 is a rule and it is a deliberately modest one: it says the German land account stops emitting and absorbs nothing. The UBA's own 2026 projection with existing measures lands at +26 MtCO₂e of emissions in 2045 — a lever position of −26 — which is 66 MtCO₂e away from the law. Retired here since the land module arrived, and hidden. The German natural sink is now computed — seven land classes, six inventory pools, a forest identity in cubic metres and 1.95 Mha of drained organic soil — so this slider moves nothing in this edition. It stays declared because land_module_active reads it and because the British and Spanish editions still use it as their whole land-use model, and a test asserts that it is inert. Everything above is what it said while it was the model.

Technological carbon sink
techSink
6 MtCO₂e/y absorbed0 … 60Published

Germany has no statutory removal volume, so there is no closure residual to compute the way France's -43 MtCO₂e is computed. What exists is a projection: the UBA's 2026 Projektionsbericht has 0.7 MtCO₂e captured in 2030, 4.7 in 2040 and 6.2 in 2045 under existing measures, which is where the default of 6 comes from. The minimum is 0 rather than France's 5, because a German pathway with no engineered removal at all is the current legal position, not an extreme.

Flagged above 20 MtCO₂e/y absorbed. Twenty megatonnes a year, for Germany alone, is around half of everything the planet currently captures and stores, across every facility in operation. The UBA's own projection reaches 6.2 by 2045, and the CO₂ storage law that would allow the rest onshore was only reopened in 2025. Nothing in this model builds the plant, supplies the electricity the capture consumes, or pays for either.

Land taken for building
artificialisationRate
11 kha/y0 … 30Published

The default is the federal target, not the observed rate. The Deutsche Nachhaltigkeitsstrategie sets land take below 30 hectares a day by 2030 and a Flächenkreislaufwirtschaft — net zero — by 2050; 30 ha/day is 10.95 kha a year, which rounds to the slider's 11. What Germany actually did in 2024 is 19.2 kha, or 50 ha a day (34 for settlement, 17 for transport, less 1 given back), down from 53 in 2023 and 77 in 2010. The base-year constant carries the 19.2 and this lever carries the target, which is the same arrangement France has between its observed 52 kha/y and its ZAN trajectory. The maximum of 30 kha/y is a rule: it is roughly half again the observed rate, far enough above it for a player to make the artificial pool worse and not so far as to empty a class.

New forest planted
afforestationRate
6 kha/y0 … 30Published

The observed net rate, because Germany has no afforestation target to put here. The land survey measures Wald growing 10 688 592 → 10 694 619 ha between 2023 and 2024, +6.0 kha. The forest inventory measures the gross flows behind it over its own decade: 82 kha of new forest (8.2 kha a year, out of Dauergrünland 37, quarries and dumps 12, arable 11 and wet land 11) against 66 kha lost, a net +15 kha over ten years, or 1.5 kha a year. The two disagree by a factor of four on the net figure and the survey's is used, because the survey is the account this module is written in. The maximum of 30 kha/y is a rule and is stated as one: WEHAM holds the German forest area constant over its whole 2023–2062 projection, and UBA's own forest scenarios add set-aside rather than area, so nothing published says how much afforestation Germany could do. What would close it: a quantified target in the Aktionsprogramm Natürlicher Klimaschutz.

Grassland to crops
grasslandConversion
-4 kha/y-50 … 50Published

Germany's grassland has been growing, so the default is negative. Dauergrünland went from 4 654.7 kha in 2010 to 4 714.3 kha in 2024, +4.3 kha a year, and the reason is the EU greening rules: ploughing permanent grassland has needed authorisation since 2015 and is refused where the regional stock has fallen. In this module's sign convention — positive ploughs grass into crops — that is −4.3 kha/y, and the slider's default is −4. The bounds are a rule. Germany lost roughly a third of a million hectares of grassland between 1991 and 2010, which is where a positive maximum of +50 kha/y comes from, but that series was not fetched and is recorded as unverified. −50 is its mirror.

Store carbon in the soil
soilCarbonPractices
0%0 … 100Game rule

The default is zero because Germany has no soil-carbon target, and the potential behind the slider is the weakest number in this block. The soil inventory of German farmland finds no significant change of topsoil carbon under unchanged management and a loss on dry arable sites, and no German equivalent of the study that sizes the French potential was read. The two potentials this lever is a share of are therefore the French ones per hectare, applied to the German arable and grassland areas, and they are declared provisional with that said in full. A player who moves this slider is moving a French coefficient, and the annex says so.

Wood harvested
forestHarvest
76 Mm³/y40 … 88Published

Declared in the unit the German statistic publishes — Erntefestmeter ohne Rinde — and converted to standing-stock volume inside the identity by forest_harvest_volume_factor = 1.25. This is the one place the German package needed an equation the French one did not: the Bundeswaldinventur measures increment and mortality in Vorratsfestmeter Derbholz mit Rinde, and the Holzeinschlagsstatistik reports the harvest in Efm o.R., and the two differ by a quarter. Reading the lever in Efm keeps it comparable with what Germany publishes and keeps the 2.14 MWh per cubic metre of the wood supply on the right unit. The default of 76 is the base year rounded to the slider's step: Destatis counted 61.183 Mm³ in 2024, and Thünen's own back-calculation finds the official statistic captures about 81 % of the real harvest, so 75.6 Mm³ is what left the forest. The maximum of 88 is WEHAM's roundwood potential at the start of its 2023–2062 projection; the minimum of 40 is a rule.

Wood into long-lived products
harvestToProducts
44%30 … 55Published

Sawlogs over the whole harvest: 33.253 of 75.6 Mm³, 44.0 %. On the official harvest alone it reads 54.3 %, and the two are quoted for different arguments — the informal firewood is a third of the difference between them. Germany's share is twice France's because the German forest is half spruce and pine and the German sawmilling industry is three times the size. The bounds are a rule around it: 30 % is roughly the share at the bottom of the calamity years, when everything went to the chipper, and 55 % is a little above the share of the official harvest, which is as far as a strategy could push it without changing the species mix.

Drained peatland rewetted
peatRewetting
0%0 … 100Game rule

The largest lever on German land, and its default is zero because no German target for it could be verified. 1.945 Mha of drained organic soil emit about 52 MtCO₂e a year — 8 % of the national total, and more than the whole German cement, steel and chemical industry's process emissions together. Rewetting is the measure every German LULUCF scenario turns on, and this slider is the share of that area put back under water by 2045. Zero is a deliberate reading of the evidence rather than a placeholder: the Nationale Moorschutzstrategie's PDF is a dead link, the Aktionsprogramm Natürlicher Klimaschutz's rewetting volume is quoted only in secondary pages, and the UBA's own 2026 projection says the 2030 LULUCF target "ist nicht mehr erreichbar" and that 2040 and 2045 are missed with current measures. A reference that rewetted nothing is what current measures describe. A player who moves this slider to 100 finds about 44 MtCO₂e a year, which is what the argument is about. The step of 5 % is 97 kha of rewetting per notch, which is the right order of magnitude for a programme: German rewetting has run at a few thousand hectares a year.

Climate effect on the forest
forestClimate
11 … 3Provisional

Germany has no published climate grid for its forest, so this one is assembled from three sources and declared provisional. France reads the IGN–FCBA's own C1/C2/C3; nothing equivalent exists here. Position 1 is WEHAM's base scenario, the only official projection, which holds the area constant and the stock near 3.6 Gm³. Position 2 continues what the last inventory decade measured: gross increment fell 16 % between the 2002–2012 and the 2012–2022 periods and mortality rose by half. Position 3 is bounded by the source case of the Projektionsbericht forest modelling, which puts 2045 living biomass anywhere between −31.8 and +10.6 MtCO₂e. The default is 1 and that is the optimistic end, deliberately. A reference should stand on the country's own official projection, and WEHAM is the only one Germany has; at position 1 the land account lands at a source of 56 MtCO₂e in 2045 against 58 observed in 2024, which is what "with existing measures" ought to look like. What was actually measured is position 2 — the German forest was a net carbon source over 2017–2022, losing 41.5 Mt of carbon from its living trees — and one click to the right costs 26 MtCO₂e a year. A player should make that click. France's default is its central case rather than its official one, because the French official projection is itself a climate grid; Germany's is not.

Red meat eaten
dietRedMeat
48 kgec/cap/y15 … 55Published

The 2024 supply balance, rounded to the slider's step: pork 35.5, beef and veal 11.8, sheep and goat 0.70 kilograms of carcass weight a head, 48.1 in all. Carcass weight is Verbrauch and not Verzehr: what reaches a German plate is 38.2 kg, and the difference is bone, fat and the losses the food-waste lever moves separately. The bounds are the published scenario range. The Oeko-Institut's Klimaschutzszenarien for the federal economics ministry cut meat 30 % by 2045, which is 34 kg; the dietary society's own rule of thumb — meat and sausage, "weniger ist mehr", widely quoted as 300 g a week — is about 21 kg of edible weight and lands near the slider's minimum of 15 on a carcass basis. 55 is a little above today, because a scenario is allowed to go the other way.

Poultry eaten
dietPoultry
21 kgec/cap/y10 … 25Published

20.9 kg of carcass weight a head in 2024, 13.7 as edible weight. Germany is the one large European producer whose poultry self-sufficiency is below one — 98 % — so a diet that shifts from red meat to poultry buys part of its chicken abroad, which the import share of the animal_product table carries. Bounds as for red meat: the scenario range, widened a little upwards.

Dairy eaten
dietDairy
100%50 … 110Published

An index rather than a quantity, because milk equivalents are published on several incompatible bases. 100 % is 2024: 33.8 Mt of cow milk produced, 46.1 kg of drinking milk, about 26 kg of cheese, 5.6 kg of butter and 6.4 kg of dried products a head. The minimum of 50 is below the Klimaschutzszenarien's own −40 % on milk by 2045, so the published scenario is inside the slider rather than at its end.

  • BLE, Bericht Milch 2026 — Cow-milk production 34.0 Mt in 2025 and 33.8 Mt in 2024; 93.1 % delivered to dairies. Per head 2024: drinking milk 46.1 kg, butter 5.6, dried 6.4, fresh milk products 79.1.
Cut edible food waste
foodWaste
0%0 … 50Game rule

Zero is today, because the German target is a halving by 2030 that the country is not on track for and the reference is what existing measures deliver. Germany threw away 10.8 Mt of food along the whole chain in 2022 and 10.9 Mt in 2023; households are 58 % of it, 74.5 kg a head, down from 78 kg in 2020. The maximum of 50 % is the UN target Germany signed, applied to the edible share the module carries.

Livestock exports
livestockExport
100%0 … 150Published

An index on the base-year volumes, held at 100 because no German scenario publishes a 2045 trade position. It matters more here than in France: German pork self-sufficiency is 135 %, all meat 119 %, and the export volume is what keeps the herd from falling with the diet. The Thuenen-Baseline projects meat production −11 % and milk deliveries +3 % by 2034 with the trade position roughly held, which is inside this slider rather than at its end.

Crop exports
cropExport
100%0 … 150Game rule

Held at the base year for the same reason as the livestock export: nothing published gives a German 2045 crop trade position. Germany is a net importer of grain in most years and a net exporter in good ones, which is why the export share of the arable area is smaller here than in France. The bounds are the French rule, 0 to 150 % of the base-year volume.

Mineral nitrogen
nIntensity
100%40 … 110Game rule

Held at the base year, and that is a statement rather than a default. Germany has no published 2045 nitrogen figure the way France has the SNBC 3's −54 %: the Duengeverordnung caps application against crop need and tightens it in nitrate-vulnerable areas, and the deliveries have already fallen — 1.03 Mt N in 2023/24 against 1.14 in 2024/25, 67.8 kg N a hectare of farmland — but no target says where they land. The German reference therefore cuts nitrogen only through the organic share, which is the one national number there is, and the fall in the herd. Since stage E this lever is the dose on the hectares that stay conventional: with organicShare at the Bio-Strategie's 30 % the reference delivers about 74 % of the 2023 nitrogen, and the two effects are counted once rather than twice.

Legumes in the rotation
legumeArea
0.7 Mha0.5 … 2Published

The observed area rounded to the slider's step: 285.0 kha of pulses and 387.4 kha of forage legumes in 2024, 672 kha in all, and rising — 326 and 401 kha in 2026. The maximum of 2.0 Mha is a rule at three times today, the same multiple the French slider carries, and it is well inside the German arable area. The nitrogen credit this lever earns is the weakest coefficient in the German food block: no German study of the mineral nitrogen a legume rotation replaces was read, so legume_n_credit and legume_credit_span carry the French pair on the German area and say so.

Organic farming
organicShare
30%0 … 50Published

The one German agricultural target with a number on it, and the module makes it harder than it is. The Bio-Strategie 2030 sets 30 % of farmland organic by 2030. This lever is the organic share of the arable area, and organic farming in Germany is over-represented on grassland — 994 042 ha of organic grassland against 866 249 ha of organic arable in 2026, so 11.3 % of arable plus grassland but only 7.4 % of arable land. Reading the target as 30 % of arable land is therefore a more demanding scenario than the strategy asks for, and it is the reading the module uses because both effects it carries — no mineral nitrogen, a yield gap — live on arable land. That choice is what puts the German reference short of arable land, which the Land and food tab reports and does not clamp.

Cattle on low-methane rations
entericMitigation
0%0 … 100Game rule

Zero, because nothing in the German inventory or in German policy books a feed additive. The Klimaschutzszenarien assume an additive reaching half the cattle herd by 2045, which is where the middle of this slider sits, and the effect per animal it earns — enteric_lipid_effect — is carried as a provisional 0.2 with no German measurement behind it. A player who moves this slider is betting on a technology, and the annex says so.

Manure to digesters
manureMethanised
53%0 … 80Published

The default is today's level, not zero, and that is a departure from the French edition worth stating. Germany already digests 8.1 of the 15.3 Mt of technically collectable manure dry matter — 53 % on the energy basis the biogas equation reads. Setting the slider at 0 the way France does would have made the German reference produce 15 TWh less manure biogas than Germany produces today, which is a sixth of the biogas band. The cost of that choice is booked openly: the module applies methanisation_abatement to a base year that is already net of today's digestion, so the reference under-books manure methane by about 1.2 MtCO2e, 2 % of the sector. The fix is an equation change — the abatement should act on the digestion added to the base year — and it would move France, so it is recorded in NOTES.md rather than made here.

Get fossil fuel off the farm
agriFuelSwitch
0%0 … 100Game rule

Zero, because the UBA projection with existing measures does not take fossil fuel off the German farm and this reference is that projection. The KSG's own 2045 target — net greenhouse-gas neutrality — requires the whole 7.5 MtCO2e to go, and that is the far end of this slider rather than its default. The gap between the two is one of the reasons the German reference is amber on the agriculture band.

Nitrogen made at home
ammoniaDomesticShare
50%0 … 100Provisional

A labelled placeholder. The share of German mineral nitrogen made in Germany is not published in the sources this port read. The fertiliser industry association says German supply has relied heavily on imports since the 2022 gas-price shock without giving a tonnage, and German ammonia output itself fell to about 2 Mt in that year from 2.95 Mt in 2020. Half is a reading of those two statements and nothing more. It is not inert: the tonnage it produces is what the industry chain builds hydrogen for, so a reviewer should treat the German ammonia electricity and hydrogen figures as carrying this uncertainty. What would close it: the Destatis production statistics for GP 20151030 and the IVA import shares by nutrient.

Winter energy cover crops
civeArea
0.05 Mha0 … 1Published

Germany grows 2.15 Mha of cover crops and cuts only 53 kha of them for a digester — 39.9 kha of winter and 13.4 kha of summer catch crops in 2022/23. The German digester runs on a main crop instead, which is energyMaizeArea, so this lever starts almost from nothing and the head room above it is large: the spring-crop area that could carry a cover crop at all is about 4 Mha. The maximum of 1.0 Mha is a rule at a fifth of that ceiling, which is as far as a scenario could plausibly push a practice that today reaches 2.5 % of the cover crops there are.

Crop residues taken off the field
residueMobilisation
0%0 … 45Published

Germany takes almost no straw off the field for energy: of 9.66 Mt of dry matter technically available, 5.23 Mt is already used — 5.18 of it for bedding — and 0.05 Mt goes to energy, which is 0.5 % and rounds to the slider's zero. The maximum of 45 % is the mobilisable pool the biomass monitor identifies, 4.42 Mt, over the technical pool. The pool is a technical potential, not the whole straw production, which is the perimeter difference to know before comparing the German residue_dm_yield of 0.83 t/ha with the French 3.30: the French figure is everything the field produces and the German one is what could be carried away after what the soil needs is left on it.

Land growing fuel
energyCropArea
0.82 Mha0 … 1.5Published

583 kha of rapeseed for biodiesel and vegetable oil, and 231 kha of ethanol crops — wheat 113, rye 49, maize 31, sugar beet 11 — 814 kha in all, rounded to the slider's step. The maximum of 1.5 Mha is a rule at not quite twice today; it competes for the same arable hectares as the energy maize and the legumes, and the competition is reported rather than clamped.

Land growing methane
energyMaizeArea
1.35 Mha0 … 1.6Published

The German lever the French module had no place for. 1.35 Mha of arable land grow a main crop for a digester: silage maize 896 kha, grass and cereal silage 361 kha, grain 78 kha, sugar beet 29 kha and Silphie 10 kha. That is 11.6 % of the German arable area, and it is 2.05 Mha of silage maize in all if the feed maize is counted with it. A cover crop shares its hectare with the spring crop that follows and this one does not, so it enters arable_needed and competes with the plates — which is the whole reason it could not be folded into civeArea. The maximum of 1.6 Mha is a rule, at the same ratio to today the note's maize-only figures carry. Pushing it there is a real scenario and a contested one: the EEG caps maize at 30 % of the feedstock of a new plant, and the arable head room this module reports is what a player sees when they try.

Imported biofuel allowed
bioImports
16 TWh/y0 … 40Derived

The base-year net import, rounded: Germany burned 31.9 TWh of liquid biofuel in 2024 and its own crops and bins made about 15.9 of it, so 16 TWh came from abroad on a net basis. The gross flows are much larger and run both ways — the quota year's own feedstock accounting puts 81 % of the feedstock and two thirds of the fuel outside Germany, because German rapeseed biodiesel is exported while imported used cooking oil is burned here — and the module carries the net, which is what a supply band should score. The maximum of 40 TWh is a rule at two and a half times today.

Hot-water efficiency
usageDhwEfficiency
0%0 … 40Game rule—
Cooking efficiency
usageCookingEfficiency
0%0 … 40Game rule—
Hot water on electricity
usageDhwElectric
31%0 … 100Provisional

A share of the hot-water service, not of the energy. Germany uses 19.84 TWh of electricity for water heating — 14.97 in dwellings (Eurostat, 2023) and 4.87 in service buildings (JRC-IDEES-2021, 2021) — against 102.17 TWh of gas, oil, wood and district heat. Through the model's own efficiencies, 19.84 × 2.0 / (19.84 × 2.0 + 102.17 × 0.85) = 31 % of the service. France's default is 68 %. Hot water is the German building sector's quietest large gas use. Why provisional: the fuel term includes district heat, which is divided by a boiler efficiency it does not have, and the residential and tertiary halves come from two sources and two years. Both conventions are the French file's, so the two defaults are at least comparable.

Cooking on electricity
usageCookingElectric
78%0 … 100Provisional

German dwellings are almost entirely electric: 40.19 TWh of the 42.29 TWh Eurostat reports for household cooking in 2023, or 95 % of the energy and 98 % of the service. German service buildings are not: JRC-IDEES-2021 puts 28.48 TWh of gas into commercial catering against 11.67 TWh of electricity. Over both, 51.86 × 0.84 / (51.86 × 0.84 + 30.96 × 0.40) = 78 % of the service. Why provisional, and it matters: run the same extraction on France and IDEES gives 25.85 TWh of tertiary catering against the 11.72 TWh the French model carries — a factor of 2.2. If IDEES over-counts German catering by the same factor, the German default is nearer 87 %. The two numbers bracket the answer and neither is a guess. Either way this is the sharpest single national difference in the buildings module and it works against the coarse control: simpleElectrifyUsages buys France a real reduction and buys Germany very little, because German kitchens are already electric.

Air-conditioning growth
usageCoolingGrowth
0%0 … 300Game rule

The baseline is this package's own two cooling rows, 6.6 TWh against France's 24, and it is the least trustworthy denominator in the German building block: cooling_tertiary is known to be out by roughly a factor of four, in the direction of understating it, for want of a German tertiary end-use source in harmonised form. A player who moves this slider is therefore moving a percentage of a number that is probably too small. The asymmetry France declares applies here too and is milder: cooling makes a summer peak and the only peak constraint in this model is a winter one. What would close the baseline: a German tertiary end-use breakdown — AGEB or a Zensus-based service-sector survey.

Appliance efficiency
usageSpecificEfficiency
0%0 … 50Game rule

Lighting, appliances, screens and servers. It is the lever that has historically delivered — French specific consumption has been roughly flat for a decade while the equipment count rose — and here it is set against the growth lever below, which is the whole point of having both.

Digital and equipment growth
usageSpecificGrowth
0%-20 … 150Game rule

The counterweight to appliance efficiency. Data centres and AI are the part of this that is growing fastest and the part the model is least able to source, so it is left as an explicit assumption rather than given a trajectory it cannot defend.

Gas plants run on hydrogen
gasPlantHydrogen
0%0 … 100Game rule

RTE keeps a few GW of combustion capacity in every 2050 scenario, for the windless fortnight that no amount of storage covers. What it burns is a choice: methane, which draws on the same biomethane everything else wants, or hydrogen, which draws on electricity instead and emits nothing at the stack. Hydrogen is much the dearer of the two, and the model charges it: the electrolytic price the industry module already computes, against a methane price. What it does not do is add the electrolysis back into the electricity the mix has to serve — that would be a fixed point the compiler cannot express, since demand sets the mix and the mix would set demand. The extra electricity is reported instead of hidden.

Electrolysis
h2Electrolysis
100%0 … 100Game rule

The model assumed this for every tonne of hydrogen until v0.12.0, which was a strong assumption wearing no clothes: 87 TWh of electricity for hydrogen, and no way to ask what a reformer would cost instead.

Steam methane reforming
h2Smr
0%0 … 100Game rule

A reformer burns and reforms methane. In this model 2050 methane is biomethane, so the colour of the hydrogen depends on the colour of the gas — and it draws on the same biomethane pool as everything else, which is the trade-off worth seeing.

Autothermal reforming with capture
h2AtrCcs
0%0 … 100Game rule

ATR concentrates the CO2 in one stream, which is why it captures at 94% where a reformer with post-combustion capture struggles past 60%. On biomethane this goes negative, and that is not a trick of the accounting: the carbon came out of the air last season and is being put underground. It is also the single most contested line in the model — see the controversy tab — because it makes a scenario's arithmetic depend on a biomass supply chain the model does not represent.

Electricity mix scenario
rteScenario
21 … 6Published

Six German mixes: the three 2045 scenarios of the Netzentwicklungsplan Strom 2037/2045 (version 2025, second draft) and three built from the TYNDP 2024 capacity trajectories for the DE00 node. The default is NEP scenario B, the one that follows the statutory renewables build path. Germany has no nuclear axis — the last three reactors closed on 15 April 2023 and no published scenario rebuilds any, so nuclear is 0.0 in all six rows and that is a value, not a gap. What the German set spans instead is the degree of electrification and the split between domestic electrolysis and hydrogen imports.

LFP share of batteries
batteryLfpShare
0%0 … 100Game rule

The chemistry choice, and the sharpest trade-off in the account. LFP carries almost no cobalt (7 grams per MWh against 27 kg) and a quarter of the nickel, but 4.4 times the lithium — 490 kg per MWh against 111. There is no chemistry that is cheap in every metal at once, which is the point of putting it on a slider. Zero by default because the source scenario's 2050 reference is NMC 811.

Industry discount rate
discountIndustry
8%2 … 15Published
Residential discount rate
discountResidential
4%0 … 10Game rule

A household and an industrial investor do not face the same cost of capital. Moving this rate from 4% to 8% raises the building indicator by about a third with no physical change at all, which is why it is a lever and not a hidden constant.

Carbon price
carbonPrice
150 €/tCO₂0 … 300Published
Industrial electricity price
elecPriceIndustry
135 €/MWh20 … 200Published

134.6 €/MWh, the German price for an industrial consumer taking 20 000-69 999 MWh a year, excluding recoverable taxes, first half of 2025; the smaller 2 000-19 999 MWh band pays 159.8. France on the same call and the same half-year pays 92.8 and 116.4. German industry pays about 45% more than French industry for electricity, which is the reason most often given for the closures in this file's own industry block, and carrying France's 70 would erase it. The two numbers are not the same quantity and a reviewer must know it. France's 70 €/MWh is a POMMES 2050 model output; this is a 2025 observation. Using an observed price as a horizon assumption says German industrial electricity is as dear in 2045 as it is today, which no German scenario claims. What would close it: an industrial electricity price out of the Langfristszenarien or a dena 2045 run, on the same basis as POMMES.

Deep-retrofit cost
retrofitCost
550 €/m²200 … 900Provisional

PLACEHOLDER — French value carried, not German data: 550 €/m² is an ADEME order of magnitude with no primary publication behind it even in France. German deep-retrofit costs are higher than French ones and the 19% VAT compounds it, where France applies a reduced 5.5% rate to renovation work — so this number is very likely too low for Germany, and by more than the slider's own step. What would close it: BKI Baukosten, or the KfW/BEG measure-cost statistics, which publish euro-per-square-metre costs by measure and by building class.

  • countries/FR/FR.yaml, retrofitCost — carried unchanged — Not a German source. See NOTES.md under Placeholders.
Liquid fuel at the pump
liquidFuelPrice
200 €/MWh80 … 400Provisional

PLACEHOLDER — French value carried, not German data: 200 €/MWh is an unsourced French 2050 pump price for biofuel and e-fuel, taxes included, and the model's own annex calls it the weakest number in the cost layer. Nothing about it is German. What would close it: a German 2045 fuel-price case — the Langfristszenarien publish one — or the observed Dieselpreis escalated with the CO₂ price the Brennstoffemissionshandelsgesetz sets, which is at least a German quantity.

  • countries/FR/FR.yaml, liquidFuelPrice — carried unchanged — Not a German source. See NOTES.md under Placeholders.
Travel less
simpleTravelLess
Coarse control
0%0 … 100Game rule

The passenger sufficiency control. At 100% it removes 45% of passenger travel and takes air traffic from the workbook's implicit 0%/y to -1.5%/y — the two demand assumptions the transport module is most sensitive to, moved together because a scenario that flies as much as today while driving 45% less is not a coherent story about sufficiency.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Passenger mobility reduction passengerReduction: 0% → 45%
  • Air-traffic growth aviationDemandGrowth: 0%/y → -1.5%/y
Electric cars instead of fuel cars
simpleCarElectric
Coarse control
0%0 … 100Game rule

Moves the 20% of 2020 car demand still served by a liquid- or gas-fuelled car in the reference onto the electric fleet. The rail transfer is left where it is: electrifying the fleet and shifting trips off it are two different decisions, and folding them together would hide which one paid.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Fuel car carFuel: 10% → 0%
  • Biogas car carGas: 10% → 0%
  • Electric car carElectric: 70% → 90%
Get the diesel out of freight
simpleTruckClean
Coarse control
0%0 … 100Game rule

The reference already leaves only 10% of road freight thermal, so this is a small lever by construction, and that is the lesson: on the workbook's own trajectory the remaining road-freight emissions are not where the tonnes are. Hydrogen trucks are left alone, because arbitrating between hydrogen and battery is a detailed-view argument, not a coarse one.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Residual thermal truckThermal: 10% → 0%
  • Electric truck truckElectric: 40% → 45%
  • Shift to rail freight truckRail: 30% → 35%
Off the plane — rail and sea instead
simpleFlyLess
Coarse control
0%0 … 100Game rule

Modal shift away from aviation, which is where the transport module's residual emissions concentrate once the fleet is electric. Distinct from "travel less": this one moves the same journeys onto another mode rather than removing them.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Domestic aviation → rail domesticAviationRail: 50% → 100%
  • Air freight → maritime freightAviationSea: 20% → 100%
Heat less
simpleHeatLess
Coarse control
5%5 … 25Game rule

The building sufficiency control, in the unit of the lever it drives because it drives only that one. It starts at the reference 5% rather than at zero: the simple view offers effort beyond the reference scenario, never less than it.

Moving this control from 5% to 25% moves, in step and in proportion:

  • Temperature-related sufficiency bldgSobriety: 5% → 25%
Renovate the building stock
simpleRenovate
Coarse control
30%30 … 65Game rule

As with sufficiency, this is the stock-performance lever shown in its own unit and bounded below by the reference scenario. 65% across the whole stock is the upper end the workbook contemplates, not a technical limit.

Moving this control from 30% to 65% moves, in step and in proportion:

  • Average retrofit improvement bldgRetrofit: 30% → 65%
Build less, and in timber
simpleBuildLess
Coarse control, hidden
0%0 … 100Game rule

Not shown in this edition. This country's package hides the control; the model reads the lever at the default in the next column.

The materials side of the building question, and the one control in the simple view whose whole interest is how far it cannot reach. At 100% the country builds 8 Mm² of housing and 8 of everything else a year instead of 20.4 and 19.9 — the order of magnitude the official housing-need study reaches for the 2040s — and frames 60% of it in timber instead of 12%. Together those take roughly a quarter off national cement demand. They take far less off steel, because new buildings are about a ninth of it; and they cannot touch the third of cement that is roads, buried networks and bridges, nor the third that nobody has attributed. Two ideas in one control is a deliberate departure. Building less and building in timber are different decisions, and the detailed view keeps them apart; here they are bundled because they are the same material choice seen from a distance, and because a simple view that separated them would have spent two of its dozen controls on one question.

Moving this control from 0% to 100% moves, in step and in proportion:

  • New housing built newHousing: 0 Mm²/y → 8 Mm²/y
  • New non-residential built newNonResidential: 0 Mm²/y → 8 Mm²/y
  • Built in timber timberShare: 0% → 60%
Heat pumps instead of boilers
simpleHeatPumps
Coarse control
0%0 … 100Game rule

Electrification of heating, with the two consequences that make it a real choice rather than a free win. The wood boilers go with the gas ones, because 95% electric plus 46 TWh of wood would allocate more heat than the stock needs; the resistance heaters go into air-water heat pumps, because electrifying on resistance is what makes the winter peak unmanageable. The peak still rises sharply, and that is the point of the control. Pushing sufficiency and renovation at the same time shrinks the heat need under a fixed 95% share, so the building readout may report over-allocated heat; the model reports it rather than absorbing it.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Heat covered by electricity bldgElectricShare: 49% → 95%
  • Biomass for heating bldgBiomassTwh: 60 TWh/y → 0 TWh/y
  • Electric resistance bldgElecResistance: 15% → 0%
  • Air-water heat pump bldgElecAirWater: 31% → 46%
Electrify hot water and cooking
simpleElectrifyUsages
Coarse control
0%0 … 100Game rule

Hot water and cooking are about as much energy again as space heating, and neither is fully electric today. Their observed electric shares are the starting points, 100% the end.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Hot water on electricity usageDhwElectric: 31% → 100%
  • Cooking on electricity usageCookingElectric: 78% → 100%
Consume less material
simpleConsumeLess
Coarse control
0%0 … 100Game rule

The industrial sufficiency control. Freight demand is driven here rather than in transport on purpose: freight is what material consumption looks like on a road, and a scenario that halves plastic and cement demand while moving the same tonne-kilometres is not consistent. Steel goes from +30% to -40% against 2020, which is the widest swing any single number in the game commands. The output of the rest of industry is not driven, because its scale starts at today's output and has nowhere lower to go.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Plastic-demand reduction plasticReduction: 30% → 70%
  • Less cement per unit of works cementReduction: 10% → 60%
  • Steel production change steelGrowth: 30% → -40%
  • Freight-demand reduction freightReduction: 0% → 45%
Change the industrial processes
simpleCleanProcesses
Coarse control
0%0 … 100Game rule

Every route change the five value chains offer, moved together: H-DRI steel, the CO2 + H2 olefin route and the biogenic carbon it uses, heat pumps for food-industry steam and direct heat, the lowest clinker ratio in range, and capture on what is left. The processes of the rest of industry are not driven, because the reference already sits at 100% of them.

Moving this control from 0% to 100% moves, in step and in proportion:

  • H-DRI steel share steelDRI: 50% → 100%
  • CO₂ + H₂ olefin route olefinRoute: 50% → 100%
  • Biogenic CO₂ share biogenicCO2: 10% → 50%
  • Heat pumps for steam foodHPSteam: 60% → 100%
  • Heat pumps for direct heat foodHPDirect: 25% → 100%
  • Clinker ratio clinkerRate: 73% → 35%
  • CO₂ capture carbonCapture: 20% → 95%
Use less energy for the same output
simpleIndustryEfficiency
Coarse control
0%0 … 100Game rule

Efficiency rather than sufficiency or fuel switching: the same product, less energy. At 100% it claims the whole potential RTE identifies and recovers all of the recoverable waste heat, neither of which is costless or instantaneous — the cost panel and the annex say what that means.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Energy-efficiency effort industryEfficiency: 0% of the identified potential → 100% of the identified potential
  • Waste-heat recovery wasteHeatRecovery: 0% → 100%
  • Food-industry efficiency foodEfficiency: 20% → 50%
Eat less meat
simpleEatLess
Coarse control
0%0 … 100Game rule

The demand end of the food chain, moved as one plate. At 100% red meat falls from 40 to 20 kgec/cap/y — below INRAE's −40% and above ADEME's S1 divide-by-three — poultry from 28 to 18, dairy to 70% of the base year and the edible waste by the SNBC 3's own half. Exports are deliberately left alone: what a country sells is a separate argument from what it eats, and folding them together would let a diet lever cut a herd that is producing for somebody else's plate. The lesson is in the coupling rather than in the total. Two fifths of French beef is a by-product of the dairy herd, so cutting the milk makes the suckler herd grow to meet a beef demand that has not moved; only moving both together shrinks the cattle. A player who moves this control and watches the grassland released is watching the land account answer a food question, which is what the module is for.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Red meat eaten dietRedMeat: 48 kgec/cap/y → 20 kgec/cap/y
  • Poultry eaten dietPoultry: 21 kgec/cap/y → 18 kgec/cap/y
  • Dairy eaten dietDairy: 100% → 70%
  • Cut edible food waste foodWaste: 0% → 50%
Plant and protect the forest
simplePlantForest
Coarse control
0%0 … 100Game rule

The sink side of the land account. At 100% the forest expands at the 90 kha/y IGN's inventory measures rather than the 15 the SNBC 3 plans, the harvest falls from 60 to 45 Mm³/y, the long-lived share of what is still cut rises from 30 to 35%, and artificialisation stops entirely — the Climat et Résilience law's 2050 destination, on this account's own measure. It is the control that most obviously costs something, and that is the point: the forest takes k out of the living stock for every cubic metre cut, 1.5 tCO₂ in France, so every cubic metre not cut deepens the sink and leaves the boiler. Pushed to the top this control takes about a fifth off the wood the scoreboard scores — 127 TWh to 102 — and a scenario that has also electrified its heating will not notice while one that leaned on wood will. The climate case the forest lives through is not driven: it is a scenario choice rather than an effort, it moves the answer further than any of these four, and it stays a fine lever the simple view draws on its own.

Moving this control from 0% to 100% moves, in step and in proportion:

  • New forest planted afforestationRate: 6 kha/y → 30 kha/y
  • Wood harvested forestHarvest: 76 Mm³/y → 45 Mm³/y
  • Wood into long-lived products harvestToProducts: 44% → 55%
  • Land taken for building artificialisationRate: 11 kha/y → 0 kha/y
  • Drained peatland rewetted peatRewetting: 0% → 100%
Fertilise less
simpleFertiliseLess
Coarse control
0%0 … 100Game rule

The field end of the farm. At 100% the mineral dose on the conventional hectares falls to 50% of the base year and half the arable land goes organic, which between them deliver 26% of the 2024 nitrogen — well below the SNBC 3's own −54% and short of TYFA's zero — the legumes reach the 3.0 Mha the rotation studies stop at, and the whole 17.3 MtCO₂/y of soil-carbon practice INRAE itemises is taken. Four consequences are worth watching rather than assuming. The organic half yields two thirds of what it replaces, and since 0.24.0 the conventional half, at half the 2024 dose, keeps 0.79 of its yield — it is below the plateau — so this control costs arable land: the fields the same plates, herd and exports need grow by more than a third, and the crop block reports the shortfall, 4.2 Mha at 100%, against the land account rather than closing it — fertilising less is not free of land, and the page says by how much. Mineral nitrogen is also an industrial decision here: the same tonnage sets the ammonia the chain has to make, so fertilising less is a hydrogen saving as well as a nitrous-oxide one. More legumes raise the nitrogen balance while lowering the emissions — a legume hectare fixes more nitrogen than the mineral fertiliser its credit replaces, and only the difference between the two emission factors makes the net move downwards, so the balance is not a proxy for the tonnes. And the soil-carbon target is a thirty-year rate on a stock that saturates: the practice has to be kept up after 2050 for the carbon to stay where this account puts it.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Mineral nitrogen nIntensity: 100% → 50%
  • Legumes in the rotation legumeArea: 0.7 Mha → 2 Mha
  • Store carbon in the soil soilCarbonPractices: 0% → 100%
  • Organic farming organicShare: 30% → 50%
Grow energy on the fields
simpleGrowEnergy
Coarse control
0%0 … 100Game rule

The supply side of the biomass the rest of the game spends. At 100% the winter cover crops reach 3.0 Mha, the straw taken off the field reaches 30% — Agro-Transfert's ceiling for less than 2.5% of soil carbon lost — and the land growing fuel reaches 1.70 Mha, nearly three times today's and the IGEDD mission's own upper case. Between them they take the methane supply from 70 to about 86 TWh and the domestic liquid supply from 24 to 52. Two things this control does not do. It does not send manure to a digester: manureMethanised sits at 0 in the reference because the abatement it books rests on an enteric/manure split no French inventory publishes, and burying that argument inside an effort scale would be the wrong place for it. And the fuel crops it plants add no mineral nitrogen, because the dose is an intensity on an arable area held at the base year's: a fuel hectare displaces a food hectare that was already fertilised. The crop block counts the displaced food — the fuel hectare is arable land the plates, the herd and the exports can no longer use, and the headroom says by how much — but the fuel hectare itself adds no nitrogen and no nitrous oxide. That is the module's largest structural simplification and it sits directly under this control.

Moving this control from 0% to 100% moves, in step and in proportion:

  • Winter energy cover crops civeArea: 0.05 Mha → 1 Mha
  • Crop residues taken off the field residueMobilisation: 0% → 30%
  • Land growing fuel energyCropArea: 0.82 Mha → 1.5 Mha

Constants — fixed inputs

ConstantValueUnitProvenanceWhy, and where it comes from
efficiency_electricity_to_h20.6MWh H₂ per MWh electricityWorkbook

The workbook converts electricity to hydrogen at 60%. POMMES-INDUSTRY uses 45 MWh of electricity per tonne of hydrogen, which is 74%. The model keeps the workbook value so the cost layer and the electricity indicator describe the same hydrogen; hydrogen is therefore about 40% more expensive here than a POMMES-native calculation gives.

  • Teaching workbook, "General hypotheses" sheet E11
efficiency_electricity_to_efuel0.4MWh fuel per MWh electricityPublished

Electricity in, liquid e-fuel out, across the whole chain: electrolysis, CO2 supply, synthesis and upgrading. Concawe's techno-economic assessment gives 38% when the carbon comes from direct air capture and 44% when it comes from a concentrated industrial source, and 0.4 sits between the two. It is a whole-barrel figure, not a kerosene-only one: Fischer-Tropsch sends roughly a fifth of its liquids to gasoline and diesel, so the electricity behind one tonne of jet fuel alone is higher — about 38 MWh, or 3.2 kWh per kWh burnt. Use this parameter for total liquid demand, which is what the equations do, and do not quote it as an aviation figure.

ef_electricity_2020366gCO₂/kWhProvisional

The UBA's specific CO₂ emission factor for the German electricity mix in 2020. Read it beside the French value before using it: France declares 79 gCO₂/kWh on a life-cycle basis, and 366 is combustion at the stack of German power stations. The two are not the same measurement, and the perimeter difference runs the wrong way — a life-cycle German factor would be higher still, because the upstream of coal and gas is real. For a fossil-dominated mix the uplift is of the order of 10–15 %, so the comparable figure is nearer 400–420 gCO₂/kWh and this constant under-states the German position. For the trend, which is the point of the constant: the same series gives 764 gCO₂/kWh for 1990. Germany has halved its grid factor in thirty years and is still four and a half times France's.

dhw_efficiency_fuel0.85fraction of the energy delivered as hot waterProvisional

A gas or oil water heater, standing losses included.

  • ADEME orders of magnitude for domestic hot water production
dhw_efficiency_electric2MWh of hot water per MWh of electricityProvisional

Above one because it is not all resistance: a 2050 electric water heater stock is a mix of resistance tanks and heat-pump water heaters, the latter at a COP near 3. Two is the blend assumed here and it is an assumption, not a measurement — the honest range runs from 1.0 if nothing changes to near 3 if the stock is heat pumps. It sets how much electricity electrifying hot water actually costs, so it is worth arguing about.

  • ADEME, chauffe-eau thermodynamique — COP de 2,5 à 3,5 selon l'installation
cooking_efficiency_fuel0.4fraction of the energy reaching the panProvisional
  • Standard hob efficiencies; a gas burner loses most of its heat around the pan
cooking_efficiency_electric0.84fraction of the energy reaching the panProvisional

Induction. The gap with gas is the widest of any usage in the model.

  • Standard induction hob efficiency
carbon_in_methane202gCO₂ per kWh of methanePublished

The carbon actually in the molecule, released whether it is burned or reformed. Distinct from efGas, which is 25 gCO₂/kWh in 2050 because the model's methane is biomethane and the convention books its carbon against the digester feedstock rather than the flame. Both numbers are needed and they answer different questions. efGas answers "what does burning this count as?"; this one answers "how much carbon is there to capture?" A capture plant removes molecules, not conventions.

ef_gas_2020227gCO₂/kWhWorkbook
  • Teaching workbook, "Synthesis" sheet S42
ef_liquid_2020264gCO₂/kWhWorkbook
  • Teaching workbook, "Synthesis" sheet S44
ef_wood_202027gCO₂/kWhProvisional

PLACEHOLDER — French value carried, not German data: 27 gCO₂/kWh is the fossil energy of the French wood chain. What would close it: UBA ProBas life-cycle records for Holzpellets and Scheitholz. Germany imports a larger share of its pellets than France does and haulage is most of this factor, so the German figure is more likely above 27 than below it.

  • countries/FR/FR.yaml, ef_wood_2020 — carried unchanged — Not a German source. Listed in NOTES.md under Placeholders.
ef_coal340gCO₂/kWhPublished

Coking coal, 94.6 kgCO₂ per GJ, converted at 3.6 GJ/MWh. The workbook declares coal at 0 gCO₂/kWh in its factor table and then charges it at the hydrogen factor, 66.7 gCO₂/kWh, which is neither. This model uses the published factor and removes the double count that resulted — see steel_bf_process_residual.

steel_bf_base_production26 375kt/yPublished

Germany produced 37.2 Mt of crude steel in 2024, 70.9 % by the oxygen (blast-furnace / basic-oxygen) route: 37.2 × 0.709 = 26.375 Mt. This is the single largest blast-furnace stock in the European Union and it is what makes Germany the most valuable port of this game — France's equivalent row is 9.9 Mt, so the steel decision that is a side-show on the French board is the main event on the German one. Note the base year. The rest of this file is 2019; the only harmonised published split by process is worldsteel's for 2024, so these two rows are 2024. Corroboration from the same publication: German pig-iron production was 24.3 Mt in 2024, consistent with a 26.4 Mt oxygen route charging 15–20 % scrap.

steel_eaf_base_production10 825kt/yPublished

37.2 Mt × 29.1 % electric = 10.825 Mt. Same source and same base year as the blast-furnace row.

steel_bf_direct_intensity1.76tCO₂ per tonne of steelPublished

The total direct intensity of the integrated route — every source on site, not a process term. It was inherited from the teaching workbook as "the blast furnace's process figure", and under that name it had been counted on top of the coal it mostly is. Re-sourced in 0.27.0, it holds: the IPCC Tier 1 defaults summed over the chain give 1.87 tCO₂/t (1.46 for the converter, which already includes the blast furnace, plus 0.56 per tonne of coke and 0.20 per tonne of sinter); the EU ETS benchmarks, set on the best tenth of European plants, chain to about 1.4; and ArcelorMittal Dunkerque, at 6.8 Mt of steel and about 12 MtCO₂ a year, is at 1.76. The model charges the route's coal its own published factor, so this figure is never booked as such: steel_bf_process_residual keeps the remainder. The limitation: 1.76 and the 0.62 t of coal charged beside it describe a furnace about 20% better than the world average — worldsteel's route average is 780 kg of coal, which at this model's factor alone would release 2.08 t. The two are consistent with each other and should be changed together or not at all.

steel_eaf_process_per_tonne0.08tCO₂ per tonne of steelPublished

What an electric furnace emits on site besides its electricity: the graphite electrodes it burns and the carbon charged to foam the slag and carburise the melt. The IPCC's Tier 1 default, and the floor of the published range — the EU ETS benchmark for carbon steel is 0.215, because it also covers the gas burners and the ladle furnace. It applies to both electric routes, from scrap and from hydrogen-reduced iron, since both end in the same furnace. Until 0.27.0 the model gave these two rows no direct term at all, so the only steel that emitted on site was the blast furnace's.

olefin_base_production8 982kt/yProvisional

German structure with a French coefficient, and it should be replaced. No German olefin production statistic was secured. What exists is JRC-IDEES-2021's chemical-industry output index, "Basic chemicals (kt ethylene equivalent)": 22 905.5 kt for Germany in 2019 and 9 323.3 kt for France. The French model's olefin row is 3 656 kt — ethylene plus propylene, the C4 cut excluded since 0.23.0 — so the index over-states the French olefin tonnage by a factor 2.550; dividing the German index by the same factor gives 8 982 kt. It was 11 315 while the French anchor still carried the C4. That is a French ratio applied to a German measurement, not a German measurement. It is the right order — German ethylene capacity is commonly given as about 5.5 Mt/y and propylene adds roughly two thirds again — but it is an inference. What would close it: Eurostat PRODCOM (the ethylene and propylene codes were not resolved), Destatis Fachserie 4 Reihe 3.1, or VCI Chemiewirtschaft in Zahlen.

olefin_carbon_per_tonne3.138tCO₂ per tonne of olefinDerived

The carbon a tonne of olefin can physically hold, which is the ceiling on any claim that the product stores CO₂. Ethylene and propylene are both 85.63% carbon by mass, so a tonne holds 0.8563 × 44.009 / 12.011 = 3.138 tonnes of CO₂ equivalent. Nothing about the route changes it: it is the polymer's own composition. It replaces a coefficient of 4.3 that was 37% above this ceiling. The old figure came from the teaching workbook's "Industry" sheet K48 with no derivation, and it reproduces exactly as the CO₂ fed to the front of the route rather than the carbon locked in the product: 2.988 tonnes of methanol per tonne of olefin (methanol_per_olefin, published) times the 1.3735 tCO₂ per tonne of methanol that stoichiometry demands is 4.105, and 3.138 / 4.105 = 0.765 is an ordinary light-olefin selectivity for a methanol-to-olefins step. The 0.97 tCO₂ of difference leaves as C₄⁺, coke and purge gas; it is consumed by the plant, not stored by the polymer, and crediting it was double-counting the losses as a removal.

  • IPCC 2006 Guidelines, Vol. 3, Ch. 1 §1.3.1 — feedstock carbon is stored, and released when the product is oxidised
  • Atomic masses: C 12.011, O 15.999, H 1.008 (IUPAC 2021)
cement_base_production34 185kt/yPublished

German cement production in 2019, on the same base year as the rest of the industry block. Cross-checked two ways: VDZ gives "around 35.0 million tonnes" for 2021, and Andrew's clinker series gives 25 069 kt of clinker for 2019, an implied clinker ratio of 0.733 that matches the 2021 pair's 0.735. A caveat large enough to be a decision rather than a footnote: German clinker production has since collapsed, from 25 736 kt in 2021 to 18 549 in 2024. On the same ratio that implies roughly 25 Mt of cement in 2024, a quarter below the figure used here. 2019 is used because both of its terms are measured and because it is this file's base year. Read the France check with the same care: the model's French row is 16 500 kt against 19 964 kt from IDEES for 2019, a ratio of 0.826, so the two are not on the same perimeter and the German figure should not be compared cell to cell with the French one.

cement_process_per_tonne0.527tCO₂ per tonne of clinkerPublished

The decarbonation of the limestone, and nothing else: 6 193 ktCO₂ of calcination in the French inventory for 11 759 kt of clinker in 2020. The neighbouring years give 0.524 (2019) and 0.531 (2021), and it is what stoichiometry predicts: the IPCC's 0.51 × 1.02 for kiln dust = 0.52 for a 65%-lime clinker, 0.53 at 67%. No change of kiln fuel can remove it — only capture, or less clinker. It was 0.7925, and that was a total wearing the wrong name. The old value was 10.2 MtCO₂ over 12.87 Mt of clinker. 10.2 Mt is not the calcination line for any year France has published — that line ran 6.19 to 6.81 over 2015–2021 — but it is inside the range of the whole cement industry's CO₂, calcination and kiln fuel. And 12.87 Mt was not an observation: it is 16 500 × 0.78, this model's own cement anchor times the top of its own clinkerRate slider. The kiln fuel is charged separately through the energy account, so it was emitted twice — and carbonCapture, which multiplies this term, was capturing fuel CO₂ under a name that said it could not. The limitation. 0.527 is a French fleet average for one year, and it moves with the lime content of the clinker and with how much of the lime comes from slag or ash instead of carbonate: the IPCC's range is 0.47 to 0.53. It is also domestic clinker; about a quarter of the clinker behind French cement is calcined abroad, outside this perimeter.

kiln_heat_per_tonne1.064MWh per tonne of clinkerPublished

What a French kiln burns to make a tonne of clinker: 3 830 MJ in 2021, down from 3 942 in 2015. It closes against the roadmap's own statement that the sector burned 13 TWh of heat in 2021 for 12 222 kt of clinker — three published quantities, one identity, no residual. The sector aims at 3 600 MJ in 2030 and 3 500 in 2050, which is the 9% the industrial efficiency lever can take off. It replaced 0.700 in 0.29.0, the teaching workbook's figure, a third short.

kiln_waste_biomass_share0.52fraction of the waste-derived heatPublished

The biomass share of the waste a French kiln burns: 52% in 2021, from 49% in 2015 — animal meal, wood waste, sludge — where the rest is tyres, solvents, oils and plastic-rich refuse-derived fuel. The biomass half is charged to the wood carrier; the fossil half goes with the coke and the coal, whose emission factor it shares within a few per cent. The sector aims at 60% by 2050; this keeps the observed share, because a higher one needs a biomass supply the model would have to find somewhere.

wte_fossil_co2_base14.347MtCO₂/yPublished

14.3 MtCO₂ of fossil carbon in 2019, the inventory's "other fossil fuels" under public electricity and heat production, 1.A.1.a: the fossil half of the household and commercial waste burned with energy recovery. The German inventory books it in energy, as the French one does, and leaves only crematoria and bonfires in 5.C. 156 thermal treatment plants took 25.0 Mt of waste that year. It is an upper bound for incinerators. The same row carries the substitute-fuel plants and the waste co-fired in public coal plants, so part of it is not an incinerator stack at all. 2023 is 13.0, and the inventory carries 2023 into 2024 because the waste statistics come every two years. The plastic share of it is not published; the French 95% is carried across, and says what it is.

wte_plastic_fossil_share0.95fractionDerived

How much of an incinerator's fossil CO₂ is plastic: 95%. French residual household waste is 14.7% plastic by mass, 2 410 kt a year (ADEME, MODECOM 2017). At the IPCC's defaults — plastics are 75% carbon and all of it fossil — that is 6.63 MtCO₂. Everything else in the bin that carries fossil carbon adds 0.35: textiles 0.15 (20% of their carbon is fossil), nappies and other hygiene products 0.12, shoes and leather 0.06, soiled paper 0.02. 6.63 / 6.98 = 0.95. It is what makes plasticReduction reach the incinerator, and it is why the other 5% does not move with it. The limitation: the composition is household waste, and the fleet also burns commercial waste, which is if anything more plastic; the composites and small appliances — plastic as well — are left out rather than guessed, which errs low.

wte_biogenic_share0.5fraction of the stack CO₂Published

The German inventory splits household and municipal waste 1:1 between fossil and biogenic energy, a fixed assumption rather than a radiocarbon measurement. It sets only what a capture plant takes alongside the fossil: one biogenic tonne for each fossil one.

  • UBA (2025), National Inventory Report Germany 2025, p. 113 and p. 127 — fossil and biogenic fractions of household waste in a ratio of 1:1 (Hoffmann et al. 2011)
plastic_fossil_co2_per_tonne2.75tCO₂ per tonne of plasticPublished

The fossil CO₂ a tonne of plastic releases when it burns: 75% carbon, all of it fossil, times 44/12. It converts the plastic part of the incinerators' CO₂ back into tonnes, which is what a recycling line receives and draws its electricity on.

plastic_recycling_electricity0.5MWh per tonne of plastic recycledPublished

Sorting, washing, extruding: the JRC gives 0.3 to 0.7 MWh of electricity a tonne for mechanical recycling and next to no heat. The middle is taken. Chemical recycling by pyrolysis would need more, and no inventory of it is public.

  • JRC (2023), Environmental and economic assessment of plastic waste recycling, EUR 31423, PDF p. 54
food_steam_demand32.15TWh/yProvisional

Steam processing, steam drying and steam cooling in the German food, beverages and tobacco branch, 2019: 29.61 + 2.14 + 0.40 TWh. provisional because the France check does not pass: the same three rows give 28.62 TWh for France against the 21.876 TWh the French model carries, a ratio of 0.76. IDEES's steam block is wider than the workbook's, so the German figure is likely to be an over-statement of the same order. What would close it: a German branch-level process-heat study — the Fraunhofer ISI / IREES industrial process-heat work behind the Energieeffizienzgesetz.

food_direct_heat_demand14.34TWh/yProvisional

Direct-fired heat in the German food branch, 2019: direct heat thermal 2.31 + process heat thermal 1.92 + thermal drying 2.50 + thermal cooling 1.00 + ovens 3.61 + specific process heat 3.00 TWh. The France check gives 12.66 TWh against the model's 10.693, a ratio of 0.845 — just inside the band, so the mapping is close but not exact.

food_heat_pump_cop3MWh heat per MWh electricityWorkbook—
food_hydrogen0.141TWh/yProvisional

German structure with a French coefficient. No German figure for merchant hydrogen in the food industry was secured — IDEES reports no hydrogen at all in industrial final consumption for 2019 — so the French 0.138 TWh is scaled by the size of the two food branches: German food, beverages and tobacco used 59.31 TWh of final energy in 2019 against 58.05 TWh in France, a ratio of 1.0218, and 0.138 × 1.0218 = 0.141. It is a very small number and no lever moves it; it is here so the hydrogen account has no hole.

building_need_calibration1fractionDerived

One for Germany, and that is the clearest single win of this port. In France the constant exists because the workbook's surface × surfacic need over-states the observed heat and has to be scaled down by 0.6528. The German building_segment table is not built that way: its surfacic need column is JRC-IDEES-2021's own thermal energy service per square metre, so surface × surfacic need reproduces the observed heat by construction and the correction is exactly 1. The level is right as well as the arithmetic. The German table sums to 511.93 TWh of useful space heat; running the same extraction on France gives 377.82 TWh against the 359.34 TWh the French model calibrates onto, a ratio of 0.951 — inside the 15 % band, so the quantity IDEES calls thermal energy service is the quantity the model calls heat need. One thing this loses and the interface should say: IDEES's space-heating total also carries 7.13 TWh of circulation pumps, which belong to no heating system and are not in the sixteen segments.

building_peak_202013.9GWProvisional

German structure with a French coefficient, and the hardest item in the port — hard for a structural reason rather than a bibliographic one. France's 40 GW is the winter power drawn by electric space heating, and Germany barely has any: three per cent of dwellings had a heat pump or solar thermal at the 2022 census, and German dwellings are 56 % gas and 19 % oil. The German winter peak is not a heating peak. Construction: the model's own base-year peak expression — Σ over the electricity rows of building_vector of need × unit_2020 / peak efficiency × peak share — gives 18.176 TWh-equivalent for the German stock and 52.170 for the French one. France anchors 52.170 at 40 GW, so the coefficient is 0.7667 GW per TWh-equivalent and Germany lands at 13.9 GW. What that assumes, stated: that German electric heating is as peak-coincident as French electric heating. It is probably less so — German night-storage heaters are deliberately off-peak and §14a EnWG lets the network operator curtail heat pumps — so 13.9 GW is more likely an over-statement than an under-statement. What would close it: the Bundesnetzagentur Leistungsbilanz, or the load chapter of the NEP main report. The alternative the scoping study recommends — drop the absolute anchor outside France and score the ratio — needs an interface change and is not available here.

  • Derived from countries/FR/FR.yaml building_peak_2020 = 40 GW and this file's own building_segment — The arithmetic is printed by extract/build_country_rows.py under `peak`. Not a German measurement.
official_transport_2024144.182MtCO₂e/yPublished

KSG sector 4, Verkehr, 2024. Domestic transport; international bunkers are a memo item outside the total.

official_building_202499.998MtCO₂e/yPublished

KSG sector 3, Gebäude, 2024 — CRF 1.A.4.a plus 1.A.4.b.

official_industry_2024149.767MtCO₂e/yPublished

KSG sector 2, Industrie, 2024 — CRF 1.A.2 combustion plus the whole of CRF 2, industrial processes. It is 2.4 times the French industry line, which is the size of the difference this port exists to show.

official_industry_205069.9MtCO₂e/yPublished

A projection, not a target. The 2024 amendment to the Klimaschutzgesetz replaced the per-sector annual budgets with one national budget path, so Germany has no statutory 2045 industry figure. What this is: the UBA's 2026 projection with existing measures, which leaves 69.9 MtCO₂e in the industry sector in 2045. The interface must call it a projection wherever France's column says SNBC.

official_agriculture_202460.8461MtCO₂e/yPublished

KSG sector 5, Landwirtschaft, 2024.

official_agriculture_205054.8MtCO₂e/yProvisional

A projection, and an interpolated one. The UBA's 2026 Projektionsbericht publishes agriculture to 2030 (58.2 MtCO₂e) and says of the years after it only that "bis 2045 ist nur ein leichtes Sinken der Treibhausgasemissionen erkennbar". This is that sentence made numerical: 58.2 declining at 0.4 %/year for fifteen years gives 54.8. What would close it: the annual series behind the Projektionsbericht, which is in the UBA datacube (a single-page application this extraction could not query) or in the EEA's national-projections datahub.

official_waste_20245.27731MtCO₂e/yPublished

KSG sector 6, Abfallwirtschaft und Sonstiges, 2024. Down 87 % on 1990: the 2005 ban on landfilling untreated organic waste is the single most effective instrument in the German inventory.

official_waste_20503MtCO₂e/yProvisional

A projection, interpolated on the same basis as agriculture. The Projektionsbericht gives 4.0 MtCO₂e in 2030 and says the landfill ban keeps reducing emissions "fortwährend bis zum Jahr 2050 und darüber hinaus"; continuing at half the 2026–2030 rate for fifteen years gives 3.0 MtCO₂e.

official_energy_2024189.699MtCO₂e/yPublished

KSG sector 1, Energiewirtschaft, 2024 — CRF 1.A.1. Six times the French energy line, and the reason a German player's electricity decisions move the national total in a way a French player's do not.

official_energy_205050MtCO₂e/yProvisional

A projection, and the residual of one. The Projektionsbericht gives the 2045 gross total (212.5 MtCO₂e) and three of the six sectors — industry 69.9, buildings 11.2, transport 23.6 — but not the split of the remaining 107.8 between energy, agriculture and waste. With agriculture at 54.8 and waste at 3.0 as interpolated above, energy is 212.5 − 69.9 − 11.2 − 23.6 − 54.8 − 3.0 = 50.0 MtCO₂e. Fifty megatonnes from a power system the same report has running on 80 % renewables looks large until you read what the sector contains: the report says a third of it is power generation and the other two thirds are waste incineration plants and fuel refineries.

official_natural_sink_202457.8389MtCO₂e/yPublished

Positive: German land use is a net source, not a sink. The German LULUCF balance was +36.5 MtCO₂e in 1990, +47.6 in 2020, +73.3 in 2023 and +57.8 in 2024, on the UNFCCC convention where the sector total is positive when the sources outweigh the removals. The forest sub-sector alone was a net sink of −19.3 MtCO₂e in the 2025 proxy year and the rest of the land account more than cancelled it. Every French assumption around this number — that the sink is negative, that the slider runs from −40 to −5, that the default absorbs 23 — is wrong for Germany. The model already allows it: naturalSink is a signed magnitude and national_natural_sink is its negation.

official_natural_sink_205026MtCO₂e/yPublished

Still positive in 2045 on the UBA's own projection with existing measures — the land account is expected to be emitting 26 MtCO₂e in the target year. Set against KSG §3a, which requires a balance of at least −40 MtCO₂e, that is a gap of 66 MtCO₂e, larger than any other single shortfall in German climate law. The statutory figure is carried in DE.official.yaml as published2050TotalSinks so the interface can show the projection and the law side by side rather than one of them.

official_technological_sink_2050-6.2MtCO₂e/yPublished

Engineered removals at the horizon, negative for absorption. Germany has no statutory volume, so unlike France's −43 this is not a closure residual: it is the UBA's projected capture under existing measures — 0.7 MtCO₂e in 2030, 4.7 in 2040 and 6.2 in 2045.

snbc_gross_2050212.5MtCO₂e/yPublished

There is no German equivalent of the SNBC's gross 2050 total. The Klimaschutzgesetz sets net neutrality in 2045 and one national annual budget ending at 438 MtCO₂e in 2030, and no gross figure for the target year. 212.5 MtCO₂e is the UBA's projection of what is left in 2045 under existing measures — a projection of failure rather than a target, and the interface must say so. It is the number a German pathway should be read against, because it is what the country is currently on course for.

industry_covered_2020136.469MtCO₂e/yDerived

What the model represents of the German industry sector, on the inventory's own basis: the sum of JRC-IDEES-2021's CO₂ emissions over the eleven manufacturing branches the model covers, for 2019 — iron and steel 43.08, non-metallic minerals 36.66, chemicals 22.33, other industrial sectors 8.41, food 7.85, paper 6.13, machinery 4.87, non-ferrous metals 3.33, transport equipment 2.93, textiles 0.56, wood 0.32. The France check is the reason this is derived and not provisional: the identical extraction gives 67.79 MtCO₂e for France against the 68.9 the French model declares, a ratio of 1.016. Against the KSG industry line of 149.77 MtCO₂e for 2024, the perimeter difference is 13.3 MtCO₂e — construction and refining sit inside the inventory sector and outside manufacturing, and the two figures are five years apart.

fuel_efficiency_ceiling0.19792fraction of fuel savedProvisional

PLACEHOLDER — French value carried, not German data: this is RTE's figure after CEREN, for French industry. It is carried because it is a ratio — the share of industrial fuel a study finds can be saved — rather than a German stock, so applying it to German fuel gives a German saving. What is being assumed is that German industry has the same identified headroom as French industry, which is a claim about how much has already been done and is probably optimistic: German industry has been under an efficiency-agreement regime France has no equivalent of. What would close it: the Fraunhofer ISI / Prognos Energieeffizienz-Potenziale work behind the NAPE and the Energieeffizienzgesetz, or the branch-level potentials in the BfEE efficiency reports.

  • countries/FR/FR.yaml, fuel_efficiency_ceiling — carried unchanged — Not a German source. Listed in NOTES.md under Placeholders.
lhv_kerosene11.9MWh per tonnePublished

42.8 MJ/kg, the standard lower heating value of jet A-1.

  • Standard lower heating value of aviation kerosene
jet_fuel_price_2023816€/tPublished

The anchor for today's ticket. Everything that is not fuel is derived from it through the fuel share of operating cost, so an error here moves the whole non-fuel block.

co2_per_tonne_kerosene3.16tCO₂ per tonne of fuelPublished

Combustion only — neither the upstream chain nor non-CO₂ effects.

  • ICAO; corroborated by the US Energy Information Administration
aviation_demand_horizon_years26yearsDerived

2045 − 2019. Germany's horizon is 2045 and its aviation demand data is 2019, so the compounding window is 26 years against France's 30. A demand-growth slider therefore buys the German player four fewer years of compounding at the same rate — a small change with a real effect at the top of the slider.

  • meta.horizon 2045 and meta.base_year 2019 of this file
aviation_horizon_years26yearsDerived

2045 − 2019, the same window, because the German traffic and efficiency statistics are the same 2019 IDEES extraction.

  • meta.horizon 2045 and meta.base_year 2019 of this file
observed_kerosene_per_pkm_202438.48g of kerosene per passenger-kilometreProvisional

The raw German statistic on the same construction as the French one: all aviation fuel — passenger and freight, domestic and international bunkers — divided by passenger-kilometres. 121.8 TWh over 266.0 Gpkm in 2019 is 0.458 kWh/pkm, and at 11.9 kWh per kilogramme of kerosene that is 38.5 g/pkm. It is higher than the model's own aviation rows because it also carries the freight in the holds and reflects actual load factors — exactly as in France, where the published statistic is 29.3 g/pkm. provisional because the France check gives 35.3 g/pkm from this extraction against the 29.28 the French model carries, a ratio of 0.83, and because the year is 2019 rather than 2024.

lhv_coal7.5MWh per tonnePublished

Lower heating values, used to turn POMMES prices per tonne into prices per MWh.

  • Standard lower heating values for hard coal, natural gas and hydrogen
lhv_methane13.9MWh per tonnePublished
  • Standard lower heating value of methane
lhv_hydrogen33.33MWh per tonnePublished
  • Standard lower heating value of hydrogen
price_methane_per_tonne561€/tPublished
price_coal_per_tonne99€/tPublished
price_iron_ore100€/tPublished
price_scrap180€/tPublished
price_limestone20€/tPublished
price_household_electricity383.5€/MWh incl. taxPublished

Household band DC (2 500–4 999 kWh/year), all taxes and levies included, first half of 2025. France's equivalent in the same series is 267 €/MWh: German households pay about half as much again for electricity, which changes every payback the building cost module computes.

price_household_gas121.6€/MWh GCV incl. taxPublished

Household band D2 (20–199 GJ/year), all taxes included, first half of 2025. France is at 129.9. The German electricity-to-gas price ratio is therefore 3.15 against France's 2.06 — and that ratio, not the absolute prices, is what decides whether electrifying a German boiler saves the household money. It is the reason the German heat-pump case is different and it deserves its own line in the interface.

price_wood77.5€/MWhProvisional

PLACEHOLDER — French value carried, not German data: 77.5 €/MWh is the Propellet index for France. Eurostat publishes no wood series. What would close it: the DEPV (Deutscher Energieholz- und Pellet-Verband) Pelletpreis index, which is monthly and national; German pellet prices have run in the 300–350 €/t range, which at 4.8 kWh/kg would be 63–73 €/MWh, but that range was not read from the index itself and is not used here.

  • countries/FR/FR.yaml, price_wood — carried unchanged — Not a German source. Listed in NOTES.md under Placeholders.
iron_ore_per_steel_bf1.8t per t of steelPublished
iron_ore_per_steel_dri1.6t per t of steelPublished
scrap_per_steel_eaf1t per t of steelPublished
cement_per_concrete300kg of cement per m³ of concreteProvisional

Structural concrete dosages run roughly 250 to 400 kg a cubic metre, and 300 is the middle of the structural range. It is not the 266 kg a cubic metre that the cement-and-concrete literature uses for "béton équivalent": that figure is a whole-economy bookkeeping factor that already absorbs mortars, renders, screeds and bagged cement, and applying it to building cement alone overstates the concrete by about seven tenths. Used only to express the construction module's cement as a concrete tonnage in the materials account; no emission depends on it.

  • Usual structural concrete dosage range; cross-checked against The Shift Project's 266 kg/m³ béton-équivalent factor, which is a different perimeter
concrete_density2 380kg/m³Published

Ordinary reinforced structural concrete. Presentation only, like the dosage above.

  • Standard value for ordinary reinforced concrete, used in the comparative life-cycle assessment this module's timber coefficients come from
limestone_per_clinker1.6t per t of clinkerPublished
kiln_heat_per_clinker0.888889MWh per t of clinkerPublished
coal_per_kiln_heat0.11919t of coal per MWh of kiln heatPublished

The cement kiln fuel appears in the cost model but NOT in the physical model, which gives cement only its grinding electricity. Cement combustion CO₂ is therefore missing from the emissions account — a known defect of the workbook, recorded here rather than silently patched.

cement_capture_extra_electricity0.54MWh per t of clinkerPublished

What an amine capture plant on a cement stack draws, per tonne of clinker, when it captures 95% of the stack: the heat that regenerates the solvent, raised electrically, plus the compression and the fans. Per tonne captured it is 0.54 / (0.95 × 0.86) = 0.66 MWh, which is where the published figures put it: an advanced solvent needs 2.3 to 3.3 GJ of heat a tonne at the reboiler, and compression to 150 bar another 132 kWh. A cement works has no steam to spare, unlike an incinerator, so the heat has to be raised, and since 0.32.0 the model raises it with electricity the power system has to supply. The capture plant treats the whole stack, the biogenic CO₂ of the kiln's waste included, so this is charged per tonne of clinker rather than per fossil tonne.

cement_capture_reference_rate0.95fraction of the stackPublished

The capture rate at which cement_capture_extra_electricity was measured. The lever's share of the stack is divided by it, so the plant draws its published figure exactly at 95% and proportionally less below.

  • Raillard-Cazanove (2024), PhD thesis, Table 2.11 p. 43, after Quevedo Parra & Romano (2023)
kiln_biomass_co20.36tCO₂ per MWh of biomass burnedPublished

The biogenic CO₂ the biomass half of a kiln's waste releases — animal meal, wood waste, sludge — at the IPCC's default for "other primary solid biomass", 100 t a terajoule. It is never counted in the emissions; it is the tonnage a capture plant takes with the fossil, and so what the transport and storage of cement capture are charged on.

wte_capture_electricity0.315MWh per tonne of CO₂ capturedPublished

What capture costs an incinerator in electricity, per tonne captured, fossil and biogenic alike. The plant has its own steam: the IEAGHG's two reference plants, 20 MWe each, extract 40 to 45% of the turbine's steam at 6 bar to regenerate the solvent at 3 GJ a tonne, which costs them 6.0 and 6.8 MWe, and compression and liquefaction take 2.8 and 3.2 MWe more. Over 27.9 and 31.8 t captured an hour, both come to 0.315 MWh a tonne, and both halve the plant's net output. The electricity an incinerator no longer exports is electricity the mix has to produce, so the model books it as a demand. Where the plant feeds a heat network a heat pump can win back part of it; the IEAGHG's third case does, and this does not.

wte_capture_cost100€ per tonne of CO₂ capturedProvisional

The capture plant on an incinerator — its capital and the running costs that are not energy — per tonne captured. The energy is charged apart, at the industrial electricity price, and so are transport and storage. Provisional, and the evidence is thin at both ends. The one techno-economic study of a retrofit gives a cost of capture of 90 to 156 € a tonne for plants of 3 to 12 kt a year, a tenth of a French incinerator. The one plant being built, Oslo's Klemetsrud, budgets 8.4 billion kroner at P50 for 350 kt a year, about 720 M€: at this model's 8% over 25 years that is close to 200 € a tonne in capital alone, for a first of its kind with its own harbour terminal. The cement plant in this model costs under 50 € a tonne on the same basis, from a gas twice as concentrated. 100 sits between them.

co2_transport_storage_cost50€ per tonne of CO₂ storedPublished

Shipping or piping a captured tonne to a storage site and injecting it. 50 € is the figure France Stratégie retains for French industry. Models that assume a shared network at scale go lower — 17 to 21 € in the IND-OPT study — and the one French cluster costed so far, Dunkirk, comes out at 120 to 160 €, because the CO₂ leaves by ship for a reservoir in the North Sea. Charged on every tonne stored, biogenic ones included, since a ship does not sort them either.

  • France Stratégie (May 2023), Les coûts d'abattement — partie 5, Industrie, ch. 4 §3, pp. 38–40 — transport and storage at 50 €/t stored
  • Raillard-Cazanove, Knibiehly & Girard (2025), J. Cleaner Production 508, 145511 — transport and storage 21.2 €/t (2030), 17.2 (2050)
  • ADEME (2024), ZIBAC Dunkerque — 120–160 €/t
smr_methane_per_tonne_h23.33t of methane per t of hydrogenPublished
smr_electricity_per_tonne_h20.58MWh per t of hydrogenPublished
smr_emission_per_tonne_h29.23tCO₂ per t of hydrogenPublished
methanol_per_olefin2.98837t of methanol per t of olefinPublished
floor_area_total7 360.19Mm²Provisional

Residential 3 841.4 Mm² plus services 3 518.7 Mm², both JRC-IDEES-2021 for 2021. The France check passes handsomely — the same extraction gives 4 187.1 Mm² against the 4 200 the French model declares, a ratio of 1.003 — and the German figure is still marked provisional, because a passing mapping check is not the same as a plausible answer. Here is the problem, and it is the largest single defect in this package. IDEES's German services floor area is 3 518.7 Mm², or 42 m² per inhabitant, against 15.5 in France and 47 in Spain. Divided into the German services space-heating consumption it implies 48 kWh/m² of final energy and 34–44 kWh/m² of useful heat, which is two to three times below any German non-residential building typology. The energy is Eurostat-consistent and is not in doubt; the area is modelled from employment and is. The consequence to watch: the energy the model computes is right because it is surface × intensity and the two errors cancel, but anything priced per square metre — retrofit cost, heat-pump cost, the renovation count — is over-stated in the German tertiary sector by the same factor. What would close it: the IWU / Wuppertal Institut Nichtwohngebäude-Bestandsmodell, or the German building typology (TABULA) for the residential half.

deep_retrofit_saving0.6fraction of demand removedProvisional

Demand reduction achieved by one deep renovation, used to convert the average stock improvement into an equivalent number of deep renovations.

  • ADEME orders of magnitude for a BBC-rénovation-level retrofit
retrofit_life30yearsProvisional
  • Conventional lifetime for building-envelope work
heat_pump_life17yearsProvisional
  • Conventional lifetime for a residential heat pump
heat_pump_cost_per_m280€/m² incl. taxProvisional

PLACEHOLDER — French value carried, not German data: 80 €/m² is an ADEME order of magnitude for an air-to-water heat pump in France. German installed costs are higher — the standard 19 % VAT rather than France's reduced 5.5 % accounts for about 13 % of the difference on its own — so this under-states the German cost. What would close it: the BKI Baukosten database, or the KfW/BEG funding statistics, which publish average measure costs per dwelling.

  • countries/FR/FR.yaml, heat_pump_cost_per_m2 — carried unchanged — Not a German source. Listed in NOTES.md under Placeholders.
renovation_vat1.19multiplierProvisional

Germany has no reduced VAT rate on renovation work: building services are charged at the standard 19 % rate, against France's reduced 5.5 %. The German instrument is on the income-tax side instead — §35c EStG, a credit on energy-efficiency measures in owner-occupied homes — which this model has no place for. A small number with a visible effect: the same retrofit costs about 13 % more in the German cost module than in the French one for purely fiscal reasons, and the German subsidy is invisible unless it is said out loud. provisional because the statute itself was not opened.

households41.474millionPublished

41 473 831 German households in 2021. The France check is 31.221 million from the same source against the 31.377 the French model carries — a ratio of 1.005 — so the definitions agree. Note this is households, not the 43.1 million dwellings the 2022 census counts; the two are different quantities and the model wants the first.

car_ownership_reference2 455€/household/yProvisional

German structure with one French coefficient. The Eurostat household budget survey gives, per German household in 2020, 1 549 PPS for the purchase of vehicles (CP071) and 534 for maintenance and repair (CP0723). Transport insurance is not published separately — Eurostat gives only total insurance (CP125), 1 537 PPS in Germany against 2 101 in France — so the French transport-insurance term of 508 €/household is scaled by that ratio to 372, giving 1 549 + 534 + 372 = 2 455. The France check on the two measured terms is what licenses this: France's CP071 + CP0723 + the same insurance term is 2 551 against the 2 541 the French model carries, a ratio of 0.996. Two caveats: the unit is purchasing power standards rather than euros, and German and French comparative price levels differ by about two points, so the conversion is left implicit; and the survey wave is 2020.

car_transport_reference4 330€/household/yPublished

The whole transport budget of a German household, COICOP division 07, 2020. The France check is as clean as it gets: 3 822 PPS from the same call against the 3 803 €/household the French model carries, a ratio of 0.995, so the French constant is this Eurostat line and the German one can be read straight off it.

km_per_car_per_year11 295kmPublished

Total car vehicle-kilometres divided by the car fleet, Germany 2019: 538 950 million km over 47 715 977 cars. The France check gives 11 080 km against the 11 600 the French model carries, a ratio of 1.047. Worth seeing behind the average: a German diesel car does 17 634 km a year and a German petrol car 8 205. The fleet average is the average of two very different populations, and an electrification lever that moves the diesel half moves more than half the kilometres.

reference_car_fleet47 715 977carsDerived

A pinned model output: the car fleet this model computes at the German reference scenario, used as the denominator of the fleet ratio so that household ownership cost scales with fleet size. Seeded here at the observed German fleet of 2019 and re-pinned from the model's own run by python3 app/tools/pin_reference.py --country DE.

afforestation_lag10yearsGame rule

New forest does not store carbon the year it is planted. Hectares planted less than ten years before the horizon are left out of the afforestation term altogether, which is a crude step where the truth is a curve; the alternative — a growth function nobody in the sources publishes — would be a curve we invented.

afforestation_storage_rate3tCO₂/ha/yPublished

New forest is booked at the expansion rate rather than at the average per-hectare rate of the standing forest, because a young stand does not store like a mature one. The same source gives 5.0 for a renewal plan on existing forest and 0.2 to 2.4 for the rest of the forest depending on management and climate; 3.0 is the expansion line.

soil_carbon_grass_to_crop3.6667tCO₂/ha/yPublished

1.0 tC/ha/y lost for twenty years when permanent grassland is ploughed, converted here at 44/12. The interval on it is ±40%, and the stock difference between the two uses (84.6 against 51.6 tC/ha over 0–30 cm) would imply 1.65 tC/ha/y if all of it were lost before a new equilibrium — it is not, and the modal value is what the inventory uses. These coefficients are measured on one country's soils and a port should check them against its own; they are shared because soil chemistry does not stop at a border, not because they are beyond argument.

soil_carbon_crop_to_grass1.8333tCO₂/ha/yPublished

0.5 tC/ha/y regained for twenty years when arable land goes back to grass, converted at 44/12. Half the loss rate, and deliberately so: the same source's finding is that "loss is twice as fast as gain", which is what makes re-grassing a slower repair than ploughing was a break.

soil_carbon_conversion_years20yearsPublished

How long a hectare goes on emitting, or storing, after it changes use. Twenty years is the tail the inventory applies, so at a horizon 26 years away only the last twenty years of conversions are still in the flux.

land_module_active1Game rule

This edition carries the land module. naturalSink is hidden and inert, the sink is the seven-class account below, the agriculture sector is the constructive chain of the food block, and the three biomass bands are the supplies the bioenergy block computes.

land_horizon_years21yearsDerived

2024 to 2045 — this edition's own horizon. The land survey behind the account is dated 31 December 2023 and the inventory year is 2024, so twenty-one years is the span every rate in this block is sustained over. France's is twenty-six, and that difference alone makes every German flow lever worth a fifth less than the same lever in France.

forest_production9.4m³/ha/yPublished

9.4 cubic metres a hectare a year of gross increment, in Vorratsfestmeter Derbholz mit Rinde — the fourth national forest inventory's own figure for its 2012-2022 period, and 16 % below the 2002-2012 period. The German forest is growing more slowly than it was, and that is measured rather than modelled.

forest_mortality1.8m³/ha/yDerived

1.8 cubic metres a hectare a year left standing or lying dead: total departures from the live stock, 110.1 Mm3, less the harvest converted to the same volume unit, 72.6 / 0.8 = 90.75 Mm3, over 10.8 Mha. The 0.8 conversion is the harvest-loss and bark convention and is not verified in the pages this port read. Calamities caused 49 % of all departures over the inventory decade — 44.8 Mm3 a year on 2.0 Mha — and a third of the calamity wood stayed in the forest. This constant is the decade's mean, so it carries the 2018-2020 bark-beetle catastrophe; 2024 alone was a much quieter year.

forest_production_area10.8MhaDerived

10.8 Mha of Holzboden — the wood-producing area the inventory's per-hectare figures are stated on, implied by 101.5 / 9.4, 110.1 / 10.2 and 72.6 / 6.7, which agree. It is not the land account's forest class of 10.689 Mha and not the inventory's headline forest area of 11.5 Mha: the three are three perimeters and the module keeps them apart. 87 % of the area is unrestricted and 6 %, 0.69 Mha, is closed to harvest.

forest_standing_volume3 670Mm³Published

3.67 billion cubic metres standing, 335 m3 a hectare — the largest standing timber stock in Europe. Spruce lost 220 Mm3, 18 % of its stock, between the 2017 carbon inventory and 2022. Nothing in the model reads this constant; it is displayed so a reader can put the annual flows beside the stock they come out of.

forest_harvest_base75.6Mm³/yDerived

75.6 million cubic metres Erntefestmeter ohne Rinde: the official 2024 harvest of 61.183 Mm3 divided by the 0.81 coverage the forest-sector research institute's own back-calculation finds for the statistic. The 14.4 Mm3 of difference is firewood cut and never sold, and it is 19 % of the German harvest against 28 % of the French one. It is in Efm and the identity runs on Vorratsfestmeter, which is what forest_harvest_volume_factor converts. The inventory's own use figure for its decade, 72.6 Mm3 Efm a year, is close to this and is a decade mean rather than a year.

forest_carbon_k1.18tCO₂/m³Derived

1.18 tonnes of CO2 a cubic metre of the volume balance, from the inventory's own stock pair: 1 184 Mt of carbon in living trees over 3 670 Mm3 of standing volume is 0.323 tC a cubic metre, whole tree and roots included, per cubic metre of Derbholz stock. It is not comparable with the French numbers, which are stated on bois fort tige: the French marginal, 1.5, is read off harvest projections, and the French level, 2.0, is the inventory's published sink over its balance rather than a stock ratio. A stock density is both a level and a margin at once, so forest_carbon_ratio_base is set equal to it and the German line stays proportional. A cross-check against the German inventory: the biomass line for 2023 is a source of 24.3 MtCO2 with an official harvest of 70.6 Mm3 Efm, and the identity at that harvest gives a source of 31.6 — the same sign, 30 % high, because the period emission factors are calibrated on logged wood and increment in 2018-2023 was below the decade mean. Recalibrate on the 2026 submission's biomass line when it can be read.

forest_carbon_ratio_base1.18tCO₂/m³Derived

Equal to forest_carbon_k. The German coefficient is a stock density, 1 184 MtC in 3 670 Mm³, which is a level and a margin at once; there is no separate sink-over-balance pair to anchor, so the living-biomass line stays proportional, as it was before France's was split.

forest_dead_wood_coefficient0.33tCO₂ per m³ of annual mortalityDerived

0.33 tonnes of CO2 a cubic metre of annual mortality: the inventory's dead wood line for 2023, a sink of 6.4 MtCO2, over the 19.3 Mm3 of mortality that produced it. German dead wood grew a third in ten years, to 323 Mm3 and 46.1 Mt of carbon, and the 6.4 is the transient of that build-up. Since 0.34.0 only this base-year flux is read: the pool then decays at forest_dead_wood_half_life, so a severe climate case refills it only by what has not decomposed by the horizon.

forest_dead_wood_half_life10yearsProvisional

Provisional: IGN–FCBA's French value, carried. Germany's own numbers point the same way or faster. 46.1 MtC of dead wood, 169 MtCO₂, taking in about 23 MtCO₂ a year — 19.3 Mm³ of mortality at forest_carbon_k — and keeping 6.4 of it is a half-life of about seven years; decay rates measured on German logs give 13 years for beech and 21 for spruce. At ten, the dead-wood sink falls from 6.4 to 1.5 MtCO₂/y by 2045 and the national net rises by 4.9 MtCO₂e. The land-sink line stays inert: the German land account is a source.

forest_litter_soil_sink9.4124MtCO₂/yCalibrated

The largest single calibration in the German package, and it is named rather than smoothed. The published lines it should carry are small: forest mineral soils including litter are a sink of 0.43 MtCO2 and fires plus mineral soil nitrous oxide a source of 0.15, so the measured mineral term is +0.28. This constant is +9.41, and the +9.13 difference is the residual that reconciles a decade-mean forest identity with a single year's category total. Where it comes from, precisely. The forest identity runs on the fourth inventory's 2012-2022 means — an increment of 101.5 Mm3, a mortality of 19.4 and a harvest of 94.5 in stock volume — and those means contain the 2018-2020 bark-beetle catastrophe. The target is the 2024 forest-land line of the national trend table, +2.14 MtCO2e, which is a quiet year: calamity wood was 27.3 Mm3 against a record 60.1 in 2020, and the harvest was the lowest in years. No published German source gives a 2024 increment or a 2024 mortality, and the only pool split available is the 2023 one of the previous inventory report — which the 2026 vintage has since revised, moving 2023 forest land from +20.9 to +7.5 MtCO2e. Three alternatives were tried and rejected. Recalibrating forest_carbon_k needs 0.44 tCO2/m3, a third of the stock ratio, and it would make the harvest lever almost powerless. Recalibrating the harvest needs 69.4 Mm3 Efm, which contradicts the Destatis rows the harvest closure is asserted on. Recalibrating the mortality needs 0.8 m3/ha/y, which contradicts a decade in which calamities were half of all departures. Loading the residual onto the one term France also treats as a residual is the least bad of the four, and this why is what makes it visible. What would close it: the 2024 pool split of the German 2026 inventory submission, which was not available when this package was written.

forest_overseas_sink0MtCO₂/yPublished

Zero. The German territory and the German inventory are the same perimeter; there is no overseas forest to carry. France's 10 MtCO2 is Guiana.

forest_harvest_sawlogs33.253Mm³/yPublished

33.253 Mm3 Efm o.R. of Stammholz in 2024, 54.3 % of the official harvest and 44.0 % of the harvest including the informal firewood.

forest_harvest_industrial12.233Mm³/yPublished

12.233 Mm3 of Industrieholz — pulpwood and panel wood — in 2024.

forest_harvest_energy_commercial12.548Mm³/yPublished

12.548 Mm3 of Energieholz sold in 2024. 2024 is the first year German energy wood passed industrial wood, which is a change in the wood chain worth knowing before reading the wood supply.

forest_informal_firewood14.417Mm³/yDerived

14.417 Mm3 by difference: 75.6 of removals less the four reported uses. It is 19 % of the German harvest, against 28 % of the French one, and it rests entirely on the 0.81 coverage ratio, which is not verified. An independent check: the inventory's own use figure of 72.6 Mm3 a year over 2012-2022 against a Destatis mean of about 64.5 over 2013-2022 gives the same 12 % gap from a completely different pair of numbers.

forest_harvest_unutilised3.149Mm³/yPublished

3.149 Mm3 of nicht verwertetes Holz in 2024 — felled and left in the forest. This is the fifth harvest row Germany needed and France does not have. It leaves the live stock, so the forest identity charges it as a removal; it reaches no boiler, so the wood supply must not count it as fuel. Folding it into the informal firewood, which was the alternative, would have handed the German wood supply 6.7 TWh of fuel that does not exist.

forest_harvest_volume_factor1.25m³ of standing stock per m³ of the harvest statisticDerived

The conversion France does not need. One cubic metre of the German harvest statistic — Erntefestmeter ohne Rinde, felling losses and bark excluded — is 1.25 cubic metres of the standing stock the increment and the mortality are measured in. The 0.8 ratio behind it is the harvest-loss and bark convention the forest inventory uses when it reconciles its own use figure with its departures, and it is not verified in the fetched pages: it is the factor that makes 110.1 = 72.6 / 0.8 + mortality close. It is worth a quarter of the harvest term of the forest identity, so a reviewer who doubts the 0.8 should read the forest pool as carrying that doubt.

hwp_coefficient0.562tCO₂/m³Provisional

German structure, a French coefficient, and nothing reads it. The stage-A flow reading of the wood-products pool is kept only so it can be shown beside the stock reading; since stage E the pool is a first-order-decay stock and no result depends on this number. No German flow coefficient is published — the national wood carbon monitor integrates half-lives instead — so the French value is carried for the comparison line.

  • countries/FR/FR.yaml, hwp_coefficient — carried for the comparison line only
hwp_long_lived_share_base0.4399fractionDerived

44.0 % of the German harvest becomes sawn timber and panels: 33.253 Mm3 of sawlogs over 75.6. It is twice the French 22.5 %, because the German forest is half spruce and pine and the German sawmilling industry is three times the size.

timber_cement_saving67kg cement per m² of floor framed in timberProvisional

Measured on one building and cross-checked against element coefficients, because no whole-building intensity by structural system is published anywhere. The anchor is an eight-storey, 142-dwelling mass-timber residential building whose bill of materials was compared with a functionally equivalent concrete one: 519 to 553 kg/m² of concrete avoided over 13 766 m² of gross floor area, which at 280–320 kg of cement a cubic metre and a density of 2 380 kg/m³ is 61 to 74 kg of cement, and 67 is the middle. A timber building is not a building without concrete, and that is the point of a saving rather than a substitution. The same measured building still carried 288 kg/m² of concrete in its foundations, its ground floor and its toppings, and used more lean concrete than its concrete twin. Against the 137 kg/m² this model books for new French housing, 67 is close to half — which is the right order: négaWatt reaches −46% of concrete at 80 to 95% timber, and half of 90% is 45. The competing way to model this is a displacement factor in tonnes of carbon avoided per tonne of carbon in the wood, and it is deliberately not used here. That literature has moved from 2.1 (Sathre and O'Connor 2010, 21 studies) to 1.2 (Leskinen 2018, 51 studies) to 0.55 at market level (Hurmekoski 2021, 44 studies, range 0.27–1.16), with a French critique arguing the benefit has been overstated several fold. A kilogramme of cement not made is a physical quantity this model already prices and emits; a displacement factor is an argument about counterfactuals. The model takes the physical route and leaves the argument to the annex.

  • FPInnovations / Gouvernement du Québec, comparative LCA of an 8-storey mass-timber residential building (Arbora, Montréal) — bill of materials
  • Hurmekoski et al. 2021, «Substitution impacts of wood use at the market level», Environmental Research Letters — market-level displacement factor 0.55 (0.27–1.16)
  • FCBA/BIPE 2019 for CODIFAB, FBF and ADEME — element-level equivalences: 1 kg of wood replaces 5.24 kg of concrete and 0.18 kg of rebar in a load-bearing CLT façade
timber_steel_saving17kg steel per m² of floor framed in timberProvisional

From the same measured building, and deliberately the net figure: the timber structure removes about 21 kg/m² of reinforcement, and adds back steel balconies, galvanised studs and brick support, so the whole-building balance is roughly −17 kg/m². Against the 21 kg/m² this model books for new French housing that is most of it — which is exactly why the national effect is small: new buildings are about a tenth of French steel, so even a wholesale switch to timber moves the steel bar by a few percent. ADEME's own biosourced scenario finds −2% then −5% on steel against −2% then −8% on cement, and this model reproduces that asymmetry rather than asserting it.

  • FPInnovations / Gouvernement du Québec, comparative LCA of an 8-storey mass-timber residential building — whole-building steel balance
  • ADEME 2019, «Prospective de consommation de matériaux pour la construction des bâtiments», scénario «développement des biosourcés»
timber_wood_intensity0.189m³ of wood product per m² of floor framed in timberProvisional

Two independent anchors agree, which is the only reason this number is here at all. The measured mass-timber building carries 2 597 m³ of cross-laminated timber, glulam beams and glulam columns over 13 766 m² — 0.189 m³/m². The French biosourced-building label's top level asks for 45 kgC/m² for housing, which at the carbon content and density of softwood is 0.200 m³/m². Light timber frame sits well below both, so 0.189 is a mass-timber figure and overstates what an ossature-bois house uses; the model says so rather than splitting a coefficient it cannot source.

  • FPInnovations / Gouvernement du Québec, Arbora mass-timber building — 2 047 m³ CLT + 378.2 m³ beams + 171.6 m³ columns over 13 766 m²
  • Arrêté du 2 juillet 2024, label «bâtiment biosourcé» — 45 kgC/m² for level 3 in housing
sawnwood_roundwood_factor2m³ of roundwood per m³ of sawn productProvisional

A sawmill turns roughly half of a sawlog into sawn timber; the rest is slabwood, sawdust and bark, and most of it is sold as chips, pellets or panel furnish rather than lost. The factor is what lets construction timber demand be compared with the long-lived harvest the forest account already computes, and 2.0 is the round number the trade uses. It is provisional because a national yield is not published on the same perimeter as this model's harvest.

  • Agreste, «Récolte de bois et production de sciages en 2024» — 18.3 Mm³ of sawlogs against 8.16 Mm³ of sawnwood produced
timber_share_base0fractionGame rule

Zero, matching the hidden timberShare lever, so the timber term is identically zero everywhere in this edition.

hwp_base_sink-0.41MtCO₂/yPublished

Minus 0.41: the German wood-products pool was a source in 2024, for the first time in the series. It absorbed 8.06 MtCO2 in 2020 and 1.42 in 2023, and the collapse follows the construction downturn — less sawn timber going in while the existing stock goes on decaying. In the module's convention a sink is positive, so this is negative.

hwp_carbon_per_m30.8373tCO₂/m³Provisional

0.8373 tCO2 a cubic metre of long-lived product, which is the IPCC 2019 Tier 1 carbon density of sawnwood, 0.229 tC/m3. It is a physical default and not a German measurement: no German inflow in tonnes of CO2 was available, so the density cannot be derived here the way it is in France, where the national report's own 10.0 MtCO2 of inflow over 11.95 Mm3 gives the same number to half a per cent. German softwood is a little lighter than the French mix, so this is more likely high than low. What would close it: the harvested-wood-products tables of the 2026 German submission.

hwp_half_life28.87yearsProvisional

German structure, a French coefficient. 28.87 years is the IPCC Tier 1 half-lives of sawnwood, panels and plywood weighted by the French inflow mix. The German mix is more sawnwood and less panel, which would lengthen it a little. Nothing German was read; what would close it is the half-life assumptions of the German submission's wood-products model.

  • countries/FR/FR.yaml, hwp_half_life — the IPCC half-lives, weighted with a French inflow mix
hwp_stock_nir_2021823.96MtCO₂Derived

The wood-products stock the pool's 2020 balance implies: at the base-year inflow of 27.8 MtCO2 and a decay rate of 2.40 %/y, a pool absorbing 8.06 MtCO2 net holds 824 MtCO2. The derived base-year stock is 1 177, and the 353 MtCO2 between them is hwp_stock_check — not an error to be closed but the size of a four-year swing in a published balance, from a sink of 8.06 to a source of 0.41. A reader should treat the German wood-products pool as the least stable line of the six.

grassland_sink_coefficient0.7415tCO₂/ha/yCalibrated

Mineral grassland absorbs 0.74 tCO2 a hectare a year; the organic soil under a sixth of it emits 27.1. The published pools for 2023 put strict grassland at a source of 28.5 MtCO2e of which 28.1 is organic soil, with biomass a sink of 6.3 and mineral soils a sink of 4.9; on the account's own 6.135 Mha and the 2024 category total of +24.18 the mineral term calibrates to +0.74. This is the entry the peat split exists for. Without it the coefficient would have had to be -5.1 tCO2 a hectare to reproduce the same total, and then every equation that grazes fewer hectares — a smaller herd, a diet with less beef — would have raised German emissions. The sign of a German herd result depends on this one decision.

cropland_source_coefficient0.6864tCO₂/ha/yCalibrated

0.69 tCO2 a hectare a year emitted by mineral cropland, calibrated on the 2024 cropland line of +17.52 once the 9.52 MtCO2 of drained organic soil under 0.34 Mha of it is taken out. The published 2023 split reads 47 % organic soils, 45 % mineral soils and 7 % biomass; the small biomass term is inside this coefficient rather than beside it.

artificialisation_carbon_content156.886tCO₂ per ha/y of flowCalibrated

157 tonnes of CO2 a year per thousand hectares of annual land take, once the settlement peat is held constant. All-in, the 2024 settlements line of 4.64 MtCO2e over 19.2 kha a year would read 242; 89 kha of drained organic soil under German settlements emits 1.63 MtCO2e whatever happens to the land-take rate, so booking it on the flow would have made the net-zero-land-take target look worth half as much again as it is. It is a standing emission per unit of flow, so stopping land take takes this line to 1.63 rather than to zero.

wetland_other_source5.2MtCO₂/yDerived

The wetlands line less its own organic soils: 8.95 MtCO2e in 2024, of which 41.9 % is organic soil, leaves 5.20 for the methane of man-made water bodies and everything else. Held constant, as in France — nothing in the game moves it.

peat_rewetted_emission5tCO₂e/ha/yProvisional

What a rewetted hectare still emits: about 5 tCO2e a year, mostly methane. Rewetting stops the peat oxidising; it does not make the hectare a sink on a twenty-one-year horizon, and a model that took the emission to zero would overstate the German peat lever by about a sixth. The figure is the order of magnitude the European rewetting literature converges on and the German fact sheets quote; no single German primary giving a national mean was opened, so it is provisional. It is uniform across classes on purpose — what differs between an arable bog and a forest bog is the drained factor, which is per class in land_class.

peat_rewetting_base0fraction of the drained organic soilPublished

Zero. German rewetting has run at a few thousand hectares a year against 1.95 million drained, and the emission factors the inventory publishes are measured on the drained area as it stands — what has already been rewetted is outside that area rather than inside it at a lower factor. The base-year pool check therefore runs on the whole drained area at the drained factor, which is what the inventory measures.

peat_agri_n2o_ef2.326tCO₂e/ha/yDerived

2.33 tCO2e a hectare a year of nitrous oxide from drained agricultural organic soil, booked in agriculture and not in land use. The inventory reports 12.3 kt of nitrous oxide from organic soils inside CRT 3.D — 3.26 MtCO2e — on the 1.353 Mha of cropland and grassland peat. It is declared apart from the peat_ef of the same soil because the two sectors are two lines, and it is kept out of ef_other_crop_n2o because it is not a response to fertiliser: a drained bog mineralises its own nitrogen, and leaving it inside the nitrogen factor would have let a German nitrogen cut switch off 3.3 MtCO2e it has no effect on. Rewetting switches it off entirely, which is what the equation does.

soil_practice_potential_arable9.977MtCO₂/yProvisional

German structure, a French coefficient, and the weakest number in this block. No German assessment of the agricultural soil-carbon potential was read. The French potential per hectare of arable land is applied to the German arable area — 14.777 MtCO2 on 17.265 Mha, scaled to 11.656 — which is an arithmetic and not a measurement. German evidence argues it is smaller, not larger: the national soil inventory of farmland finds no significant change in topsoil carbon under unchanged management and a loss on dry arable sites. soilCarbonPractices starts at zero in this edition, so nothing in the German reference depends on it; a player who moves that slider is moving this number. What would close it: the Thuenen humus-building work, or the UBA and Thuenen agricultural mitigation catalogue.

  • Thuenen Report 64, Landwirtschaftlich genutzte Boeden in Deutschland, p. 8 — No significant change of topsoil carbon under unchanged management; a loss on dry arable sites. Mineral soils 0-30 cm hold 61 tC/ha under arable and 88 under permanent grassland.
  • countries/FR/FR.yaml, soil_practice_potential_arable — 14.777 MtCO2 on 17.265 Mha, rescaled to the German arable area
soil_practice_potential_grassland1.698MtCO₂/yProvisional

The same arithmetic on grassland: 2.53 MtCO2 on France's 9.139 Mha, scaled to Germany's 6.135. Same caveat, same source, same zero default.

  • countries/FR/FR.yaml, soil_practice_potential_grassland — rescaled to the German grassland area
artificialisation_to_arable_share0.75fractionProvisional

Three shares where France has one, and none of the three is published. Germany's land-take split is not reported as a share anywhere this port read. What is measured is the forest side: the forest inventory finds 16 kha of the 66 kha of forest lost over its decade went to industry, commerce and transport, about 1.6 kha a year against a land take of 19.2 — which is the 8 % the forest share carries. The rest is farmland, and the arable and grassland split of it is set at three parts to one on the composition of the German agricultural area. The three shares sum to one, so the semi-natural class supplies nothing: German building spreads onto farmland and forest, not onto heath. What would close it: the land-use change matrix of the national inventory, which gives the transitions in hectares.

artificialisation_to_grassland_share0.17fractionProvisional

The grassland share of German land take, on the same reading and with the same gap behind it. France declares 0 here because its own accounting does not separate grassland from arable land in what is built on; Germany declares a share because the class matters — 17 % of 19.2 kha a year is 69 kha of grassland over the horizon, against a grassland class of 6.13 Mha.

artificialisation_to_forest_share0.08fractionDerived

8 % of German land take comes out of forest: 1.6 kha a year of the 19.2, from the forest inventory's own 16 kha of forest lost to industry, commerce and transport over ten years. It is the one of the three shares with a measurement behind it, and it is the one that matters most per hectare, because forest is the only class whose conversion removes a standing carbon stock.

artificialisation_rate_base19.2kha/yPublished

19.2 thousand hectares a year: Siedlung and Verkehr grew from 5 207 377 ha at the end of 2023 to 5 226 558 ha at the end of 2024, +19 181 ha. The daily indicator reads the same fact as 50 hectares a day — 34 for settlement, 17 for transport, less 1 given back — against 53 in 2023 and 77 in 2010. It is the rate the base-year settlements pool is calibrated on, so it and artificialisation_carbon_content have to be read together.

afforestation_rate_base6kha/yPublished

6 thousand hectares a year of net forest gain, from the land survey: Wald grew 10 688 592 to 10 694 619 ha between 2023 and 2024. The forest inventory's own net figure for its decade is 1.5 kha a year, four times smaller, from gross flows of +8.2 and -6.6; the survey's figure is used because the survey is the account. It is the largest unreconciled flow in the German land account, as the equivalent disagreement is in the French one.

grassland_conversion_base-4.3kha/yPublished

Negative: German grassland has been gaining. Dauergruenland went from 4 654.7 kha in 2010 to 4 714.3 in 2024, +4.3 kha a year, which in this module's sign convention — positive ploughs grass into crops — is -4.3. The EU greening rules are why: ploughing permanent grassland has needed authorisation since 2015.

soil_practice_base0fractionGame rule

Zero: no German soil-carbon practice programme is booked in the inventory, so the base year takes none of the potential. It is the value soilCarbonPractices is read at where the module is switched off.

secten_sink_forest_20242.14MtCO₂e/yPublished

CRT 4.A forest land, 2024: a source of 2.14 MtCO2e. It was a sink of 26.45 in 1990 and of 1.99 in 2020, and a source of 7.49 in 2023. The German forest stopped absorbing during the drought decade, and the inventory says so.

secten_sink_hwp_20240.41MtCO₂e/yPublished

CRT 4.G harvested wood products, 2024: a source of 0.41 MtCO2e, against a sink of 8.06 in 2020 and 1.42 in 2023.

secten_sink_grassland_202424.18MtCO₂e/yPublished

CRT 4.C grassland, 2024: a source of 24.18 MtCO2e — the second largest single line of the German land account, and 28.7 of it is the 1.06 Mha of drained organic soil under German grassland. France's grassland absorbs 5.7.

secten_sink_cropland_202417.52MtCO₂e/yPublished

CRT 4.B cropland, 2024: a source of 17.52 MtCO2e, of which 9.5 is drained organic soil. It was 26.75 in 1990 and 30.59 in 2023; the year-to-year swing is large because the mineral-soil term follows the weather.

secten_sink_artificial_20244.64MtCO₂e/yPublished

CRT 4.E settlements, 2024: a source of 4.64 MtCO2e, of which 1.63 is the 89 kha of organic soil under German settlements and the rest is the land take itself.

secten_sink_wetland_20248.95MtCO₂e/yPublished

CRT 4.D wetlands, 2024: a source of 8.95 MtCO2e — five times France's 1.2 — of which 41.9 % is organic soil, split between peat extraction and terrestrial wetlands, and the rest is largely the methane of man-made water bodies.

diet_dairy_index_base1index, base year = 1Game rule

One, by definition: dietDairy is an index on the base year, so the base year sits at 100%. It is declared rather than written into the formula so that the switched-off branch of the module names what it reads.

food_waste_cut_base0fraction of edible waste removedGame rule

Zero: the base year has cut none of its own waste, because the waste share is measured on it.

livestock_export_base1index, base year = 1Game rule

One: the export volumes the table declares are the base year, so the index that scales them is one there.

crop_export_base1index, base year = 1Game rule

One, like livestock_export_base: the export hectares the crop block declares are the base year's, and the index that scales them is one there.

n_intensity_base1index, base year = 1Game rule

One: mineral_n_base is the base-year delivery, and nIntensity is a percentage of it.

enteric_mitigation_base0fraction of cattleGame rule

Zero, and this is a statement about the calibration rather than about farming practice: the per-head emission factors are fitted to the observed inventory year, so whatever low-methane feeding that year already contained is inside the factors. The lever measures the change from there, and the change at the base year is nothing.

manure_methanised_base0fraction of manureGame rule

Zero, for the same reason as enteric_mitigation_base: the digesters the base year already runs are inside the observed emission factors, and the lever books the change from there. It is not a claim that no manure is methanised today.

agri_fuel_switch_base0fraction of farm fuelGame rule

Zero: the base year burns all of the fossil fuel the inventory measures on its farms.

ef_liquid_fossil_observed264gCO₂/kWhWorkbook

The observed emission factor of fossil liquid fuel, the value efLiquid slides away from and the one the base-year farm burned. It is used in one place only — to say how much energy the base year's farm fuel represents — and no emission is charged at it.

ln_two0.693147Published

The natural logarithm of two, which turns a half-life into a first-order decay rate: k = ln 2 / half-life. Declared once rather than written into a formula, like the nitrogen fraction of ammonia, because a number that appears in an equation should be a number a reader can find.

nh3_nitrogen_fraction0.822t N per t NH₃Published

14 ÷ 17: the nitrogen in a tonne of ammonia, from the atomic masses. It is the one number in this module that is chemistry rather than statistics, and it is what turns a nitrogen demand into an ammonia tonnage for the industry chain.

  • IUPAC atomic weights: N 14.007, H 1.008 — 14.007 / 17.031 = 0.8225
population_base83.51million peoplePublished

The population the food balance divides by: 83.51 million at 30 June 2024, the mid-year denominator the BLE itself uses. Destatis's end-of-year figure is 83.577 million; using the balance's own denominator keeps the per-capita quantities and the totals one arithmetic.

population_horizon80.33million peoplePublished

80.33 million in 2045, the moderate variant of the 16th coordinated population projection (G2L2W2). It is a fall of 3.8 % from the base year, where the French horizon population rises 1 %, and it is the single largest driver of the difference between the two references' agriculture: every diet-driven quantity in this module is scaled by it. The migration variants span 77.92 to 82.75 million, which is +/- 3 % on the herd.

diet_red_meat_base48.1kgec/cap/yPublished

Pork 35.5 plus beef and veal 11.8 plus sheep and goat 0.70 kilograms of carcass weight a head in 2024. The edible weight of the same basket is 38.2 kg; the module works in carcass weight because that is the unit the supply balance publishes and the unit the production chain is written in.

diet_poultry_base20.9kgec/cap/yPublished

20.9 kg of carcass weight a head in 2024, 13.7 as edible weight — the one German meat whose consumption has risen and the one whose self-sufficiency is below one.

food_waste_base0.07fraction of the food supplyProvisional

A labelled placeholder. Germany measures its food waste well — 10.8 Mt along the whole chain in 2022, 6.3 Mt of it in households — and does not publish the avoidable share of the food supply, which is what this constant is. 7 % is the French figure carried across, and it is displayed rather than driving: since stage E the waste that moves the chain is the per-product share in animal_product and crop_food_waste_share, and this constant only feeds the comparison line food_waste_basket_share. What would close it: the avoidable fraction in the Thuenen baseline study, which was not fetched.

dairy_beef_coupling_share0.8fraction of beef productionDerived

Four fifths of German beef is a by-product of the dairy herd, against two fifths in France, and it is what makes the German suckler herd almost irrelevant: 0.62 million suckler cows could yield at most about 0.19 Mt of the 1.05 Mt of beef Germany produces, so the rest comes from the dairy herd's culls and its calves. The consequence is worth knowing before reading any German diet result: cutting dairy consumption alone grows the suckler herd here even harder than it does in France, because the beef the dairy herd was supplying has to come from somewhere. A Schlachtungen-by-category series would replace the derivation with a measurement.

enteric_lipid_effect0.2fraction of enteric methane removedProvisional

A labelled placeholder. No German inventory or German study of a methane-reducing feed additive was read. 0.2 — a fifth of the enteric methane of an animal on the ration — is the order of magnitude the Klimaschutzszenarien assume when they put an additive in half the cattle herd. With entericMitigation at its default of zero it moves nothing in the German reference; it is what a player buys when they move that slider. What would close it: the Thuenen or UBA agricultural mitigation catalogue.

methanisation_abatement0.298fraction of manure methane removedDerived

Digestion avoided 42.5 kt of methane in the inventory year — 15.8 % of the manure methane that would otherwise have been released — with 53 % of the collectable dry matter digested, so the abatement per unit digested is 0.158 / 0.53 = 0.298. Read it with manureMethanised's own why. The equation applies this factor to the whole manure methane at the lever's position, and the base year the per-head factors reproduce is already net of today's digestion, so the German reference at 53 % under-books manure methane by about 1.2 MtCO2e. The correct form is an abatement on the digestion added to the base year; it would change France, so it is recorded as a gap rather than made here.

refrigerants_fixed0MtCO₂e/yPublished

Zero. German CRT sector 3 carries no HFC line: refrigerant leakage on farms is booked in sector 2.F with the rest of the country's fluorinated gases, not in agriculture the way the French inventory books it. The constant is therefore 0 rather than small, and the base-year livestock check closes without it.

mineral_n_base1 037.2kt N/yPublished

1 037.2 kt of nitrogen, the inventory's own calendarised mineral-fertiliser figure for 2023. The market data around it disagree in ways worth knowing: the trade association reports 1.095 Mt for 2023/24 and 1.137 Mt for 2024/25 on its own perimeter, and the cooperative federation reports 1.03 Mt of sales in 2023/24. The inventory figure is used because every emission factor beside it is the inventory's implied factor, and mixing a market tonnage with an inventory factor would break the closure.

manure_n_spread_base929.6kt N/yPublished

929.6 kt of nitrogen in manure spread on fields, manure digestates included. It is not every organic input: the inventory books 302.4 kt more from energy-crop digestates, 52.7 from waste digestates and composts, 15.4 from imported manure and 12.1 from sewage sludge, and the module does not itemise them — their nitrous oxide is inside ef_other_crop_n2o, which is calibrated on the whole 2024 soil line. A German reader should know that 383 kt of organic nitrogen is carried in a residual rather than as an input.

manure_n_grazing_base131kt N/yPublished

131.0 kt of nitrogen deposited by grazing animals. German cattle spend far less of the year outside than French ones: grazing is an eighth of the German excretion against half of the French, which is why the German grazing nitrous oxide is small and the manure-management line large.

fixation_n_base149kt N/yDerived

149 kt of nitrogen fixed biologically: 9.0 kg a hectare of farmland over 16.57 Mha, from the Thuenen sector model's own nitrogen balance for 2020/22. It is not an inventory source — the German inventory does not publish biological fixation as an input the way Eurostat's gross nutrient balance does for France — so the figure is a model output rather than a measurement, and it is a seventh of what the French balance reports per hectare.

fixation_gain0.6fraction of base-year fixationProvisional

German structure, a French coefficient. The additional fixation a hectare of legumes brings over the credit's span. No German study of it was read; the French value is carried onto the German legume area and the arithmetic below it is German. It is one of the three coefficients that make the German legume lever weaker evidence than the rest of this block.

  • countries/FR/FR.yaml, fixation_gain — carried unchanged onto a German area
legume_area_base0.672MhaPublished

672 kha in 2024: 285.0 kha of pulses and 387.4 kha of forage legumes. It is 2.4 % of the German farmland against 4 % in France, and it has been rising — 326 and 401 kha in 2026.

legume_n_credit128kt N/yProvisional

German structure, a French coefficient. The mineral nitrogen a larger legume area replaces, over the span below. No German study of the substitution was read, so the French pair is carried and applied to the German area. What would close it: a German rotation study, or the nitrogen chapter of the Thuenen baseline read in detail rather than for its balance table.

  • countries/FR/FR.yaml, legume_n_credit — carried unchanged
legume_credit_span1.7MhaProvisional

The increase in legume area the credit above was booked over, carried with it from the French package. The two are one coefficient in two parts and have to move together.

  • countries/FR/FR.yaml, legume_credit_span — carried unchanged
organic_share_base0.0743fraction of the arable areaPublished

7.43 % of the German arable area is organic: 866 249 ha of 11 656 400. The figure usually quoted is 11.3 %, which is organic arable plus organic grassland over arable plus grassland — organic farming in Germany is over-represented on grassland, 994 042 ha of it. This module's lever is on arable land, so the arable share is what it starts from.

organic_yield_ratio0.65fraction of the conventional yieldProvisional

German structure, a French coefficient. An organic hectare yields 65 % of a conventional one. No German meta-analysis was read; the value is the French package's, itself the middle of an international range that runs from −19 % to −57 % depending on the crop. It is the coefficient the German arable head room is most sensitive to, because the reference organic share is 30 %.

  • countries/FR/FR.yaml, organic_yield_ratio — carried unchanged onto German areas
n_yield_plateau0.9index, base-year dose = 1Provisional

German structure, a French coefficient. The German conventional hectare keeps its yield down to 90 % of its base-year mineral dose, the French package's own stance between INRAE's reading of the cut as efficiency (0.80) and the GRAFS curve with practices unchanged (1.00). No German study splitting a dose cut into efficiency and sufficiency was read. The German reference keeps the base-year dose, so the reference does not move with it; only a player who cuts the dose below 90 % reads it.

  • countries/FR/FR.yaml, n_yield_plateau — carried unchanged onto German areas
crop_nue_base0.67fraction of the nitrogen inputProvisional

German structure, a French coefficient. The curvature of the yield response below the plateau, taken from the French cropland nitrogen budget. Germany's own mineral share, 0.49, is its own: its fields get more of their nitrogen from manure, so the same cut in mineral nitrogen costs Germany less yield than France.

  • countries/FR/FR.yaml, crop_nue_base — carried unchanged onto German areas
crop_food_waste_share0.222fraction of the supplyProvisional

German structure, a French coefficient. The edible share of the plant-food supply lost downstream of the farm. Germany's own food-waste statistics are good at the whole-chain tonnage and silent on the split by product family, so the French chain synthesis is carried. It drives the plant side of the food-waste lever and nothing else.

  • countries/FR/FR.yaml, crop_food_waste_share — carried unchanged
arable_share_food0.1595fraction of the non-energy arable areaProvisional

The four use shares of the German arable area, fuel and methane crops aside — 9.49 Mha of the 11.66 Mha the land account holds. They are built from the crop areas themselves rather than from a grain balance: cereals for milling and the food potatoes, vegetables and sugar beet that go to people are 1.51 Mha, which is 15.95 % of the non-energy arable area. Germany's arable land is much more feed-oriented than France's — 61 % against 40 % — because half the German cereal crop and almost all its silage maize go to a pig, a chicken or a cow.

arable_share_feed0.61fraction of the non-energy arable areaProvisional

Feed: silage maize for the herd, feed cereals, feed potatoes and beet, and the temporary grassland inside the arable class. 61 % of the German non-energy arable area, and the reason a German herd cut frees far more land than a French one.

arable_share_export0.1355fraction of the non-energy arable areaProvisional

Export crops. Germany exports wheat and rapeseed and imports maize and soya, so the net position is much smaller than France's 23 % — the crop self-sufficiency this block reports is a little above one rather than near a half again.

arable_share_other0.095fraction of the non-energy arable areaProvisional

Fallow, seed, set-aside and everything else. It carries the rounding of the other three, which is why arable_share_check is exactly zero and this share is the one to distrust.

feed_forage_share0.62fraction of the feed areaDerived

The forage part of the feed area — silage maize and temporary grassland — which follows the cattle herd alone; the rest is grain and follows the compound-feed species mix. Germany's forage share is higher than France's because 2.05 Mha of silage maize is a fifth of the arable area.

energy_maize_area_base1.35MhaPublished

1.35 Mha of arable land grew a main crop for a digester in 2024: silage maize 896 kha, grass silage 285, cereal silage 76, grain 78, sugar beet 29 and Silphie 10. It is the value energyMaizeArea is read at where the module is switched off and the area the base-year biogas balance is built on.

energy_maize_dm_yield15.2t DM/haDerived

15.2 tonnes of dry matter a hectare: the inventory's own biogas energy-crop input, 20.9 Mt of dry matter in 2023, over the feedstock area the same year. Taking the tonnage and the area from the same pair of statistics is what makes the biogas balance close on a measurement rather than on an agronomic yield table.

energy_maize_digestate_ef1.1407tCO₂e/ha/yDerived

1.54 MtCO2e over 1.35 Mha. CRT line 3.J — digestion of energy crops — books 1.445 Mt of methane and 0.093 Mt of nitrous oxide in 2024, from a line that did not exist in 1990. Booking it on the area rather than on the gas is what makes it move with the lever a player has; the alternative, a fixed constant, would have left 1.5 MtCO2e answering to nothing.

compound_feed_share_poultry0.2fraction of compound feedProvisional

German structure, a reading rather than a statistic. The species split of German compound feed was not read from a primary source; the three shares are set from the herd's own feed demand — pigs dominate German compound feed, poultry is second and cattle third, which is the reverse of the French order. They are the weights of the feed-grain index and nothing else. What would close it: the DRV or BVA compound-feed production statistics by species.

  • countries/DE/NOTES.md — the compound-feed species split is a reading, not a fetched statistic
compound_feed_share_cattle0.3fraction of compound feedProvisional

Cattle's share of German compound feed, on the same reading.

  • countries/DE/NOTES.md — the compound-feed species split is a reading, not a fetched statistic
compound_feed_share_pig0.42fraction of compound feedProvisional

Pigs' share of German compound feed, on the same reading. Germany feeds 21 million pigs, three times the French herd, and the compound-feed industry is built around them.

  • countries/DE/NOTES.md — the compound-feed species split is a reading, not a fetched statistic
ef_mineral_n2o2.5294tCO₂e per t NDerived

2.53 tCO2e a tonne of mineral nitrogen: 9.9 kt of nitrous oxide over 1 037.2 kt of nitrogen. The implied direct emission factor is 0.61 % against the IPCC default of 1 %, because Germany uses the regionalised factors of Mathivanan et al. (2021) rather than the Tier 1 default. The indirect nitrous oxide — 0.87 tCO2e a tonne of any nitrogen input — is not here: it is in ef_other_crop_n2o, which the module applies to the whole input.

ef_mineral_co20.3182tCO₂e per t NDerived

0.318 tCO2 a tonne of mineral nitrogen: the urea line, 0.33 MtCO2 in 2024, over the nitrogen delivered. It is urea and nothing else. German liming is 1.91 MtCO2 and is driven by area and soil pH rather than by nitrogen, so it is declared in crop_carbon_fixed instead — which is why this factor is a quarter of the French one, where the two are charged together.

crop_carbon_fixed2.06MtCO₂e/yPublished

German liming, taken out of the nitrogen dose. 1.91 MtCO2 of liming (CRT 3.G) plus 0.15 of other carbon-containing fertilisers (3.I), held constant. Liming follows soil pH and the area limed, not the nitrogen delivered, so charging it on nitrogen the way the French package does would have let a German nitrogen cut switch off two megatonnes of limestone. It is 2.6 % of the German agriculture sector and it answers to no lever, which is stated rather than hidden.

ef_organic_n2o2.7652tCO₂e per t NDerived

2.77 tCO2e a tonne of nitrogen in spread manure: 9.7 kt of nitrous oxide over 929.6 kt of nitrogen. Above the mineral factor, which is the opposite of the usual ordering and follows from Germany's regionalised mineral factors.

ef_grazing_n2o2.2252tCO₂e per t NDerived

2.23 tCO2e a tonne of nitrogen deposited at pasture: 1.1 kt of nitrous oxide over 131.0 kt. The inventory applies the IPCC 2019 wet-climate factor of 0.6 % to cattle.

ef_other_crop_n2o2.545tCO₂e per t N of total inputCalibrated

The calibrated factor of the German crop block, and the one to watch. It carries, per tonne of the nitrogen input the module counts, everything the three factors above do not: crop residues (8.2 kt of nitrous oxide), mineralisation (1.2), the organic inputs the module does not itemise (3.8), and all the indirect deposition and leaching (10.9). It is fitted so that the base-year soil line reproduces the 2024 category total less the peat nitrous oxide — 11.20 MtCO2e — and it lands at 2.545, within a per cent of the 2.842 the 2023 sources imply on their own. The gap between the two is a year: the nitrogen inputs the module declares are the 2023 inventory's, because the 2024 detail is not published, and the target is the 2024 line. Watch this number after any change to the German nitrogen inputs.

residue_burning_fixed0MtCO₂e/yPublished

Zero. CRT 3.F — field burning of agricultural residues — is reported as not occurring in Germany: burning straw on the field has been prohibited since the 1990s.

farm_fuel_20247.5MtCO₂e/yPublished

7.5 MtCO2e from farm and forestry engines and farm boilers, CRT 1.A.4.c, which the Klimaschutzgesetz counts inside the agriculture sector: 53.31 of sector 3 plus 7.5 is the 60.8 the KSG books. As in France it is a process term rather than energy times a factor, and the energy behind it is reported as farm_fuel_energy_2024 and is outside the carrier pools in both directions.

grassland_rough-1.42054MhaDerived

Negative, which France's is not, and the sign is the point. The land account's grassland class is 6.134544 Mha — the land survey's agricultural area less arable land and permanent crops — while the farm survey's Dauergruenland is 4.714 Mha. The 1.42 Mha between them is non-farm grassland, paddocks, airfield margins and small parcels the land survey calls agricultural and the farm survey does not. The livestock block must graze the farm survey's grassland, so this constant subtracts the difference instead of adding rough grazing to it. France's +1.39 Mha runs the other way, because the French farm survey counts rough grazing the land survey books as heath. Both are the same reconciliation with opposite signs, and a country package may declare either.

ammonia_non_fertiliser2 319.1kt NH₃/yDerived

The ammonia German chemistry makes for something other than German fields: 2 950 kt of output less the 631 kt that the fertiliser nitrogen at a 50 % domestic share implies. It is large — four fifths of the output — because Germany exports fertiliser and because caprolactam, technical nitrates and the urea that goes into diesel exhaust fluid are all made here. It is derived from a placeholder: the 50 % domestic share above it is not sourced, so this residual carries that uncertainty one for one. A reviewer should read the two together.

ammonia_domestic_share_base0.5fractionProvisional

A labelled placeholder, and the same one the ammoniaDomesticShare lever carries: the share of German mineral nitrogen made in Germany is not published in the sources this port read. What would close it: the Destatis production statistics for GP 20151030 against the IVA import shares by nutrient.

citepa_livestock_202434.915MtCO₂e/yPublished

CRT 3.A enteric fermentation 25.85 plus 3.B manure management 9.07 (methane 6.23 and nitrous oxide 2.84), 2024. Livestock is 65 % of the German agriculture sector, enteric fermentation is 77 % of its methane and cattle are 93 % of that.

citepa_crops_202418.393MtCO₂e/yPublished

CRT 3.D agricultural soils 14.47 plus 3.G liming 1.91 plus 3.H urea 0.33 plus 3.I other carbon-containing fertilisers 0.15 plus 3.J digestion of energy crops 1.54, 2024. The last of the five is a German line France has no equivalent of, and 3.26 MtCO2e of the first is the nitrous oxide of drained organic soil, which this module drives from the peat lever rather than from the nitrogen dose.

biomass_biogas_yield2MWh PCI per t DMPublished

Methane yield of the wet feedstocks a digester takes — manure, crop residues and grass alike, which is how the source publishes it, as one number rather than three. Cover crops get their own, higher figure (cive_biogas_yield), because a whole green plant digests better than straw or a slurry does. It is shared rather than national because it is a property of the substrate, not of the country: the same tonne of dry manure yields the same methane in Germany. What is national is how many tonnes there are, which is manure_dm_per_cattle_head and its neighbours.

cive_biogas_yield2.8MWh PCI per t DMPublished

A winter intermediate crop harvested whole gives 250–320 Nm³ of methane a tonne of dry matter, and a normal cubic metre of methane is 9.97 kWh PCI, so the range is 2.5–3.2 MWh/t DM. 2.8 is its middle, and it is the figure that makes the mission's own arithmetic work: 6 t DM/ha × 2.8 is 17 TWh per million hectares, which is what the report quotes.

residue_liquid_yield2MWh per t DMPublished

A tonne of dry residue turned into a second-generation liquid fuel by the thermochemical route yields the same 2.0 MWh as the same tonne turned into biogas, which is exactly why the two compete: choosing one forecloses the other at no gain in energy. Declared separately from the biogas figure so that a source which does separate them can move one without the other. The equality is not a coincidence of rounding — Fischer-Tropsch converts at up to 50% and a digester's methane at a similar order — but it is a coarse number, and the route's real efficiency depends on the plant.

wood_energy_per_m32.14MWh per m³Published

Two administrations publish two numbers and the game has to pick one. The energy directorate's biomass balance uses 2.14 MWh per cubic metre of roundwood; the environment inspectorate's annex uses 2.4. 2.14 is taken because it is the figure the balance that also supplies non_forest_wood and waste_wood is written on, and mixing two conventions inside one total would be worse than choosing the lower of them. The difference is 12%, or about fourteen terawatt-hours on the base year — larger than any single lever in this block moves. It is shared rather than national because it is a conversion, not a measurement of a country: what varies across borders is the species mix behind it, and a country that knows its own should say so in the why of the entries that use it.

manure_dm_per_cattle_head1.29t DM per head per yearDerived

1.29 tonnes of collectable dry matter a head of cattle a year: 14.15 Mt of technically available cattle slurry and solid manure over the 11.0 million cattle of the survey year. Technically available is the biomass monitor's own perimeter — what could be collected from housing, not what the animal excretes — which is why it is twice the French figure: German cattle spend far less of the year at pasture, so far more of the manure is collectable.

manure_dm_per_pig_head0.045t DM per head per yearDerived

0.045 tonnes a pig a year: 1.18 Mt of pig slurry and solid manure over 26 million pigs. Pigs are 6 % of the collectable dry matter and a third of the animals.

manure_methanised_20240.53fraction of collectable manurePublished

On the dry-matter basis, because that is what the biogas equation reads. 8.1 of the 15.3 Mt of technically collectable manure dry matter already goes to a digester. Two other fractions of the same practice are published and neither belongs here: the inventory reports 18.8 % of the manure nitrogen digested, and the sector association says about a third by fresh mass. The three measure the same fleet on three denominators, and mixing them would break the base-year biogas balance.

cive_dm_yield5t DM per hectareProvisional

Not verified. Five tonnes of dry matter a hectare of catch crop, the middle of the 4 to 6 the German farm-management institute quotes; the source was reached at search level only. It multiplies 53 kha, so it is worth 0.74 TWh of the German biogas supply and the uncertainty is small in absolute terms — but a player who pushes civeArea to its maximum is multiplying it by twenty.

  • KTBL cover-crop dry-matter yields, quoted at search level — 4 to 6 t DM/ha — The primary was not opened. Recorded as not verified in NOTES.md.
cive_area_base0.053MhaPublished

53 kha of cover crop cut for a digester in 2022/23 — 39.9 kha of winter and 13.4 kha of summer catch crops — out of 2.15 Mha of cover crops grown in Germany. The feedstock association's own 285 kha of grass silage including cover crops is a wider category and is inside energy_maize_area_base instead, so the two do not overlap.

cive_land_ceiling4MhaProvisional

About 4 Mha of spring crops — silage and grain maize, sugar beet, potatoes and spring cereals — could carry a winter cover crop before it. Derived from the crop areas rather than published as a ceiling, so it is a reported diagnostic and never a constraint.

residue_dm_yield0.828729t DM per hectareDerived

0.83 tonnes of dry matter a hectare of arable land: 9.66 Mt of technically available cereal straw over the land account's own 11.656 Mha of arable land. The perimeter is not France's. The French constant, 3.30 t/ha, is everything the field produces; this one is what could be carried away once what the soil needs is left on it. Comparing the two directly is a mistake, and the mobilisation lever's maximum is stated on this narrower pool accordingly.

residue_mobilisation_base0.005fraction of the residue poolPublished

Half a per cent. Of the 9.66 Mt of technically available straw, 5.23 Mt is already used and 5.18 Mt of that is bedding; 0.05 Mt goes to energy. German straw is a bedding and a soil input, not a fuel.

residue_to_biogas_share0.5fraction of mobilised residuesGame rule

Half the mobilised straw to a digester and half to a second-generation liquid plant, as in the French package. Neither route exists at scale in Germany today — the base mobilisation is half a per cent — so the split is a teaching rule and is declared as one. What matters more than the value is that the split is exhaustive: this share and its complement are the only claims on the mobilised pool, so a tonne of straw is methane or a liquid and never both.

  • countries/FR/FR.yaml, residue_to_biogas_share — the same rule, and the same reason
biogas_other15.6848TWh/yCalibrated

The residual, and it is 17.6 % of the German base year against 78 % of the French one. What the module cannot build from an area or a herd: sewage gas (3.8 TWh), landfill gas (0.2), and the biowaste and industrial digestion that make up the rest. It is fitted so the base-year balance closes, exactly as France's is, and the reason it is a sixth rather than three quarters is that Germany publishes its digester feedstock as hectares and tonnes of dry matter while France publishes a number of plants. It moves with no lever, because it is what the module does not model.

wood_byproduct_share0.591074fraction of the material harvestCalibrated

The share of the material harvest that comes back as sawmill offcuts, bark, panel residues and black liquor. It is the one fitted term in the German wood balance — the harvest, the material share, the unutilised share, the conversion factor and the two waste terms are all measured — so what the base-year check measures is how much those five miss the observed total by once this one has done its work. It lands at 0.591, within two points of the French 0.581 on a completely different forest, which is a weak but real cross-check. The German by-products the biomass monitor counts — 8.91 Mt of sawmill by-products, 1.78 of black liquor — imply a lower share on a narrower definition of energetic use, and the difference is what the fit absorbs.

non_forest_wood5TWh/yProvisional

Wood energy from hedges, orchards, parks and trees outside woodland. The biomass monitor puts the technical landscape-wood potential at 2.08 Mt of dry matter with 0.61 Mt used, which is 3 to 9 TWh depending on the moisture and the conversion assumed; 5 TWh is the middle of that and is declared provisional. France's 22.8 TWh is far larger because the French figure includes the hedgerow firewood that Germany counts inside its informal harvest instead.

waste_wood28.53TWh/yDerived

End-of-life wood burned for energy: 6.34 Mt of the 7.48 Mt of waste wood the biomass monitor counts is used energetically, at 4.5 MWh a tonne — 28.5 TWh. It is three times the French figure and is a fifth of the whole German wood supply, which is worth knowing before reading any German wood result: a fifth of it comes out of a demolition skip rather than out of a forest, and no lever in this game moves it.

biofuel_1g_yield15.89MWh per hectareDerived

15.9 MWh a hectare, from the German crop mix: 583 kha of rapeseed at about 1.5 tonnes of oil a hectare and 10.3 MWh a tonne, plus 231 kha of ethanol crops at about 17 MWh a hectare. The mix is held fixed while the area moves, which is the simplification to name — a sugar-beet hectare yields three times an oilseed one, and the German mix is three quarters oilseed.

energy_crop_area_base0.814MhaPublished

814 kha growing a first-generation liquid-fuel crop in 2023. Unlike the cover crops it takes land, so it is inside arable_needed with the energy maize; the two together are 2.16 Mha, 19 % of the German arable area.

waste_fats_supply3TWh/yProvisional

A labelled placeholder. Used cooking oil and animal fats collected in Germany and made into liquid fuel. Two thirds of the fuel Germany burns is made from wastes and residues, but most of that used cooking oil is imported — the quota report puts 19 % of all feedstock inside Germany — and the table that splits the wastes by origin was not read. 3 TWh is the French value carried across, and it is a plausible German order of magnitude for domestic collection rather than a German measurement. What would close it: Table 25 of the BLE evaluation report, wastes by country of origin.

bio_imports_base15.8822TWh/yDerived

The net import that closes the base-year liquid balance: 31.865 TWh consumed less 12.93 from German crops, 3.0 from German bins and 0.05 from straw. The base-year check therefore closes by construction on this pool, which is a difference from France, where the liquid check was the one nothing was fitted to. The gross flows are much larger and run both ways — 81 % of the feedstock and two thirds of the fuel come from outside Germany, because German rapeseed biodiesel is exported while imported used cooking oil is burned here — and the module carries the net, because a supply band should score what the country actually has. The gross reading would put the import at about 26 TWh, and the difference between the two is the trade asymmetry the module does not model.

sdes_wood_2024148.77TWh/yPublished

148.77 TWh of primary solid biofuels, gross inland consumption, 2023 — and the year is not 2024. The German final-energy series for 2024 is published and the primary one is not: AGEE-Stat reports 120.75 TWh of heat and 10.10 TWh of electricity from solid biomass in 2024, which are final figures on two different conversion chains and cannot be added into a primary total without inventing two efficiencies. The European energy balance publishes the primary figure directly, for 2023. The constant states the year rather than hiding it, and the wood balance is checked on it.

sdes_biogas_202489.3TWh/yDerived

89.3 TWh of raw biogas in 2024, built from the German sector figures: 29 TWh of electricity from on-site combined heat and power at 40 % electrical efficiency is 72.5 TWh of gas, plus 12.8 TWh of biomethane fed to the grid, plus 3.8 of sewage gas and 0.2 of landfill gas. The 40 % is the convention to name; it is consistent with the 32.3 TWh of gross heat the same fleet sells and gives it away. It lands within one per cent of the European balance's 90.21 TWh of biogases for 2023, which is an independent cross-check on the construction.

sdes_biofuel_202431.865TWh/yPublished

31.87 TWh of liquid biofuel in 2024: biodiesel and hydrotreated oil 20.359, ethanol 9.245, vegetable oil 0.031 in transport, plus 2.129 of heat and 0.101 of electricity. Biomethane in transport (3.1 TWh) is not here — it is a gas and is counted in the biogas pool, so the two do not double count; the German quota year, which counts them together and on a different calendar, reports 3.6 Mt or about 35 TWh.

Data tables

The categories the model iterates over. Every row is addressed by its identifier, which is what the formulas in the next section refer to.

Passenger transport categories, Germany Published

Demand is 2019 service demand in billion passenger-kilometres, not 2020: German rail lost 40 % of its passenger-kilometres to Covid in 2020 and German aviation four fifths, and building a lockdown into a 2045 baseline would be the same mistake the French building_usage table avoids by using 2019 for the tertiary sector. The column is still called demand_2020, because the column names are the model's shared vocabulary. Which columns are German and which are not. demand_2020, in_inventory and the three aviation rows' occupancy and unit_consumption are German measurements from JRC-IDEES-2021. The road and rail unit_consumption and occupancy are PLACEHOLDER — French values carried, not German data: they are the workbook's 2045 vehicle characteristics, no equation reads them for a base-year account, and carrying them is what keeps the two boards comparable. For the record, the observed German 2019 intensities differ most for buses (645 kWh per 100 vehicle-km against the 284 carried here) and long-distance rail (1 813 against 1 859); German cars are within a percent of the French value once occupancy is taken into account. What would close it: a German 2045 vehicle-efficiency scenario — the Verkehrswende scenarios of the UBA RESCUE study, or the vehicle module of the Projektionsbericht. Aviation is on a different basis from France and must not be compared cell to cell. The French rows carry 413 Gpkm at 0.196 kWh/pkm, which is an airport-traffic basis — every passenger counted once at departure and once at arrival — with a per-passenger-kilometre intensity half the physical one; the product is right and neither factor is. The German rows carry 266 Gpkm on a departing-flight basis at IDEES's own 0.37 to 0.40 kWh/pkm, so the product reproduces German aviation fuel — 106.7 TWh of passenger kerosene in 2019 — and both factors are right. Doubling the German pkm to the French convention would double German aviation energy. Two row ids keep French names and German meanings. Germany has no overseas territories, so aviation_overseas carries intra-European aviation and aviation_international carries intercontinental. The ids are shared vocabulary — passenger_shift and flight_type address them by name — and the labels say what they are. Unlike France's, both are outside the national inventory: they are international bunkers. Two German rows are empty and are kept so the shift table has somewhere to send demand: two_wheeler_electric (IDEES has no electric two-wheeler row for Germany) and bus_h2. Urban rail — 17.6 Gpkm of German metro and tram — is not in this table, exactly as France's 15 Gpkm of métro is not in the French one; it is stated rather than silently dropped.

  • JRC-IDEES-2021, Germany, Transport module: TrRoad_act, TrRail_act, TrAvia_act and TrAvia_ene, 2019 — Cars 902.6 Gpkm (petrol 431.7, diesel 455.0, LPG 8.3, natural gas 2.5, plug-in hybrid 1.6, battery electric 3.6); buses 61.3; two-wheelers 13.0; high-speed rail 33.2; conventional rail 67.0; aviation 11.4 / 77.2 / 177.4. Light commercial vehicles are 43.4 Gvkm of freight activity in IDEES and are converted to passenger-kilometres at the model's own occupancy of 1.8, which is the French workbook's convention for that row. Extracted by extract/extract_transport.py.
  • countries/FR/FR.yaml, passenger — the road and rail unit_consumption and occupancy columns, carried unchanged — Not German values. Listed in NOTES.md under Placeholders.
Rowvectorunit_consumptionoccupancydemand_2020in_inventoryaviation
Fuel car
car_fuel
liquid651.5896.510
Gas car
car_gas
gas651.52.516110
Electric car
car_electric
electricity201.53.583410
Fuel utility vehicle
utility_fuel
liquid851.878.203710
Gas utility vehicle
utility_gas
gas851.80.309610
Electric utility vehicle
utility_electric
electricity201.80.434110
Fuel two-wheeler
two_wheeler_fuel
liquid501.0112.99710
Electric two-wheeler
two_wheeler_electric
electricity151.01010
Fuel bus
bus_fuel
liquid28414.2760.127310
Gas bus
bus_gas
gas28014.270.97210
Electric bus
bus_electric
electricity7514.270.200710
Hydrogen bus
bus_h2
hydrogen20014.27010
Long-distance train
train_long
electricity1 859457.99233.20410
Regional train
train_short
electricity97585.218167.04810
Domestic aviation
aviation_domestic
liquid7 133.298.770411.389811
Intra-European aviation
aviation_overseas
liquid4 884.87131.05377.195101
Intercontinental aviation
aviation_international
liquid8 481.2215.987177.43501

Passenger demand reallocation, Germany Game rule

Where 2019 demand goes in 2045. These are the game's own reallocation conventions, not national data: each row moves a share of one category's demand to another, the six shares a lever drives are overridden in the equations, and a category with no row keeps nothing — which is how fuel cars, fuel vans, fuel two-wheelers and fuel buses are retired. The conventions are identical to France's because they are rules of the game rather than facts about a country; the row set is German only in so far as it names German rows. One thing a German reviewer should argue with: bus_to_gas at 0.2 sends a fifth of German bus traffic to methane, which is a French workbook choice and sits oddly beside a German bus fleet that is electrifying.

  • The reallocation conventions of countries/FR/FR.yaml, kept as game rules — Declared `rule` rather than carried as data: no row here is a measurement in either country.
Rowsourcetargetshare
car_to_fuel
car_to_fuel
car_fuelcar_fuel0
car_to_gas
car_to_gas
car_fuelcar_gas0
car_to_electric
car_to_electric
car_fuelcar_electric0
car_to_rail
car_to_rail
car_fueltrain_short0
gas_car_keep
gas_car_keep
car_gascar_gas1
electric_car_keep
electric_car_keep
car_electriccar_electric1
utility_to_fuel
utility_to_fuel
utility_fuelutility_fuel0
utility_to_gas
utility_to_gas
utility_fuelutility_gas0.1
utility_to_electric
utility_to_electric
utility_fuelutility_electric0.9
gas_utility_keep
gas_utility_keep
utility_gasutility_gas1
electric_utility_keep
electric_utility_keep
utility_electricutility_electric1
two_wheeler_to_fuel
two_wheeler_to_fuel
two_wheeler_fueltwo_wheeler_fuel0
two_wheeler_to_electric
two_wheeler_to_electric
two_wheeler_fueltwo_wheeler_electric1
electric_two_keep
electric_two_keep
two_wheeler_electrictwo_wheeler_electric1
bus_to_fuel
bus_to_fuel
bus_fuelbus_fuel0
bus_to_gas
bus_to_gas
bus_fuelbus_gas0.2
bus_to_electric
bus_to_electric
bus_fuelbus_electric0.5
bus_to_h2
bus_to_h2
bus_fuelbus_h20.3
gas_bus_keep
gas_bus_keep
bus_gasbus_gas1
electric_bus_keep
electric_bus_keep
bus_electricbus_electric1
h2_bus_keep
h2_bus_keep
bus_h2bus_h21
train_long_keep
train_long_keep
train_longtrain_long1
train_short_keep
train_short_keep
train_shorttrain_short1
aviation_keep
aviation_keep
aviation_domesticaviation_domestic1
aviation_to_rail
aviation_to_rail
aviation_domestictrain_long0
overseas_keep
overseas_keep
aviation_overseasaviation_overseas1
international_keep
international_keep
aviation_internationalaviation_international1

Freight transport categories, Germany Published

Demand is 2019 service demand in billion tonne-kilometres, on the same base year and from the same source as the passenger table. A row that does not exist in France. German inland waterways carry 50.9 Gtkm — the Rhine, the Main-Danube canal and the Mittellandkanal — against 8.0 in France. The French table has no barge row because French inland freight is small; Germany's cannot omit it. This is exactly the case the free row set was designed for, and the barge is the one row whose unit_consumption is a German observation: 5.99 kWh per 100 tonne-km, from IDEES's own energy and activity, against 14.15 for France. Everything else's unit_consumption is PLACEHOLDER — French value carried, not German data: the workbook's 2045 intensities. Their relation to today is worth knowing before trusting them — observed 2019 is 31.6 kWh/100 tkm for German road freight against the 50 carried here, 3.63 for rail against 3.2, and 1.63 for international shipping against 0.6. The shipping row in particular understates by a factor of three in both countries. Cross-check against the national statistic, which uses a different perimeter and is worth stating: Verkehr in Zahlen 2023/2024 gives, for 2022, rail 132.6 Gtkm, inland waterway 44.1 and road 503.1 — but road there is all lorries on German soil including foreign ones, while IDEES counts German-registered vehicles including their international legs.

Rowvectorunit_consumptiondemand_2020in_inventory
Hydrogen truck
truck_h2
hydrogen5001
Fuel truck
truck_fuel
liquid50469.2931
Electric truck
truck_electric
electricity2001
Rail freight
rail_freight
electricity3.2119.471
Inland waterway
barge
liquid5.9950.9191
Maritime
maritime
liquid0.6976.0280
International air freight
air_freight
gas24516.73150

Freight demand reallocation, Germany Game rule

The same game rules as France's, plus one row the German table needs: barge_keep sends German inland-waterway freight to itself, without which 50.9 Gtkm would exist in 2019 and vanish in 2045. There is deliberately no truck_to_barge row. A road-to-water modal shift is a real German policy question — it is in the Bundesverkehrswegeplan — but it would be a lever, and a country file may not add one. Reported as a gap rather than hidden in a fixed share.

  • The reallocation conventions of countries/FR/FR.yaml, plus one German row — Declared `rule`: no row here is a measurement.
Rowsourcetargetshare
truck_to_h2
truck_to_h2
truck_fueltruck_h20
truck_to_thermal
truck_to_thermal
truck_fueltruck_fuel0
truck_to_electric
truck_to_electric
truck_fueltruck_electric0
truck_to_rail
truck_to_rail
truck_fuelrail_freight0
h2_truck_keep
h2_truck_keep
truck_h2truck_h21
electric_keep
electric_keep
truck_electrictruck_electric1
rail_keep
rail_keep
rail_freightrail_freight1
barge_keep
barge_keep
bargebarge1
maritime_keep
maritime_keep
maritimemaritime1
air_to_sea
air_to_sea
air_freightmaritime0
air_keep
air_keep
air_freightair_freight0

Building heating systems Workbook

The eight systems the stock is made of. is_destination says whether new surface can arrive: fuel boilers and electric resistance can only shrink, because nobody installs either in 2050, so the six remaining systems are what the stage-2 mix distributes over. heat_pump is used by the cost layer to price the equipment actually installed.

  • Teaching workbook, "Building parc 2020" and "Building heating" sheets
Rowis_destinationheat_pump
Biomass
biomass
10
Fuel boiler
fuel
00
Gas boiler
gas
10
Electric resistance
resistance
00
District heating
district
10
Air-air heat pump
air_air
11
Air-water heat pump
air_water
11
Hybrid heat pump
hybrid
11

Building stock segments, Germany 2021 Published

Sixteen rows, not twenty-four, and the restructuring is the point of a free row set. France splits its stock eight heating systems × three building types (apartment, house, tertiary). JRC-IDEES-2021 resolves the German stock by heating system and by sector, and no source crossing heating system × dwelling type × floor area × specific heat need was secured for Germany, so the German table is eight systems × two building types. Nothing is lost in the calculation: the only equation that reads building_type asks whether it is tertiary. What is lost is a display distinction, and a German house/apartment split from Zensus 2022 would restore it. surfacic_need is IDEES's own thermal energy service per square metre — useful heat delivered to the room, before the heating system's efficiency — which is why building_need_calibration is 1 for Germany and 0.65 for France. Surface per system is derived, not read: IDEES publishes the service and the service per square metre, and their ratio is the heated area. The extraction checks the derived total against the published stock area and fails above 0.5 %. Three things a reader should not take on trust. The tertiary rows are provisional inside a published table. They imply 34 to 44 kWh/m² of useful space heat, two to three times below any German non-residential typology, because IDEES models German services floor area from employment and gets 42 m² per inhabitant against 15.5 in France. The energy is right and the area is not; see floor_area_total. The electric split is wrong in a known direction. IDEES puts 2 471 445 German dwellings on heat pumps and only 90 652 on resistance heating, which cannot be right for a country with a large night-storage stock. Run the same extraction on France: the electric total is right (9.49 M dwellings against the French model's 9.67 M) and the internal split is out by a factor 2.6. Assume the same here. Everything electric is put on air_water because IDEES draws no air-air / air-water distinction, so air_air is empty; with 2.5 million dwellings out of 41 million it moves little except the winter peak. Zensus 2022 table 4000W would close both. Coal is inside the fuel-boiler row. IDEES separates solid fuels, LPG and heating oil; the game has one fossil-boiler system, so the German fuel rows carry all three and are charged the liquid emission factor. German household solid fuels were 348 ktoe in 2021, 0.6 % of residential energy, so the error is small — but it is an error, and it is in the direction of understating. The sixteen rows sum to 511.93 TWh of useful space heat, against 359.34 for France. IDEES's own space-heating total is 519.06 TWh; the 7.13 TWh difference is circulation pumps, which belong to no heating system.

Rowsystembuilding_typesurface_2020surfacic_needdwellings
Biomass, residential
biomass_residential
biomassresidential554 428 538104.4445 985 851
Fuel boiler, residential
fuel_residential
fuelresidential730 780 93779.00327 889 828
Gas boiler, residential
gas_residential
gasresidential1 939 466 348103.04420 939 320
Electric resistance, residential
resistance_residential
resistanceresidential8 396 47696.075890 652
District heating, residential
district_residential
districtresidential379 452 61298.09084 096 735
Air-air heat pump, residential
air_air_residential
air_airresidential000
Air-water heat pump, residential
air_water_residential
air_waterresidential228 913 088101.4792 471 445
Hybrid heat pump, residential
hybrid_residential
hybridresidential000
Biomass, tertiary
biomass_tertiary
biomasstertiary470 965 40236.63440
Fuel boiler, tertiary
fuel_tertiary
fueltertiary610 167 58744.41620
Gas boiler, tertiary
gas_tertiary
gastertiary1 851 831 82236.05030
Electric resistance, tertiary
resistance_tertiary
resistancetertiary117 755 43938.06340
District heating, tertiary
district_tertiary
districttertiary392 668 30843.38870
Air-air heat pump, tertiary
air_air_tertiary
air_airtertiary000
Air-water heat pump, tertiary
air_water_tertiary
air_watertertiary75 358 45033.75950
Hybrid heat pump, tertiary
hybrid_tertiary
hybridtertiary000

Heating system efficiencies and vector mix, Germany Provisional

How a segment's heat need becomes energy. Only two of the seven columns are German, and the table is provisional for that reason. German: the district-heating mix. unit_2020 on the six district_* rows is the fuel that produces German network heat — 64 % gas, 14 % coal, 14 % waste and recovered heat, 6 % wood, 2 % oil. France's network is 42 % gas, 28 % wood and 3 % coal. Germany burns four times France's coal share on its heat networks, which is the single most German fact in this table. Method, because it moves the answer: heat comes from heat-only plants, whose fuel all serves heat, and from CHP, whose fuel does not. The CHP fuel is split by energy allocation — heat output over heat plus electricity output, 43.9 % for Germany in 2021 — which is the simplest of the conventions in use and charges district heat more fuel than an exergy split would. Run the same method on France and it gives 42 % gas against the 35.2 % the French file carries and 28 % wood against 23.8 %: close in shape, not in level, which is why this is provisional rather than published. unit_2050 is a declared German assumption and no equation reads it: §29 Wärmeplanungsgesetz requires every network to run on renewables or unavoidable waste heat from 2045, so gas, oil and coal go to zero and the rest is split between wood, recovered heat and large heat pumps. PLACEHOLDER — French values carried, not German data: the three efficiency columns and peak_share. They are equipment characteristics rather than national facts — a German air-water heat pump has the same seasonal coefficient as a French one at the same outdoor temperature — but Germany is colder, with 3 114 heating degree-days in 2021 against 2 413 in France, and a colder climate lowers a seasonal coefficient of performance by several percent. What would close it: the seasonal performance factors measured in the Fraunhofer ISE "WPsmart im Bestand" field trials, which are the German reference and are published per technology and per building type.

Rowsystemvectorseasonal_efficiencypeak_efficiencypeak_shareunit_2020unit_2050
Biomass, wood
biomass_wood
biomasswood0.850.85111
Fuel boiler, heating oil
fuel_liquid
fuelliquid0.90.9111
Gas boiler, gas
gas_gas
gasgas0.950.95111
District heating, gas
district_gas
districtgas0.850.8510.6391510
District heating, oil
district_liquid
districtliquid0.850.8510.0219350
District heating, wood
district_wood
districtwood0.850.8510.0615140.25
District heating, coal
district_coal
districtcoal0.850.8510.1413670
District heating, recovered heat
district_other
districtother0.850.8510.1360330.45
District heating, heat pump
district_electricity
districtelectricity2.51.5100.3
Electric resistance, electricity
resistance_electricity
resistanceelectricity11111
Air-air heat pump, electricity
air_air_electricity
air_airelectricity2.52111
Air-water heat pump, electricity
air_water_electricity
air_waterelectricity32111
Hybrid heat pump, electricity
hybrid_electricity
hybridelectricity330.30.950.95
Hybrid heat pump, gas
hybrid_gas
hybridgas0.950.950.70.050.05

Where the cement and the steel go Game rule

Not ported. No end-use map of Germany's cement has been assembled for this edition, so the whole base-year tonnage sits in the residual row and the two new-build rows carry zero intensity. The module's arithmetic then returns 34185 kt unchanged, which is exactly what the cement chain read before the module existed — and a test asserts that every one of the four construction levers moves no output at all here. What a port needs is in the French file: an end-use split between new build, civil engineering and the rest; a cement and a steel intensity per square metre; and the floor area built each year. The French version of this table also shows that the two published maps of a country's cement are unlikely to reconcile, and where to keep the difference.

Rowcement_intensitysteel_intensitycement_2024steel_2024floor_2024driver
New housing
housing_new
00000none
New non-residential
other_new
00000none
Roads, networks and civil works
civil_works
00000none
All of it, unattributed
unattributed
0034 18500none

Industrial production routes Workbook

Unit consumption in MWh per tonne of product and process emissions in tCO₂ per tonne. These are shared by the physical model and the cost model, so the two can never drift apart. Grey ammonia's 0.914 MWh/t of gas is an order of magnitude below the roughly 9 MWh/t of a real reforming plant; it is kept for continuity with the workbook energy balance but the figure needs review, and the cost module prices that route from POMMES instead. The cement row carried electricity and a process term but no kiln fuel at all until 0.9.0: a clinker kiln burns 0.70 MWh a tonne and the model had it burning nothing, which left about 9 TWh of industrial fuel — and the combustion emissions that go with it — outside the account. The three fuel intensities are the source workbook's own, from its plaster/lime/cement branch sheet. The kiln row carries its electricity and nothing else since 0.29.0. Its fuel was 0.700 MWh a tonne of clinker in gas and "liquid", which a French kiln does not burn; it is now computed from kiln_heat_per_tonne and kilnAltFuel — petroleum coke, coal and the fossil half of the waste on the coal carrier, the biomass half on the wood carrier — because how much of it is waste is a choice the player makes, and a static row cannot carry a choice.

Rowsubpostelectricitygascoalliquidhydrogen
Steel — BF-BOF
steel_bf
steel0.1940.625.0474200
Steel — H₂-DR-EAF
steel_dri
steel1.2310.55001.683
Steel — EAF from scrap
steel_eaf
steel0.9180000
Ammonia
ammonia
ammonia0.7780005.94
Olefins — CO₂ + H₂
olefins
olefins5.95120001.32
Cement clinker
cement
cement0.15230000

Industrial plant, capital and fixed cost Published

CAPEX in euros per tonne of annual capacity, lifetime in years, fixed O&M in euros per tonne of capacity per year. The annualised cost is CAPEX × CRF(discount rate, lifetime) + fixed O&M, at full utilisation.

Rowcapexlifefixed
Blast furnace + BOF
steel_bf
4422553
H₂ direct reduction + EAF
steel_dri
4142553
Electric arc furnace
steel_eaf
1842553
Haber-Bosch ammonia
haber_bosch
1 0002050
Water electrolyser
electrolyser
1 12511.4216.87
Steam methane reformer
smr
3 24325546
Cement kiln
cement_kiln
186259.31
Cement kiln with capture
cement_kiln_ccs
4562522.81
Methanol synthesis
methanol
3002015
Methanol to olefins
methanol_to_olefins
1 0002063.7

Flight categories, Germany Published

Three German categories where France has eight. The French rows are the DGAC's route geography — Paris, province and Outre-mer — and Germany has neither an Outre-mer nor a single dominant hub: Frankfurt and Munich are two, and Berlin a third with a different profile. The German set is the one JRC-IDEES-2021 resolves and the one that matters for emissions: domestic, intra-European, intercontinental. pax_2023 and pkt_2023 are 2019 values, for the same Covid reason as the rest of the transport block, and are on a departing-flight basis: 23.2 million passengers on German domestic flights, 63.1 million on intra-European and 38.5 million intercontinental. Average one-way distances follow at 490, 1 223 and 4 610 km. Because game_row points at rows whose unit consumption is IDEES's own, a German ticket is priced on the model's own physics: 0.72 kWh per passenger-kilometre domestic, 0.37 intra-European, 0.39 intercontinental. Those are two to four times the French figures in the same table, and the German ones are the physical values — the French rows carry a halved intensity against a doubled traffic, as the passenger table explains. A German player will therefore see a long-haul return cost roughly twice as much carbon as a French player sees for the same distance, and the German number is the right one.

Rowpax_2023pkt_2023game_row
Within Germany
domestic
23.22511.39aviation_domestic
Germany ↔ Europe
intra_european
63.10177.195aviation_overseas
Germany ↔ long haul
intercontinental
38.491177.436aviation_international

The rest of industry — energy and process emissions, Germany Provisional

The manufacturing branches the game does not model as value chains, grouped so the published efficiency and waste-heat studies map onto them. Energy is output times unit consumption, so it is bilinear in the two levers and four corners reproduce every combination exactly. Only one of the four corners is German data. e00 — observed 2019, German. Final energy by branch and carrier from JRC-IDEES-2021, on the Eurostat energy-use perimeter, which excludes the naphtha and gas that enter the chemical industry as feedstock — that is charged through industry_chain instead. 370.5 TWh in total, 2.1 times France's 173.9. The process rows are megatonnes of CO₂, not TWh. The France check is the reason to trust the perimeter and distrust the grouping: run the identical extraction on France and the five groups sum to 173.3 TWh against the 173.9 the French model carries — 0.4 % — while individual groups are out by up to a factor two, because IDEES and the French manufacturing survey draw the branch boundaries differently. Worst: "other industries" 0.54, chemicals 1.26, paper 1.25. Two group definitions differ from France and must be said out loud. minerals is the non-metallic minerals branch minus the cement subsector, which the game models as a chain; the France check on that construction is 0.97, so it is sound. chemicals_other is the chemical industry minus the whole "basic chemicals" subsector, which removes more than the ammonia and olefin chains the game models — chlorine, soda, methanol and fertilisers go with it — so this row is a lower bound. The France check on that construction is 1.26, i.e. it under-counts by a quarter, and the German row probably does the same. metals_machinery is non-ferrous metals plus machinery plus transport equipment; iron and steel is excluded because it is a chain. e10 = e00, and the volume lever does nothing in Germany. France's otherIndustryVolume is a national reindustrialisation scenario — textiles ×8.5, electronics ×3.1, naval and aerospace ×0.56 — with no German counterpart and no honest way to synthesise one. The German output index is therefore 1 at both ends, the lever moves nothing, and that is stated rather than hidden behind a fabricated trajectory. The interface should relabel or hide it for Germany. e01 and e11 — German structure, French process assumptions. e01 is the French 2045 process vector expressed as a fraction of the French branch's observed energy and applied to the German branch's observed energy. Scaling carrier by carrier instead would break wherever a carrier is zero today and non-zero at the horizon, which is the case for biomass and hydrogen in four of the five branches. e11 = e01 × (e10/e00) = e01, since e10 = e00. What that transfers is "at the horizon this branch runs on these carriers in these proportions and at this intensity relative to today"; only the industrial structure is German. It behaves: German e01 is 427.8 TWh against e00's 370.5, a ratio of 1.155, and the French pair gives 1.164. What would close it: a German industrial decarbonisation scenario with a branch-and-carrier resolution — the Ariadne scenarios, Agora Industrie's Klimaneutrales Deutschland, or the industry module of the Projektionsbericht.

  • JRC-IDEES-2021, Germany, Industry module: the eleven branch sheets and NMM_fec / CHI_fec, 2019 — Branch totals from 'by fuel (EUROSTAT DATA)'; the cement and basic-chemicals subsectors are subtracted with their own carrier split, read from the *_fec sheets and checked against the subsector total. Process CO₂ from 'CO2 emissions (kt CO2) / process emissions'. Extracted by extract/extract_industry.py.
  • countries/FR/FR.yaml, industry_other — the e01 carrier vector, carried as a ratio — The horizon corners are French process assumptions on German structure. Listed in NOTES.md under Placeholders.
Rowgroupcarriere00e10e01e11
Metals and machinery — coal
metals_machinery__coal
metals_machinerycoal2.45392.453900
Metals and machinery — oil
metals_machinery__oil
metals_machineryoil3.27943.279400
Metals and machinery — gas
metals_machinery__gas
metals_machinerygas40.940240.940237.265737.2657
Metals and machinery — biomass
metals_machinery__biomass
metals_machinerybiomass0.81520.81522.77022.7702
Metals and machinery — electricity
metals_machinery__electricity
metals_machineryelectricity65.17665.176153.694153.694
Metals and machinery — hydrogen
metals_machinery__hydrogen
metals_machineryhydrogen000.06060.0606
Metals and machinery — steam
metals_machinery__steam
metals_machinerysteam6.50976.50971.13181.1318
Minerals and building materials — coal
minerals__coal
mineralscoal9.93479.934700
Minerals and building materials — oil
minerals__oil
mineralsoil2.49462.494600
Minerals and building materials — gas
minerals__gas
mineralsgas19.414519.414516.916716.9167
Minerals and building materials — biomass
minerals__biomass
mineralsbiomass8.21758.217500
Minerals and building materials — electricity
minerals__electricity
mineralselectricity10.023510.023523.76323.763
Minerals and building materials — hydrogen
minerals__hydrogen
mineralshydrogen000.11080.1108
Minerals and building materials — process
minerals__process
mineralsprocess3.89063.89063.79643.7964
Chemicals, other — coal
chemicals_other__coal
chemicals_othercoal1.32151.321500
Chemicals, other — oil
chemicals_other__oil
chemicals_otheroil3.27063.270600
Chemicals, other — gas
chemicals_other__gas
chemicals_othergas21.502221.50222.82392.8239
Chemicals, other — biomass
chemicals_other__biomass
chemicals_otherbiomass1.10991.10990.8790.879
Chemicals, other — electricity
chemicals_other__electricity
chemicals_otherelectricity14.444414.444441.950641.9506
Chemicals, other — hydrogen
chemicals_other__hydrogen
chemicals_otherhydrogen004.23884.2388
Chemicals, other — steam
chemicals_other__steam
chemicals_othersteam9.73899.73897.1417.141
Chemicals, other — process
chemicals_other__process
chemicals_otherprocess0.44670.446700
Paper and board — coal
paper__coal
papercoal2.99362.993600
Paper and board — oil
paper__oil
paperoil0.4570.45700
Paper and board — gas
paper__gas
papergas21.802621.802612.759412.7594
Paper and board — biomass
paper__biomass
paperbiomass9.7189.71824.58124.581
Paper and board — electricity
paper__electricity
paperelectricity19.78819.78823.090923.0909
Paper and board — steam
paper__steam
papersteam7.44477.44477.0317.031
Other industries — coal
other_industries__coal
other_industriescoal1.18861.188600
Other industries — oil
other_industries__oil
other_industriesoil17.882317.882300
Other industries — gas
other_industries__gas
other_industriesgas20.415920.41595.2875.287
Other industries — biomass
other_industries__biomass
other_industriesbiomass15.459215.45922.98162.9816
Other industries — electricity
other_industries__electricity
other_industrieselectricity30.05430.05458.841858.8418
Other industries — steam
other_industries__steam
other_industriessteam2.65282.65280.51430.5143

Building energy by usage, Germany Published

Final energy by usage and carrier, other than space heating. Residential is Eurostat's disaggregated household survey for 2023 — the same instrument for every Member State — and tertiary is JRC-IDEES-2021 for 2021, because no harmonised source covers the service sector by end use at all. The residential half is the best-verified block in this package: run the same Eurostat call on France and every cell lands within 6 % of the value the French model carries from CEREN — hot water electricity 1.01, gas 1.06, oil 0.87, wood 0.94, heat 0.99; cooking electricity 0.97; cooling 0.94; specific electricity 0.98. Cooking gas alone is out, because the French table folds bottled LPG into gas; taken together the two agree to 5 %. The tertiary half is not. On the same comparison, hot water lands at 1.015 and specific electricity at 1.035 — both fine — while catering is out by a factor 2.2 and cooling by a factor 4.6. IDEES's "catering" block is wider than the French "cuisson tertiaire", and CEREN's tertiary air conditioning counts a whole cooling system where IDEES counts the service. So cooking_tertiary is probably over-stated by about a factor of two and cooling_tertiary under-stated by about a factor of four. Both are stated rather than corrected: correcting them with a French ratio would put French structure into a German table. other_tertiary is all zeros. It is not an omission: IDEES's tertiary end-use tree is exhaustive — space heating, cooling, hot water, catering and specific electricity sum to the Eurostat total — so there is no residual category to fill it with. France's row carries 10.7 TWh of CEREN's "autres usages", which IDEES distributes over the other four. Excluded, and worth saying: 9.37 TWh of solar thermal and ambient heat in German household hot water, and 0.35 TWh of solar thermal in the tertiary sector. The French table excludes heat-pump heat on the same reasoning — counting the harvested heat beside the electricity that harvests it would count the energy twice — and 1.06 TWh of household cooking energy that Eurostat attributes to renewables and no carrier column here can hold.

Rowusagesegmentelectricitygasliquidwoodheat
Hot water, residential
dhw_residential
dhwresidential14.9747.81187.623.82
Hot water, tertiary
dhw_tertiary
dhwtertiary4.8718.134.9801.81
Cooking, residential
cooking_residential
cookingresidential40.191.04000
Catering, tertiary
cooking_tertiary
cookingtertiary11.6728.481.360.070
Air conditioning, residential
cooling_residential
coolingresidential1.310000
Air conditioning, tertiary
cooling_tertiary
coolingtertiary5.230.08000
Specific electricity, residential
specific_residential
specificresidential62.50000
Specific electricity, tertiary
specific_tertiary
specifictertiary99.920000
Other uses, tertiary
other_tertiary
othertertiary00000

German electricity mixes at the horizon Provisional

Six mixes. The first three are the Netzentwicklungsplan Strom 2037/2045 (version 2025, second draft) scenarios A, B and C for 2045, ordered along an electrification axis: A is low electrification with high hydrogen import, B follows the statutory renewables build path and is the default, C is high electrification with large domestic electrolysis. All three are read directly from the report and their shares are arithmetic on its own generation table. The last three are built from the ENTSO-E / ENTSOG TYNDP 2024 capacity trajectories for the DE00 node, and they are provisional for three reasons that the labels state rather than hide. They are not named scenarios. The TYNDP methodology report is explicit that LOW and HIGH are the bounds the capacity-expansion model works between — "low trajectory corresponds as starting capacity and expansion can be possible till high trajectory" — not per-scenario results. The per-scenario German results live in the TYNDP scenario datasets, which were not available here, so these rows are labelled by trajectory and horizon. Calling the low-2050 row "Distributed Energy" would be false. The horizon is not 2045. TYNDP's horizons are 2030 / 2035 / 2040 / 2050; National Trends+ stops at 2040 and only the deviation scenarios reach 2050. Two of the three rows are 2050 and one is 2040. Offshore wind is the single exception — sheet 1.3. does publish a DE00 2045 column, 71 748 MW — and it is recorded below. Only the wind and solar capacities are TYNDP's. Hydro, bioenergy and the hydrogen peaking fleet are held at their NEP scenario-B 2045 German values, because those three fleets are close to fixed in every German scenario — 4.6 GW of hydro, 3 GW of biomass, and a peaking fleet that runs a few hundred hours a year. Holding them is a much smaller assumption than inventing them. Capacities become generation with the NEP's own 2045 full-load hours, which is what keeps the six rows on one basis. Two splits the sources do not make are made here and declared. Solar is split between ground and rooftop: the three NEP rows halve it, because the report describes a regional pattern without giving a number; the three TYNDP rows use the rooftop share sheet 1.1. publishes for DE00 — 52.96 % in 2040 and 52.58 % in 2050 — which is better and should replace the 50/50 convention in the NEP rows as soon as the Marktstammdatenregister shares are read. Offshore wind is put entirely on the fixed-bottom row: German offshore is North Sea and Baltic, both shallow, and no floating capacity is in any German scenario. That one is a fact, not a convention. hydro is run-of-river plus reservoir and excludes pumped storage, which is a store rather than a source. bioenergy is biomass plus the waste-to-energy line. gas_turbine carries the hydrogen-fired peaking fleet. combined_cycle carries only the 0.5 TWh of "sonstige Konventionelle": natural gas is exactly zero in every 2045 NEP scenario, which is worth seeing rather than rounding away.

Rowscenario_indexnuclearpv_groundpv_roofwind_onshorewind_offshore_fixedwind_offshore_floatinghydrobioenergygas_turbinecombined_cycle
NEP A 2045 — low electrification, high hydrogen import
m0
100.1519630.1519630.4066430.22067100.0191470.0159740.0331110.000529
NEP B 2045 — the statutory build path
m1
200.1661470.1661470.3837590.2251800.0161160.0131780.0290270.000445
NEP C 2045 — high electrification, high domestic electrolysis
m23
300.1726750.1726750.3941420.20605800.015070.0122390.0267260.000416
TYNDP 2024 — 2040, best-estimate renewables trajectory
n1
400.1502070.1690770.4002790.21870700.0169290.0138420.0304910.000468
TYNDP 2024 — 2050, low renewables trajectory
n2
500.157040.1741060.3851020.22519200.016060.0131320.0289260.000444
TYNDP 2024 — 2050, high renewables trajectory
n03
600.16960.1880310.3897950.20270200.0136770.0111840.0246340.000378

Generation technologies, German load factors Provisional

German: the load_factor column. Every one is the NEP's own 2045 generation divided by its own 2045 installed capacity, in scenario B. Doing it that way rather than quoting a resource statistic keeps the mix and the load factors internally consistent — they come from the same run. Three are worth arguing about. German onshore wind at 0.3075 is far above today's fleet, roughly 0.20, and encodes the NEP's assumption of repowering to taller machines; a reader who thinks that optimistic should say so rather than be surprised by it. German PV at 0.1065 is below the French 0.14, which is latitude, and is the clearest single reason a German pathway needs more installed capacity per kilowatt-hour than a French one. German hydro at 0.4492 is above the French 0.295 because German hydro is overwhelmingly run-of-river on the Rhine, Danube and Inn rather than reservoir. The thermal load factor of 0.0452 is what makes the German 2045 system legible: 83.5 GW of firm capacity running 396 hours a year. France's 0.114 describes a different machine. nuclear keeps 0.75 and is never read: its share is 0.0 in all six mixes. wind_offshore_floating keeps the fixed-bottom figure for the same reason. bioenergy is derived from the biomass capacity alone, 9.0 TWh over 3.0 GW; the waste-to-energy line is in the bioenergy share but has no separate capacity in the NEP table, so this factor understates its own hours by about 60 %. Stated rather than silently averaged. PLACEHOLDER — French values carried, not German data: the lifetime, capital cost, operating cost and eight material columns. They are technology rather than national resource, which is why the porting checklist says they can be carried, and they are still French: German capital costs for offshore wind and grid connection differ from French ones, and the material intensities come from a French scenario workbook. What would close it: the NEP's own cost annex, or the Fraunhofer ISE Stromgestehungskosten study, which publishes German CAPEX and full-load hours by technology and is updated every two years.

  • NEP kompakt, Tabelle 1 p.4 and Abbildung 4 p.8, scenario B 2045 — PV 373.2 TWh / 400.0 GW = 933 h → 0.10651. Onshore 431.0 / 160.0 = 2 694 h → 0.30750. Offshore 252.9 / 70.0 = 3 613 h → 0.41243 (the report separately quotes about 3 900 full-load hours after offshore optimisation, p.11). Hydro (16.1 + 2.0) / 4.6 = 3 935 h → 0.44917. Biomass 9.0 / 3.0 = 3 000 h → 0.34247. Thermal (32.6 hydrogen + 0.5 other) / 83.5 = 396 h → 0.04525.
  • countries/FR/FR.yaml, generation_technology — the cost, lifetime and material columns, carried unchanged — Not German values. Listed in NOTES.md under Placeholders.
Rowrenewableload_factorthermal_efficiencyfuel_carrierhydrogen_capablelifetimecapex_per_kwopex_per_kw_yearsteelconcretealuminiumcopperlithiumcobaltnickelrare_earth
Nuclear
nuclear
00.750none06011 900100675330.351.61.5e-073.8e-0502.3e-05
Solar PV, ground
pv_ground
10.106510none0257471128.470635.137317.43.19.37e-070.0003202.2235e-05
Solar PV, rooftop
pv_roof
10.106510none0257471116.176528.8627123.18.7e-070.00031396201.9765e-05
Wind, onshore
wind_onshore
10.30750none0251 300402004500.692.67.1e-063.4e-0504.2e-05
Wind, offshore fixed
wind_offshore_fixed
10.412430none0202 6008025091018.58.1e-063.65e-0500.106674
Wind, offshore floating
wind_offshore_floating
10.412430none0202 600804801 7001.158.558.55e-064.8e-0500.106676
Hydro
hydro
10.449170none0701 0001598210.520.181.9e-070.0001409e-05
Bioenergy
bioenergy
10.342470.25gas0253 000120573.50.0590.127.2e-075.4e-0505.4e-06
Hydrogen peaking plant
gas_turbine
00.045250none025800486.3410.750.791.5e-087.2e-0606.4e-06
Combined cycle
combined_cycle
00.045250.6gas1301 1004829361.11.23.6e-080.001802e-05

Vehicle production and material intensity, Germany Provisional

PLACEHOLDER — French values carried, not German data: production_2050 and electric_share are the output of a French 2050 scenario, and there is no German twin. This is the worst placeholder in the package by magnitude: Germany is the largest vehicle producer in Europe and built roughly four times France's cars in the base year, so the German satellite material account is understated by about that factor. The battery_kwh, steel and aluminium columns are technology and travel; electric_share is overridden by the player's own electrification levers for cars and trucks, so only the production volumes and the four unlevered rows are affected. What would close it: the VDA Jahresbericht for observed production by category, and a German 2045 industrial scenario for the forward number. If no such scenario exists the satellite account should be run at today's German production and labelled as such — which is a better answer than this one and needs only the VDA series.

  • countries/FR/FR.yaml, vehicle_type — carried unchanged — Not German values. Listed in NOTES.md under Placeholders.
Rowproduction_2050battery_kwhelectric_sharesteelaluminium
Car
car
2 500 004450.99951 111130
Utility vehicle
van
500 004800.99599052
Bus and coach
bus
15 7834000.94316 7851 670
Truck
truck
55 0051 0000.98 738351
Motorcycle
motorcycle
220 00714122226
Moped
moped
110 0028122226
Bicycle
bicycle
15 701 8790.5168

Battery material intensity by chemistry Workbook

Tonnes per MWh of battery. The two the model blends are the two credible 2050 options; the source also documents NMC 333, NCA and LTO.

  • Offre_et_demande.xlsx, "Matériaux transports" sheet rows 19-28
Rowsteelaluminiumcopperlithiumcobaltnickel
NMC 811
nmc_811
1.911.80.1110.0270.75
LFP
lfp
21.31.60.496.8e-060.03

Hydrogen production routes Published

Per MWh of hydrogen produced. methane is the feedstock and fuel together, which is how a reformer is measured; carbon_captured is the share of the carbon in that methane that ends up underground rather than in the air. Electrolysis has no methane, and its electricity column is zero because the figure is derived in the equations from the conversion efficiency the rest of the model uses — declaring it here as well would be two copies of one number. The reformer figures come from the constants the cost layer already used and nothing else did: 3.33 t of methane and 9.23 tCO2 per tonne of hydrogen, converted at the lower heating values declared beside them.

Rowmethaneelectricitycarbon_captured
Electrolysis
electrolysis
000
Steam methane reforming
smr
1.390.01740
Autothermal reforming + capture
atr_ccs
1.450.030.94

The land of Germany Published

The land survey of 31 December 2023, whole territory, one nomenclature (ALKIS), published national total 35 768 293 ha. The seven classes are aggregated from it: arable and perm_crops are the farm survey's Ackerland and Dauerkulturen, forest is Wald, other_natural is Gehölz, Heide, Moor, Sumpf and Unland together, water is Gewässer, artificial is Siedlung plus Verkehr, and grassland is the residual of the survey's own agricultural class once arable land and permanent crops are taken out. The seven add up to the published total to the hectare, which is what the account's closure is asserted on. Two reconciliations to know before quoting any of them. The survey's agricultural class is 1.42 Mha wider than the farm survey's utilised agricultural area — non-farm grassland, paddocks, airfield margins, small parcels — so the livestock block grazes the farm survey's 4.714 Mha instead and grassland_rough is negative, −1.42 Mha. France's is positive for the mirror-image reason. And the forest flow model runs on the forest inventory's 10.8 Mha of Holzboden, not on this class's 10.689, because the two are different perimeters. peat_area and peat_ef are the German headline. 1.945 704 Mha of drained organic soil, from the inventory's own organic-soil table, split across five of the seven classes: cropland 339 484 ha, grassland 1 013 791 strict plus 48 044 woody, forest 284 637, wetlands and water 132 019 + 28 342 + 10 544 for peat extraction, and settlements 88 843. The forest research institute's independent mapping gives 1.93 Mha, or 1.87 without deeply covered peat, which is the same number. The factors are the land-use share of the inventory's own published pools — the agricultural nitrous oxide of the same soil is peat_agri_n2o_ef and is booked in agriculture — and they run from 11.6 tCO₂e a hectare under forest to 28.0 under arable land. Permanent crops and semi-natural land carry zero because the inventory maps no organic soil under them; land_peat_unbooked asserts that nothing was lost that way. soil_carbon_stock is tC/ha over 0–30 cm and no equation reads it. Arable 61 and permanent grassland 88 are the national soil inventory's own means for mineral soils; forest 81 is the fourth forest inventory's 936 Mt of carbon in litter and mineral soil over 11.5 Mha, on a 0–90 cm depth rather than 0–30, which is stated because it is not comparable with the other two. Permanent crops and semi-natural land carry the arable and grassland figures for want of their own — the soil inventory's special-crop sampling error is ±29 % — artificial land carries 30, and water zero.

Rowarea_2023soil_carbon_stockpeat_areapeat_ef
Arable land
arable
11.6564610.33948428.04
Permanent grassland
grassland
6.13454881.0618427.056
Vines and orchards
perm_crops
0.19826100
Forest
forest
10.6886810.28463711.636
Heath, bog, scrub and bare ground
other_natural
1.058378800
Water and wetlands
water
0.82480900.17090521.942
Artificialised
artificial
5.20738300.08884318.322

Climate cases for the German forest Provisional

Assembled, because Germany publishes no climate grid for its forest. France reads the three cases its own forest-sector projection defines; nothing equivalent exists here, so these three are built from three different sources and declared provisional together. C1 is the official base projection: the wood-availability model holds the area constant over 2023–2062, keeps the stock near 3.6 Gm³ and starts its increment 6 % below the inventory before recovering — so production 1.00 and mortality 1.0, a forest whose growth has not changed. C2 continues the decade the inventory measured: gross increment fell 16 % between the 2002–2012 and 2012–2022 periods and mortality rose by half. C3 is bounded by the source case of the national projection report's forest modelling, which puts 2045 living biomass between a sink of 31.8 and a source of 10.6 MtCO₂e. Two cautions. The German environment agency's own climate-sensitive forest modelling finds that using averaged rather than annual climate series overstates the sink by 13 to 14 Mt a year, so every case here is on the optimistic side of an annual-series model. And the second column is a multiplier on a mortality that already contains the 2018–2020 bark-beetle catastrophe, so C3 is a very severe case indeed.

Rowpositionproduction_factormortality_factor
C1 — WEHAM growth
c1
111
C2 — the drought decade continued
c2
20.851.5
C3 — unfavourable climate
c3
30.752

The German herd Derived

The November 2024 livestock survey, with the poultry places of the 2023 farm-structure census: 10.5 million cattle of which 3.6 million dairy cows and about 0.62 million suckler cows, 21.2 million pigs, 167.3 million poultry places and 1.66 million sheep and goats. Germany's herd is a quarter smaller than France's in cattle and three times larger in pigs, and the suckler herd is a sixth of the French one — which is why dairy_beef_coupling_share is 0.80 here and 0.40 there. emission_factor is calibrated and manure_ch4_share is derived. The methane per head is the inventory's own implied factor — a dairy cow emits 142.8 kg of enteric and 24.2 kg of manure methane a year, other cattle 47.5 and 7.8, a pig 1.19 and 4.1 — which over this herd gives 32.0 MtCO₂e against the published 32.07 of enteric plus manure methane, a cross-check that costs nothing. The remaining 2.88 MtCO₂e of manure nitrous oxide is spread across the six categories by nitrogen excretion, and the six factors together reproduce the published 34.915. manure_ch4_share is then the manure part of each factor, methane and nitrous oxide together, because that is what the equation multiplies. Three weaknesses to name. The suckler-cow enteric factor is not printed separately in the inventory and 95 kg is an interpolation between the published dairy and other-cattle factors — not verified. Goats are not in the annual survey and about 0.15 million is the 2020 census figure, also not verified. And German horses — 1.2 million of them, 21.7 kt of enteric methane — have no row in this table at all, so their 0.6 MtCO₂e is inside the calibrated factors of the six categories that do. grassland_ha_per_head is calibrated so the herd's grassland requirement closes on the farm survey's 4.714 Mha of permanent grassland, keeping the French ratios between the categories: a cow 0.572 ha, other cattle 0.343, a sheep or goat 0.086. Pigs and poultry graze nothing.

Rowspecies_groupheads_2024emission_factorenteric_mitigablemanure_ch4_sharemanure_n_2024grassland_ha_per_head
Dairy cows
dairy_cow
cattle3.64 977.7710.1967399.9840.572296
Suckler cows
suckler_cow
cattle0.623 083.1910.137345.4690.572296
Other cattle
other_cattle
cattle6.281 657.710.1977252.7330.343377
Pigs
pig
pig21.2179.24300.8141242.9310
Poultry
poultry
poultry167.32.4552901101.2220
Sheep and goats
small_ruminant
small_ruminant1.66278.51800.135418.2610.085844

German animal products, and where they go Published

The 2024 meat supply balance, in thousand tonnes of carcass weight, and the 2024 milk balance in milk equivalent. Consumption is Verbrauch — what the balance divides by the population — not Verzehr, which is what reaches a plate and is a quarter smaller. export_base is a net figure and the published exports are gross. Germany trades in both directions on every product and also trades live animals: the balance closes as production = consumption × (1 − import share) + exports − net live imports, and this table folds the live-animal term into the export volume so that the identity the base year is checked on closes exactly. Pork is the clearest case: 2 965.1 kt consumed at a 33.0 % import share plus the published 2 304.2 kt of exports less 281.6 kt of net live imports is the 4 007.7 kt produced, and the column below carries 2 021.1. The gross export volumes are in the source detail. The milk row is a labelled placeholder. Production is published — 33.8 Mt of cow milk in 2024, 93.1 % of it delivered to dairies — and the milk-equivalent consumption and trade split are not: the supply balance in milk equivalent was not found, and the report that would carry it returned a dead link. The consumption here is production over a self-sufficiency of 1.20, which is a rounded reading of the four ratios the dairy report does publish (drinking milk 106 %, butter 111.5 %, cheese 125 %, dried products 134.5 %), and the import share of 0.30 is an assumption. Nothing in the base year depends on them — the dairy herd is production over yield, and both are published — but the response of the German dairy herd to the diet lever does. What would close it: the BLE supply balance for milk in milk equivalent. waste_share is the French per-product chain synthesis carried across: beef, pork and sheep 8.8 %, poultry 19.1 %, milk 10.8 %. Germany measures its food waste as a national tonnage and not by product family.

  • BLE, Versorgungsbilanz Fleisch 2010–2025, sheet 2024 — kt carcass weight, 2024 — pork: production 4 007.7, consumption 2 965.1, imports 980.0 (live 355.1 in, 73.5 out), gross exports 2 304.2, self-sufficiency 135 %. Beef and veal: 1 048.6, 989.3, 536.1 (5.6 / 38.6), 562.4, 106 %. Poultry: 1 704.8, 1 741.4, 1 066.7 (112.4 / 288.7), 853.9, 98 %. Sheep and goat: 26.2, 58.8, 47.2 (3.7 / 0.2), 18.1, 44.5 %. Per head: 35.5, 11.8, 20.9, 0.70 kg. Population 83.51 M at 30.06.2024.
  • BLE, Bericht Milch 2026 — Cow-milk production 34.0 Mt in 2025, 33.8 Mt in 2024; 93.1 % delivered. Self-sufficiency 2025: drinking milk 106 %, butter 111.5 %, cheese 125 %, dried products 134.5 %. The Versorgungsbilanz Milch in Milchäquivalent was not found; bmel-statistik.de returned 404.
  • countries/FR/FR.yaml, animal_product — the waste_share column is carried from the French chain syntheses
Rowspeciesconsumption_baseper_capita_2024import_shareexport_baseproduction_2024waste_share
Beef and veal
beef
suckler_cow989.311.80.542595.5011 048.60.088
Pork
pork
pig2 965.135.50.332 021.084 007.70.088
Sheep meat
sheep
small_ruminant58.80.70.80314.61626.20.088
Poultry
poultry
poultry1 741.420.90.6131 030.881 704.80.191
Cow milk
milk
dairy_cow28 166.7337.30.314 083.333 8000.108

Scoreboard bands, Germany Game rule

Three bands are German measurements — the three bioenergy ones. Four are rules with a statutory or published anchor named. One, the peak, is a judgement, and it is the weakest row in the table because the constant it scores is itself the weakest constant in the package. The emission bands. total is the only band in this game whose lower edge comes from statute rather than from playtesting: the Klimaschutzgesetz requires net greenhouse-gas neutrality in 2045 (§3) and gives that meaning through §3a, where the LULUCF balance must reach at least -40 MtCO₂e. A German pathway that leaves 40 MtCO₂e of gross emissions is therefore exactly balanced by the land sink the law demands, with no engineered removal at all. warning at 80 allows an equal amount again to be met by capture and storage; Germany has a Carbon Management Strategy and a CCS bill but no statutory removal volume, so 80 is a judgement and is declared as one. For scale, the UBA's own projection leaves 212.5 MtCO₂e gross in 2045. The three sector bands are the French bands rescaled by the ratio of the two total bands — 40/15 on the target edge and 80/30 on the limit — and rounded: transport 4 → 10 and 10 → 27, buildings 3 → 8 and 7 → 19, industry 10 → 27 and 15 → 40. That keeps the German game as hard as the French one relative to its own national target, which is the only defensible thing to do while Germany publishes no sector figure, and the interface must say so as bluntly as it is said here. The industry band deserves the most scepticism of the three: German industry is not a scaled-up French industry. It carries 26.4 Mt of blast-furnace steel against France's 9.9 and emitted 149.8 MtCO₂e in 2024 against France's 61.6, so a band derived by a single national ratio will be wrong in a structured way rather than a random one. The bioenergy bands are measurements, and they use one rule. Good is JRC ENSPRESO's low-mobilisation German potential for 2050 and warning its medium one. That rule is calibrated, not asserted: applied to France it gives 66 / 170 TWh of digestible biomass against the 70 / 150 the French file carries as a game rule, so the rule reproduces the French band it replaces. biomass — German forestry potential, 110 TWh low and 197 medium. For scale, Germany already consumes 149 TWh of primary solid biofuel, between the two, and the forest sink has been shrinking. biofuel — German liquid energy crops, 40 TWh low and 44 high; the medium scenario is identical to the low one, so the high is used for the warning edge and the band is genuinely narrow. Germany consumed 38 TWh of liquid biofuel in 2023, just under the target edge. biogas — German digestible feedstock, 71 TWh low and 127 medium. The German national study says something close on a narrower definition: dena puts the exploitable biomethane from waste and residues above 50 TWh, against roughly 100 TWh that German biogas plants already produce and consume locally without feeding the grid. ENSPRESO is used rather than dena so that all three bioenergy bands come from one rule and one assessment — in Germany they compete for one pile of material, and three bands from three sources would not be mutually consistent. The peak band is a judgement. NEP scenario B 2045 has 13.3 million heat pumps and 31.2 TWh of network power-to-heat behind a thermal peaking fleet of 83.5 GW. 30 GW as a target and 45 GW as a limit are a reading of that, not a published adequacy figure, and they score a constant — building_peak_2020 = 13.9 GW — that is itself derived from a French coefficient. What would close it: the Bundesnetzagentur Leistungsbilanz, the ENTSO-E ERAA, or the load chapter of the NEP main report. agriculture is declared and is not scored here. This edition switches the land and food module off (land_module_active: 0), so the three agriculture rows of the post table are present and empty by construction and there is nothing on the game perimeter to score; the scoreboard leaves the line out rather than printing a free green zero. The band is declared anyway so the table has the same shape in every edition and a future port has a slot to fill: good 55 is the UBA projection's own 2045 agriculture figure of 54.8 MtCO₂e rounded, and warning 82 is 1.5 times that — the ratio this file falls back on wherever no second published edge exists. Both are a rule until Germany carries the module. sink is the statute again, added in 0.26.0: KSG §3a's −40 MtCO₂e of LULUCF balance in 2045, the same figure the total band is argued from, scored against the land sink as a magnitude. The line exists because the net line is hinged at zero and stops charging a scenario for leaning on the land the moment it crosses; the French file gives the full argument. The statute is used rather than the UBA projection (official_natural_sink_2050, +26, a source) because scoring a player against a with-existing-measures projection scores them against failure. In Germany the line is inert: the land account is a source, so there is no reliance to charge, and a country whose land emits cannot lean on it. warning 60 is a teaching rule with no German anchor above the statute, and it is declared as one. techsink is the UBA's projection, 6.2 MtCO₂e in 2045, added in 0.31.0 (official_technological_sink_2050). Germany has no statutory volume of engineered removals, so unlike the land line there is no law to prefer to the projection. It is scored the way the net line is, against gross emissions: a megatonne of engineered removal beyond it costs exactly what it buys on the net line. warning 20 is the slider's flag.

Rowgoodwarning
Total emissions, game perimeter
total
4080
Transport emissions
transport
1027
Building emissions
building
819
Industry emissions
industry
2740
Agriculture emissions
agriculture
5582
Winter electricity peak
peak
3045
Biogas
biogas
71127
Biofuels
biofuel
4044
Wood energy
biomass
110197
Land sink reliance
sink
4060
Engineered removals
techsink
6.220

Contested assumptions, Germany Game rule

A model that shows its sources still hides which of them are argued over. This table names them. weight is how much the answer moves: high means a reasonable person taking the other side gets a materially different result. Four of the eight are German versions of French arguments; four are arguments France does not have.

Rowtopicweightpositioncontestedsettles_it
Is German 2045 methane really biogenic?
gas_factor
emission factorshigh175 gCO₂/kWh, a blend of 25 % biomethane at 25 g with 75 % fossil gas at 227. France declares 25 g, assuming all of it is biomethane.Germany produced 12.3 TWh of biomethane in 2025 against a gas system of about 864 TWh, and dena puts the domestic residue potential above 50 TWh against a 2045 demand case of 200. The 25 % is that arithmetic. Whoever thinks Germany will import synthetic or biogenic methane at scale should move the slider and say where from — this is the single assumption that most separates the German board from the French one.A German 2045 gas balance that says how much methane is left and where it comes from. The Projektionsbericht has the demand; nobody has published the supply side at that horizon.
German land emits, and the law says it must absorb 40 Mt
land_sink_sign
carbon sinkshighThe sink is computed, not chosen: seven land classes, six inventory pools and a forest identity in cubic metres give a net source of 57.8 MtCO₂e at the base year and 56.3 at the reference.German LULUCF has been a net source in every year since 1990: +36.5 Mt then, +57.8 in 2024, +26.9 in the 2025 estimate. KSG paragraph 3a requires at least −40 Mt by 2045. That is a swing of about 97 Mt in twenty years, and this module reaches −19 at best — every land lever at its far end, including rewetting all 1.95 Mha of drained peat. The law is not reachable inside this game, and that is a finding rather than a defect of the sliders.The 2024 pool split of the 2026 inventory submission, which would replace the +9.4 MtCO₂e that this package has to calibrate on the forest pool; and a rewetting programme with a measured carbon balance. The first exists and could not be downloaded; the second barely exists.
Rewetting the bogs is the biggest single move on German land
peat_rewetting
land usehigh1.945 Mha of drained organic soil emit about 50 MtCO₂e a year — 8% of the German total. The slider starts at 0% rewetted and reaches about 40 MtCO₂e a year at 100%.Three things about that number are arguable. **What a wet hectare still emits** is taken as 5 tCO₂e a year, mostly methane; a wetter reading would make the lever worth less and a drier one more, and no German national mean was opened. **Whether the land can be bought** is not modelled at all: 1.9 Mha is 11% of German farmland, largely in Lower Saxony and Mecklenburg, and the module takes it out of the grazed grassland without paying anyone. And **the timing**: peat stops oxidising when the water table comes back, but the model books the whole saving at the horizon, which is right for 2045 and wrong for the cumulative budget.A national rewetting programme with hectares, a schedule and a measured carbon balance. The Moorschutzstrategie's own document could not be reached and the hectare targets quoted in secondary pages are not verified here; a paludiculture yield would settle the fodder half.
1.35 million hectares of maize for the gas grid
energy_maize
bioenergymediumThe energy-maize area is a lever of its own, 0 to 1.6 Mha, and it takes arable land: 1.35 Mha is 11.6% of the German arable area and makes 57 TWh of raw biogas, more than half the whole pool.Growing a main crop to feed a digester is the most contested practice in German bioenergy, and this model books only one side of it. The hectares are charged against the food chain and the digestate methane and nitrous oxide are charged at 1.14 tCO₂e a hectare — but the nitrogen the maize needs is not, because the module holds the mineral dose as an intensity on an arable area it does not let the maize grow; nor is the digestate returned to the field counted as a fertiliser input, which cuts the other way. The renewable-energy law caps maize at 30% of a new plant's feedstock, which this slider can exceed.A nitrogen balance for the energy-crop rotation, digestate returns included — the inventory already publishes 302 kt of nitrogen in energy-crop digestates, which this module carries in a residual rather than as an input.
Half the German building stock may not exist
tertiary_floor_area
building stockhigh3 519 Mm² of heated service floor area, from JRC-IDEES-2021.That is 42 m2 per inhabitant against 15.5 in France, and it implies a space-heating intensity of 34 to 44 kWh/m² — two to three times below any German non-residential typology. The energy is Eurostat-consistent and is not in doubt; the area is modelled from employment. The emissions are unaffected, because surface times intensity is right either way. Everything priced per square metre is not.The IWU / Wuppertal Institut Nichtwohngebäude-Bestandsmodell, which is the German non-residential stock model and gives heated floor area by use and by age class.
There is no German sector target to compare against
no_sector_target
accountinghighThe 2045 column is the UBA's projection with existing measures, not a target: 212.5 MtCO₂e gross remaining.The 2024 amendment to the Klimaschutzgesetz replaced the per-sector annual budgets with one national path. France's panel can say "the strategy says X for this sector"; the German panel cannot. What it can say is arguably better — the law requires net zero in 2045 and the government's own projection leaves 212.5 Mt — but it is a different comparison and the interface must not present a projection as a target.Nothing available settles it. It is a choice the Bundestag made, and the honest response is to name the projection as a projection.
366 g/kWh is combustion, not life cycle
electricity_factor_basis
emission factorsmedium366 gCO₂/kWh for the 2020 German mix, against 79 declared for France.The two are not the same measurement. The French figure is life-cycle and the German one is combustion at the stack, so this file understates the German factor by roughly the upstream of coal and gas — of the order of 10 to 15 %, or 400 to 420 g/kWh. The gap between the two countries is therefore larger than the numbers shown, not smaller.UBA CLIMATE CHANGE 13/2025, the current edition of the same series, which carries a life-cycle variant.
The German winter peak is not a heating peak
peak_anchor
system constraintsmedium13.9 GW, derived by applying France's gigawatts-per-terawatt-hour coefficient to the German electric-heating stock.France's 40 GW is electric space heating, which dominates the French winter peak. Germany's stock is 56 % gas and 19 % oil, and what electric heating it has is deliberately off-peak: night-storage heaters charge at night and paragraph 14a EnWG lets the network operator curtail heat pumps. So 13.9 GW is more likely an over-statement than an under-statement, and the whole indicator means less in Germany than in France.The Bundesnetzagentur Leistungsbilanz, or the load chapter of the NEP main report, which gives the coincident load per scenario.
How much German biomass is actually available?
biomass_ceiling
resourcesmediumBands from JRC ENSPRESO for 2050: wood energy 110 / 197 TWh, liquid biofuel 40 / 44, biogas 50 / 100.For the first time these bands are a measurement rather than a game rule — but ENSPRESO's own low and high forestry scenarios differ by a factor of 3.6 for Germany, and its potentials are primary feedstock rather than delivered fuel. Germany already burns 149 TWh of solid biofuel, between the two bands, while the forest sink shrinks. A German wood-energy band that ignores the forest carbon account tells half a story, and the half it omits is going the wrong way.A German resource assessment that closes the loop between the energy use and the LULUCF account — the UBA/DBFZ work behind the 48 to 235 TWh range covers the same feedstock base and would keep the three bioenergy bands mutually consistent.
German industry, French processes
rest_of_industry
accountingmediumThe observed corner is German — 370 TWh across five branch groups — and the three horizon corners apply French process assumptions to it.Two things ride on that. The output lever does nothing in Germany, because France's reindustrialisation scenario has no German twin and inventing one would be worse. And the chemicals group is a lower bound: it removes the whole of basic chemicals, which is more than the two value chains the game models. Against France the same construction under-counts by a quarter.A German industrial decarbonisation scenario resolved by branch and by carrier — the Ariadne scenarios, Agora Industrie's Klimaneutrales Deutschland, or the industry module of the Projektionsbericht.

Emissions and energy posts, Germany Provisional

The constructive account: one row per sub-sector, one column per energy carrier. Sector totals are sums of this table and nothing else, which is what makes a missing sub-sector visible. The row set is the model's, the sector and kind columns are the model's, and the three numeric columns are PLACEHOLDER — French values carried, not German data. Carrying them is more defensible here than anywhere else in this file, and it is still an assumption. ADEME expresses the recoverable waste-heat gisement per unit of fuel burned and RTE the efficiency potential as a percentage, so both are ratios attached to a process rather than stocks attached to a country, and applying them to German fuel gives a German gisement. What is assumed: that a German cement kiln rejects the same fraction of its fuel as recoverable heat as a French one — close to a technology statement — and that German industry has the same identified efficiency headroom, which is not. That second one is a claim about how much has already been done, and German industry has been under an efficiency-agreement regime France has no equivalent of. The eight transport and building rows carry zero, as in France, because the underlying study is industrial. What would close it: the sEEnergies European excess-heat datasets, or a German excess-heat cadastre; and for the ceilings, the Fraunhofer ISI branch potentials behind the Energieeffizienzgesetz.

  • countries/FR/FR.yaml, post — the three numeric columns, carried unchanged — French ratios on German structure. Listed in NOTES.md under Placeholders.
  • ADEME, La chaleur fatale (2017, updated 2021) — The origin of the waste-heat columns. A French study applied to German structure.
Rowsectorkindwaste_heat_sharewaste_heat_hot_shareelec_efficiency_ceiling
Passenger mobility
passenger_mobility
transportmobility000
Freight
freight_mobility
transportmobility000
Residential heating
residential_heating
buildingheat000
Tertiary heating
tertiary_heating
buildingheat000
Residential, other uses
residential_uses
buildingother000
Tertiary, other uses
tertiary_uses
buildingother000
Electricity generation
energy_production
energyother000
Hydrogen production
hydrogen_production
energyother000
Waste to energy
waste_to_energy
energyother000
Steel
steel
industryprocess0.012490.64490.11412
Ammonia
ammonia
industryprocess0.018310.43970.31091
Olefins and plastics
olefins
industryprocess0.018310.43970.31091
Cement
cement
industryprocess0.086760.83540.24128
Food-industry heat
food_heat
industryheat0.016430.32760.25011
Metals and machinery
other_metals
industryother0.061850.5560.15539
Minerals and materials
other_minerals
industryother0.087480.82830.24128
Chemicals, other
other_chemicals
industryother0.018310.43970.31091
Paper and board
other_paper
industryother0.31080.33480.19258
Other industries
other_diverse
industryother0.11130.54120.23636
Livestock
livestock
agricultureprocess000
Crops and soils
crops
agricultureprocess000
Farm and forestry engines
farm_machinery
agricultureother000

Every equation

The complete calculation, in the order it is evaluated. A name in a formula is either a lever, a constant, or another equation in this list; row.x is a field of the row being computed; and sum(table.column, condition) totals a column over the rows that satisfy the condition.

Transport — demand reallocation

Every 2020 service demand is reallocated to the 2050 categories through an explicit matrix. Reading the matrix is the only way to see that, for instance, car demand shifted to rail is then served at the occupancy and unit consumption of a train rather than a car.

NameFormulaUnitNotes and sources
shift_share
per row of passenger_shift
car_to_fuel: carFuel
car_to_gas: carGas
car_to_electric: carElectric
car_to_rail: carRail
aviation_keep: 1 - domesticAviationRail
aviation_to_rail: domesticAviationRail
default: row.share
fraction

Fixed workbook conventions come from the table; the six shares a lever drives are overridden here. The four car shares and the two aviation shares each sum to one by construction of the controls.

aviation_demand_factor(1 + aviationDemandGrowth) ** aviation_demand_horizon_yearsmultiple of 2020 demand

Growth compounded over thirty years. At the default of 0%/year it is exactly 1, which reproduces the workbook: the workbook carries 2020 air traffic straight through to 2050.

demand_2050_before_shift
per row of passenger
row.demand_2020 * (aviation_demand_factor if row.aviation == 1 else 1)Gpkm/y

Only aviation carries a demand trend. Road and rail demand is set by the modal levers, which is where the player's choices act.

passenger_flow
per row of passenger_shift
passenger[row.source].demand_2050_before_shift * (1 - passengerReduction) * row.shift_shareGpkm/y—
passenger_demand
per row of passenger
sum(passenger_shift.passenger_flow, passenger_shift.target == row.id)Gpkm/y—
aviation_efficiency_factor(1 - aviationEfficiency) ** aviation_horizon_yearsfraction of today's consumption

A yearly improvement compounded to 2050. At the default of 0%/year it is exactly 1, which reproduces the workbook: the workbook gives 2050 aviation the same consumption per passenger-kilometre as today.

unit_consumption_2050
per row of passenger
row.unit_consumption * (aviation_efficiency_factor if row.aviation == 1 else 1)MWh per million vehicle-kilometres

Only aviation carries an efficiency trend. Road and rail keep the workbook's 2050 values, in which the shift between vehicle types already does the work.

passenger_energy
per row of passenger
row.passenger_demand * row.unit_consumption_2050 / row.occupancy / 100TWh/y

Unit consumption is per vehicle-kilometre, so dividing by occupancy converts it to passenger-kilometres. The factor 100 carries the unit change from the workbook's mixed units to TWh.

freight_shift_share
per row of freight_shift
truck_to_h2: truckH2
truck_to_thermal: truckThermal
truck_to_electric: truckElectric
truck_to_rail: truckRail
air_to_sea: freightAviationSea
air_keep: 1 - freightAviationSea
default: row.share
fraction—
freight_flow
per row of freight_shift
freight[row.source].demand_2020 * (1 - freightReduction) * row.freight_shift_shareGtkm/y—
freight_demand
per row of freight
sum(freight_shift.freight_flow, freight_shift.target == row.id)Gtkm/y—
freight_energy
per row of freight
row.freight_demand * row.unit_consumption / 100TWh/y—

Transport — energy by vector

Liquid fuel is split between biofuel and e-fuel by the biofuel-share lever, and the e-fuel half is converted back into the electricity needed to make it, at the declared conversion efficiency. Hydrogen is handed on as hydrogen: the posts module converts it through the production mix, like every other consumer's. That is why an electrified transport scenario still shows a large electricity demand even where no vehicle is plugged in.

NameFormulaUnitNotes and sources
passenger_liquidsum(passenger.passenger_energy, passenger.vector == "liquid")TWh/y—
passenger_gassum(passenger.passenger_energy, passenger.vector == "gas")TWh/y—
passenger_electricity_directsum(passenger.passenger_energy, passenger.vector == "electricity")TWh/y—
passenger_hydrogensum(passenger.passenger_energy, passenger.vector == "hydrogen")TWh/y—
freight_liquidsum(freight.freight_energy, freight.vector == "liquid")TWh/y—
freight_gassum(freight.freight_energy, freight.vector == "gas")TWh/y—
freight_electricity_directsum(freight.freight_energy, freight.vector == "electricity")TWh/y—
freight_hydrogensum(freight.freight_energy, freight.vector == "hydrogen")TWh/y—
passenger_biofuelpassenger_liquid * biofuelShareTWh/y—
passenger_electricity_efuelpassenger_liquid * (1 - biofuelShare) / efficiency_electricity_to_efuelTWh/y—
freight_biofuelfreight_liquid * biofuelShareTWh/y—
freight_electricity_efuelfreight_liquid * (1 - biofuelShare) / efficiency_electricity_to_efuelTWh/y—

Building heating

The stock says how much heat the country needs and anchors the winter peak. What covers that heat is set by target: so many TWh of wood, such a share of the need on electricity, and that electric heat split across five technologies with genuinely different efficiencies — in season and, which is what the peak cares about, on the coldest evening. Gas is the residual. It is not a target and has no slider: it absorbs whatever the other choices leave uncovered, which is what makes the account close by construction and what makes the cost of not choosing visible. If the targets over-subscribe the need, gas goes to zero and a surplus is reported rather than silently absorbed.

NameFormulaUnitNotes and sources
need_2020
per row of building_segment
row.surface_2020 * row.surfacic_need / 1000000000 * building_need_calibrationTWh/y

Surface times surfacic need, scaled by the one stock-wide calibration that lands the 2020 account on the observed 359.34 TWh.

need_2050
per row of building_segment
row.need_2020 * (1 - bldgRetrofit) * (1 - bldgSobriety)TWh/y

Retrofit and temperature-related sufficiency act on the need itself, before any heating system sees it, so they benefit every vector alike and they are the only levers that lower the peak without changing a single technology.

building_heat_needsum(building_segment.need_2050)TWh/y—
building_heat_need_residentialsum(building_segment.need_2050, building_segment.building_type != "tertiary")TWh/y

Apartments and houses. The stock carries the building type, so the residential/tertiary split of every vector is counted rather than assumed — the allocation is national, but the need it is applied to is not.

building_residential_sharebuilding_heat_need_residential / building_heat_needfraction—
vector_need_2020
per row of building_vector
sum(building_segment.need_2020, building_segment.system == row.system)TWh/y—
vector_peak_load_2020
per row of building_vector
row.vector_need_2020 * row.unit_2020 / row.peak_efficiency * row.peak_shareTWh/y equivalent

The 2020 stock at its own peak efficiencies. This is the denominator of the peak anchor and the only thing the segment table is still needed for once the allocation is set by target.

building_peak_load_2020sum(building_vector.vector_peak_load_2020, building_vector.vector == "electricity")TWh/y equivalent—
heat_from_biomassbldgBiomassTwh * building_vector["biomass_wood"].seasonal_efficiencyTWh/y

Wood burned times the boiler efficiency gives the heat delivered.

heat_from_electricitybldgElectricShare * building_heat_needTWh/y—
heat_from_district_wooddistrictWoodTwh * building_vector["district_wood"].seasonal_efficiencyTWh/y—
heat_from_district_wastedistrictWasteTwhTWh/y

Recovered heat is delivered as it is found; no conversion, no losses charged.

heat_targetedheat_from_biomass + heat_from_electricity + heat_from_district_wood + heat_from_district_wasteTWh/y—
heat_from_gasmax(0, building_heat_need - heat_targeted)TWh/y

The residual, floored at zero. Gas is the only thing here without a slider, which is the point: it is what a scenario is left burning.

building_heat_surplusmax(0, heat_targeted - building_heat_need)TWh/y

What the targets over-subscribe, once gas has gone to zero. It is reported rather than absorbed, because a scenario that has quietly allocated more heat than the stock needs is a scenario whose numbers should not be trusted, and the interface says so.

electric_split_totalbldgElecAirAir + bldgElecAirWater + bldgElecResistance + bldgElecHybrid + bldgElecDistrictHPfraction

The interface rebalances these five to 100%, but a scenario file is just JSON and can be hand-edited. Normalising here means the electric heat is shared out rather than over- or under-allocated, so the five shares cannot between them invent heat that the target did not grant.

heat_air_airheat_from_electricity * bldgElecAirAir / electric_split_total if electric_split_total > 0 else 0TWh/y—
heat_air_waterheat_from_electricity * bldgElecAirWater / electric_split_total if electric_split_total > 0 else 0TWh/y—
heat_resistanceheat_from_electricity * bldgElecResistance / electric_split_total if electric_split_total > 0 else 0TWh/y—
heat_hybridheat_from_electricity * bldgElecHybrid / electric_split_total if electric_split_total > 0 else 0TWh/y—
heat_district_hpheat_from_electricity * bldgElecDistrictHP / electric_split_total if electric_split_total > 0 else 0TWh/y—
electricity_air_airheat_air_air / building_vector["air_air_electricity"].seasonal_efficiencyTWh/y—
electricity_air_waterheat_air_water / building_vector["air_water_electricity"].seasonal_efficiencyTWh/y—
electricity_resistanceheat_resistance / building_vector["resistance_electricity"].seasonal_efficiencyTWh/y—
electricity_hybridheat_hybrid * building_vector["hybrid_electricity"].unit_2050 / building_vector["hybrid_electricity"].seasonal_efficiencyTWh/y

A hybrid runs 95% of its output on electricity over the year and the rest on gas — and reverses that on the coldest evening, which is what the peak calculation picks up.

gas_hybridheat_hybrid * building_vector["hybrid_gas"].unit_2050 / building_vector["hybrid_gas"].seasonal_efficiencyTWh/y—
electricity_district_hpheat_district_hp / building_vector["district_electricity"].seasonal_efficiencyTWh/y—
building_electricityelectricity_air_air + electricity_air_water + electricity_resistance + electricity_hybrid + electricity_district_hpTWh/y—
building_gasheat_from_gas / building_vector["gas_gas"].seasonal_efficiency + gas_hybridTWh/y

The residual heat at a boiler efficiency, plus the gas a hybrid burns over the year. Network gas is charged the same efficiency as a boiler — the allocation no longer distinguishes a network from an individual installation, which slightly understates distribution losses and is stated rather than hidden.

building_woodbldgBiomassTwh + districtWoodTwhTWh/y—
building_waste_heatdistrictWasteTwhTWh/y—
building_liquid0TWh/y

Zero by construction: fuel oil is not one of the targets and gas is the residual, so no scenario can leave heating oil in 2050. Carried so the account stays constructive and so the post table keeps a line that would reappear the moment fuel became a choice again.

building_coal0TWh/y—
building_electricity_residentialbuilding_electricity * building_residential_shareTWh/y—
building_gas_residentialbuilding_gas * building_residential_shareTWh/y—
building_wood_residentialbuilding_wood * building_residential_shareTWh/y—
building_liquid_residentialbuilding_liquid * building_residential_shareTWh/y—
building_coal_residentialbuilding_coal * building_residential_shareTWh/y—
building_peak_load_2050heat_air_air / building_vector["air_air_electricity"].peak_efficiency + heat_air_water / building_vector["air_water_electricity"].peak_efficiency + heat_resistance / building_vector["resistance_electricity"].peak_efficiency + heat_hybrid * building_vector["hybrid_electricity"].unit_2050 / building_vector["hybrid_electricity"].peak_efficiency * building_vector["hybrid_electricity"].peak_share + heat_district_hp / building_vector["district_electricity"].peak_efficiencyTWh/y equivalent

Each technology at its peak efficiency rather than its seasonal one, and only the share of it actually running on electricity then. Those two things differ by technology in ways a single COP cannot express: air-air and air-water both fall to 2.0, a network heat pump to 1.5, resistance stays at 1, and a hybrid puts 70% of its peak on gas.

building_peakbuilding_peak_2020 * building_peak_load_2050 / building_peak_load_2020GW

The peak-coincident electric load is built for 2020 and for 2050 from the same rule, and the observed 2020 peak scales their ratio, so the anchor checks itself: run the 2020 stock through this and it returns 40 GW exactly. Electric space heating only, as in the source. Transport, industry and electrolysis change annual electricity but never this figure — a real asymmetry of the model, stated rather than silently patched.

building_surface_2020sum(building_segment.surface_2020) / 1000000Mm²—
building_surface_residentialsum(building_segment.surface_2020, building_segment.building_type != "tertiary") / 1000000Mm²—
building_surface_coveragebuilding_surface_2020 / floor_area_totalfraction

What share of France's floor area this stock covers: 3 654.9 Mm² of heated surface against the 4 200 Mm² ADEME reports after CEREN, so 87%. Every €/m² the model prints is per square metre of heated stock.

heat_pump_surface_2050building_surface_2020 * (heat_air_air + heat_air_water + heat_hybrid) / building_heat_needMm²

Surface in proportion to the heat that heat pumps cover. The allocation is national and carries no stock of its own, so this is a conversion rather than a count — enough to price the equipment, not enough to say which buildings got it.

heat_pump_surface_2020sum(building_segment.surface_2020, building_segment.system == "air_air" or building_segment.system == "air_water" or building_segment.system == "hybrid") / 1000000Mm²—
heat_pump_surface_addedmax(0, heat_pump_surface_2050 - heat_pump_surface_2020)Mm²

The surface that gains a heat pump it did not have in 2020 — what the scenario has to buy and install.

What the country builds, and what it takes

Stage A of the construction module. Until v0.20 no square metre was built anywhere in this model. Cement volume was a bare index — a player could remove a third of French cement by moving cementReduction without saying which building was not built — and the materials account knew about wind turbines and cars but not about buildings, which are the largest mineral flow in any industrial country. The chain is short and every step is an observation. Two floor-area levers set how much is built; the construction_use table says how many kilogrammes of cement and of steel a square metre of each destination carries, and how much of the country's cement no square metre reaches; a timber share converts part of that floor area to a frame that carries less of both and more wood. Cement demand then drives cement production, which is the change this stage exists to make. Three things this stage deliberately does not do, each because the evidence says it should not. It does not drive steel. New buildings are roughly a tenth of French steel use and about a sixth of the construction envelope, the rest being civil engineering, renovation and cladding; and construction itself is 43% of a demand whose other 57% is vehicles, machinery, tubes and metalware that nothing here models. Construction steel is computed and put beside production in the materials account, and steelGrowth remains the driver. A model that set steel output from floor area would be wrong by a factor of ten. It does not make the building stock grow. New floor area consumes cement here and heats nothing: building_heat_need still reads a stock frozen at its base-year surface. That is a real and named gap — the land account has been booking artificialised hectares since stage A of the land module while the building account stayed still — and it is stage B. It does not move the harvested-wood-products pool. Construction timber is compared with the long-lived harvest the forest account already computes, and the headroom is reported; the pool's inflow is calibrated on the inventory and is left alone. Making construction demand set the long-lived share is stage C, and it needs a sawn-versus-panel split the base year does not carry.

NameFormulaUnitNotes and sources
construction_floor_housingnewHousingMm²/y—
construction_floor_othernewNonResidentialMm²/y—
construction_floor_totalconstruction_floor_housing + construction_floor_otherMm²/y—
construction_timber_extraconstruction_floor_total * (timberShare - timber_share_base)Mm²/y

The floor area a scenario frames in timber beyond what the country already does. The base year's timber buildings are already inside the observed cement and steel tonnages the table carries, so booking the whole timber share as a saving would count today's timber twice. It can go negative — a scenario is free to build less in timber than the country does now — and then the sign works the other way, which is correct and is the reason it is not clamped.

construction_cement_savedconstruction_timber_extra * timber_cement_savingkt/y

Megagrammes per square metre are kilotonnes per square megametre, so the unit carries itself: Mm² times kg/m² is kt.

construction_steel_savedconstruction_timber_extra * timber_steel_savingkt/y—
construction_use_cement
per row of construction_use
housing_new: construction_floor_housing * row.cement_intensity
other_new: construction_floor_other * row.cement_intensity
civil_works: row.cement_2024 * civilWorksVolume
unattributed: row.cement_2024
kt/y

How much cement each end use asks for at the horizon. The two new-build rows are floor area times an intensity, which is the whole point of the module; civil works are a base-year tonnage times an index, because no square metre drives a road; and the residual row is held where it is, since a slider on a quantity nobody has attributed would be a slider on an accounting gap. An edition that has not been through its own end-use map declares zero intensities and puts all of its cement in the residual row. The arithmetic then returns the base-year tonnage unchanged, which is what the three provisional editions do and why they are unaffected by this module.

construction_use_steel
per row of construction_use
housing_new: construction_floor_housing * row.steel_intensity
other_new: construction_floor_other * row.steel_intensity
civil_works: row.steel_2024
unattributed: row.steel_2024
kt/y—
cement_demandmax(0, sum(construction_use.construction_use_cement) - construction_cement_saved)kt cement/y

The country's cement demand at the horizon, before any change in how much cement a cubic metre of concrete carries. At the reference it is the base-year total to the last digit: the four rows sum to it by construction, every index is 1, and the timber share sits on its own base — which is what lets this stage replace an exogenous volume without moving a single published result.

construction_steel_demandmax(0, sum(construction_use.construction_use_steel) - construction_steel_saved)kt/y

Structural and reinforcing steel for new buildings, computed and never read back: steelGrowth still sets what the country's mills make. The materials account puts the two side by side, which is the honest comparison — and the gap between them is the point. New buildings are a small part of construction steel, construction is 43% of French steel demand, and the rest is transport, machinery and metalware that nothing in this model drives.

construction_timber_floorconstruction_floor_total * timberShareMm²/y—
construction_timber_woodconstruction_timber_floor * timber_wood_intensityMm³/y of sawn product—
construction_timber_roundwoodconstruction_timber_wood * sawnwood_roundwood_factorMm³/y

What the built square metres ask of the forest, in the standing-stock volume the harvest is written in. It is compared with land_harvest_long_lived further down rather than subtracted from it: the long-lived share is a supply decision the player makes with harvestToProducts, and this is the demand that decision has to meet.

Industry — production volumes

NameFormulaUnitNotes and sources
steel_bf_productionsteel_bf_base_production * (1 - steelDRI) * (1 + steelGrowth)kt/y—
steel_dri_productionsteel_bf_base_production * steelDRI * (1 + steelGrowth)kt/y—
steel_eaf_productionsteel_eaf_base_production * (1 + steelGrowth)kt/y—
olefin_productionolefin_base_production * olefinRoute * (1 - plasticReduction)kt/y—
cement_productioncement_demand * clinkerRate * (1 - cementReduction)kt clinker/y

Demand now sets this, and it did not before v0.20. Until then the volume was cement_base_production — a bare base-year tonnage — times a slider, so a scenario could remove a third of the country's cement without naming a building it had not built. It is now the demand the construction module computes from floor area, civil works and the share nothing attributes, times the clinker ratio, times what a cubic metre of concrete still asks of the cement works. cementReduction survives the change and finally has a driver: it is no longer "less cement" but less cement per unit of works — leaner mixes, thinner structures, more supplementary material inside the concrete rather than inside the cement, which is what clinkerRate does. The two are not the same lever and the annex says so. What this equation still does not do is import. About a seventh of French cement consumption is imported, and clinker imports on top of that put roughly a quarter of the clinker behind French cement in a kiln outside France. Demand here drives domestic output one for one, which overstates what a French kiln burns and, in the other direction, quietly leaves the imported quarter's carbon outside the perimeter. Named rather than corrected: a domestic-supply share would be a fifth lever on a chain that already has four.

chain_production
per row of industry_chain
steel_bf: steel_bf_production
steel_dri: steel_dri_production
steel_eaf: steel_eaf_production
ammonia: chain_ammonia_production
olefins: olefin_production
cement: cement_production
kt/y—

Industry — energy and process emissions

Energy is production times unit consumption. Process emissions are the part that no change of fuel can remove: the carbon of the limestone, the carbon locked into the product, and the residue of the blast-furnace route once its coal has been counted as energy.

NameFormulaUnitNotes and sources
chain_electricity
per row of industry_chain
row.chain_production * row.electricity / 1000TWh/y—
chain_gas
per row of industry_chain
row.chain_production * row.gas / 1000TWh/y—
chain_coal
per row of industry_chain
row.chain_production * row.coal / 1000TWh/y—
chain_liquid
per row of industry_chain
row.chain_production * row.liquid / 1000TWh/y

No chain burns liquid fuel since 0.29.0: the cement kiln's 0.358 MWh a tonne of "liquid" was the teaching workbook's, and a French kiln burns petroleum coke, coal and waste instead. Kept so the account stays constructive.

chain_hydrogen
per row of industry_chain
row.chain_production * row.hydrogen / 1000TWh/y—
kiln_heatcement_production * kiln_heat_per_tonne / 1000TWh/y

What the cement kilns burn: clinker times the French fleet's 1.064 MWh a tonne. Split below between what is fossil and what is biomass, because the carriers the model has are fuels and a kiln burns a mix of them that the player chooses with kilnAltFuel.

kiln_fossil_heatkiln_heat * (1 - kilnAltFuel * kiln_waste_biomass_share)TWh/y

Petroleum coke, coal and the fossil half of the waste, all on the coal carrier. At 2020's mix — 43% waste, half of it biomass — this gives 0.281 t of fuel CO₂ a tonne of clinker, against the 0.284 the French kilns were observed at: the fossil half of the waste burns within a few per cent of coal's factor, so one carrier carries both honestly.

kiln_biomass_heatkiln_heat * kilnAltFuel * kiln_waste_biomass_shareTWh/y

The biomass half of the waste — animal meal, wood waste, sludge — on the wood carrier, where it draws on the wood pool the land supplies. Not all of it is wood, and the pool is the nearest one the model has.

kiln_fuel_co2_per_tonnekiln_heat_per_tonne * (1 - kilnAltFuel * kiln_waste_biomass_share) * sum(post.efficiency_fuel_factor, post.id == "cement") * ef_coal / 1000tCO₂ per tonne of clinker

The fossil CO₂ of the kiln fuel per tonne of clinker, after the industrial efficiency lever, so that capture and the carbon price can reach it. The same quantity the coal carrier books for the cement post, read per tonne.

kiln_biomass_co2_per_tonnekiln_heat_per_tonne * kilnAltFuel * kiln_waste_biomass_share * sum(post.efficiency_fuel_factor, post.id == "cement") * kiln_biomass_co2tCO₂ per tonne of clinker

The biogenic CO₂ of the kiln's waste, per tonne of clinker. Never counted as an emission; it goes up the same stack as the fossil, so a capture plant takes it too, and the CO₂ has to be shipped and stored whatever its origin.

cement_captured_fossilcement_production * (cement_process_per_tonne + kiln_fuel_co2_per_tonne) * carbonCapture / 1000MtCO₂/y

What carbonCapture removes from the cement post: its share of the calcination and of the fossil kiln fuel.

cement_captured_biogeniccement_production * kiln_biomass_co2_per_tonne * carbonCapture / 1000MtCO₂/y

Shown, not counted, for the reason wte_biogenic_captured gives; paid for all the same, in transport and storage.

cement_capture_powercement_production * cement_capture_extra_electricity * carbonCapture / cement_capture_reference_rate / 1000TWh/y

The electricity the cement capture plants draw. It is added to the cement post after the industrial efficiency lever, which was sized on the grinding mills and cannot shave a solvent's regeneration heat.

steel_bf_process_residualsteel_bf_direct_intensity - industry_chain["steel_bf"].coal * ef_coal / 1000tCO₂ per tonne of steel

A remainder, not a measurement. The route's direct total, steel_bf_direct_intensity, less the coal the chain row charges at the published coal factor: 1.76 − 5.047 MWh × 340 g = 0.044 tCO₂ per tonne. The coal is counted once, as energy, where the fuel levers can reach it; this keeps the rest. The teaching workbook had charged both, so the coal carbon was counted twice until this line existed. The rest is physically the limestone flux — 0.27 t per tonne of steel, +0.12 tCO₂ — less the carbon that stays in the steel, −0.04, less whatever leaves the site in blast-furnace and coke-oven gas. 0.044 is inside that band, but it is the difference of two numbers of order 1.7, so a 2% revision of either moves it by 78%. Treat it as a closure, and build it from the flux if it ever matters.

chain_process_per_tonne
per row of industry_chain
steel_bf: steel_bf_process_residual
steel_dri: steel_eaf_process_per_tonne
steel_eaf: steel_eaf_process_per_tonne
olefins: -olefin_carbon_per_tonne * biogenicCO2
cement: cement_process_per_tonne * (1 - carbonCapture) - carbonCapture * kiln_fuel_co2_per_tonne
default: 0
tCO₂ per tonne of product

Emissions no change of fuel can remove: the limestone carbon in cement, the carbon locked into synthetic olefins — a credit, hence negative — the blast-furnace residue left once its coal has been counted as energy, and, since 0.27.0, the electrodes and charge carbon of the two electric-furnace routes.

chain_emissions_per_tonne
per row of industry_chain
row.coal * ef_coal / 1000 + row.chain_process_per_tonne + (kiln_fuel_co2_per_tonne if row.id == "cement" else 0)tCO₂ per tonne of product

What the plant emits on site, per tonne of product. The cost model charges the carbon price on exactly this quantity, so the cost and the emissions account can never describe different plants.

chain_process
per row of industry_chain
row.chain_production * row.chain_process_per_tonne / 1000MtCO₂/y—
food_steamfood_steam_demand * (1 - foodEfficiency)TWh/y—
food_direct_heatfood_direct_heat_demand * (1 - foodEfficiency)TWh/y—
food_electricity(food_steam * foodHPSteam + food_direct_heat * foodHPDirect) / food_heat_pump_copTWh/y

Heat delivered by heat pumps, divided by their coefficient of performance.

food_gasfood_steam * (1 - foodHPSteam) + food_direct_heat * (1 - foodHPDirect)TWh/y—

The rest of industry

Seventeen manufacturing branches the game does not model as value chains — metals and machinery, minerals, the rest of chemistry, paper, and a diverse remainder. Together they are about 174 TWh today, 68 of it electricity, more than the five modelled chains use between them. Output and processes move on separate levers because the source scenario mixes the two: it electrifies, and it also multiplies textile output by 8.5.

NameFormulaUnitNotes and sources
other_energy
per row of industry_other
(row.e00 + (row.e10 - row.e00) * otherIndustryVolume + (row.e01 - row.e00) * otherIndustryProcess + (row.e11 - row.e10 - row.e01 + row.e00) * otherIndustryVolume * otherIndustryProcess) * (1 - otherIndustrySobriety)TWh/y, or MtCO₂/y for the process rows

Bilinear interpolation between the four corners. It is exact at all four, so at the default levers the block reproduces the published 2050 processes applied to today's output, and at (100%, 100%) it reproduces the source scenario to the last decimal. Then the whole block is scaled by otherIndustrySobriety, the same share off every branch, carrier and process term.

other_industry_energysum(industry_other.other_energy, industry_other.carrier != "process")TWh/y—
other_industry_electricitysum(industry_other.other_energy, industry_other.carrier == "electricity")TWh/y—

The constructive account — energy and emissions by post

One row per sub-sector, one column per energy carrier. Sector totals are sums of this table and nothing else. Electricity is kept in three columns — used directly, used to make hydrogen, used to make e-fuel — because the three have very different implications for the power system even though they carry the same emission factor.

NameFormulaUnitNotes and sources
energy_electricity_direct_raw
per row of post
passenger_mobility: passenger_electricity_direct
freight_mobility: freight_electricity_direct
residential_heating: building_electricity_residential
tertiary_heating: building_electricity - building_electricity_residential
residential_uses: usages_electricity_residential
tertiary_uses: usages_electricity_tertiary
steel: sum(industry_chain.chain_electricity, industry_chain.subpost == "steel")
ammonia: sum(industry_chain.chain_electricity, industry_chain.subpost == "ammonia")
olefins: sum(industry_chain.chain_electricity, industry_chain.subpost == "olefins")
cement: sum(industry_chain.chain_electricity, industry_chain.subpost == "cement")
food_heat: food_electricity
other_metals: sum(industry_other.other_energy, industry_other.group == "metals_machinery" and industry_other.carrier == "electricity")
other_minerals: sum(industry_other.other_energy, industry_other.group == "minerals" and industry_other.carrier == "electricity")
other_chemicals: sum(industry_other.other_energy, industry_other.group == "chemicals_other" and industry_other.carrier == "electricity")
other_paper: sum(industry_other.other_energy, industry_other.group == "paper" and industry_other.carrier == "electricity")
other_diverse: sum(industry_other.other_energy, industry_other.group == "other_industries" and industry_other.carrier == "electricity")
energy_production: 0
hydrogen_production: 0
waste_to_energy: 0
livestock: 0
crops: 0
farm_machinery: 0
TWh/y—
energy_hydrogen
per row of post
passenger_mobility: passenger_hydrogen
freight_mobility: freight_hydrogen
steel: sum(industry_chain.chain_hydrogen, industry_chain.subpost == "steel")
ammonia: sum(industry_chain.chain_hydrogen, industry_chain.subpost == "ammonia")
olefins: sum(industry_chain.chain_hydrogen, industry_chain.subpost == "olefins")
food_heat: food_hydrogen
other_metals: sum(industry_other.other_energy, industry_other.group == "metals_machinery" and industry_other.carrier == "hydrogen")
other_minerals: sum(industry_other.other_energy, industry_other.group == "minerals" and industry_other.carrier == "hydrogen")
other_chemicals: sum(industry_other.other_energy, industry_other.group == "chemicals_other" and industry_other.carrier == "hydrogen")
other_paper: sum(industry_other.other_energy, industry_other.group == "paper" and industry_other.carrier == "hydrogen")
other_diverse: sum(industry_other.other_energy, industry_other.group == "other_industries" and industry_other.carrier == "hydrogen")
default: 0
TWh/y

The hydrogen each post consumes, before anything is said about how it was made. Until v0.12.0 this was converted straight into electricity at the electrolyser efficiency, which hard-coded one production route into every consumer of hydrogen in the model. That release undid it for industry but left the two transport rows pointing at figures the transport module had already divided by that efficiency, so transport hydrogen was converted twice — 2.78 MWh of electricity per MWh of hydrogen instead of 1.67 — until v0.14.3.

hydrogen_mix_totalh2Electrolysis + h2Smr + h2AtrCcs if h2Electrolysis + h2Smr + h2AtrCcs > 0 else 1fraction

Normalised in the model rather than trusted to the interface, like the building and generation mixes. Falls back to one if a scenario zeroes all three, since hydrogen has to come from somewhere.

hydrogen_demand_totalsum(post.energy_hydrogen)TWh/y—
route_share
per row of hydrogen_route
electrolysis: h2Electrolysis / hydrogen_mix_total
smr: h2Smr / hydrogen_mix_total
atr_ccs: h2AtrCcs / hydrogen_mix_total
fraction—
route_hydrogen
per row of hydrogen_route
hydrogen_demand_total * row.route_shareTWh/y—
route_electricity_per_mwh
per row of hydrogen_route
electrolysis: 1 / efficiency_electricity_to_h2
default: row.electricity
MWh of electricity per MWh of hydrogen

The electrolyser's figure is derived from the conversion efficiency the rest of the model already uses, rather than declared again in the table. Two copies of that number would be two numbers.

route_methane
per row of hydrogen_route
row.route_hydrogen * row.methaneTWh/y—
route_captured_methane
per row of hydrogen_route
row.route_methane * row.carbon_capturedTWh/y—
hydrogen_electricity_totalsumproduct(hydrogen_route.route_hydrogen, hydrogen_route.route_electricity_per_mwh)TWh/y—
hydrogen_methane_totalsum(hydrogen_route.route_methane)TWh/y

Feedstock and fuel together. It draws on the same methane the buildings and the power stations want, and the scoreboard counts it there — which is the trade-off a reforming route actually makes.

hydrogen_carbon_capturedsum(hydrogen_route.route_captured_methane) * carbon_in_methane / 1000MtCO₂/y

The carbon in the reformed methane that ends underground. Charged against the physical carbon the methane carries, not against efGas: what a capture plant removes is molecules, and efGas at 25 gCO₂/kWh is a biogenic accounting convention rather than a measurement of what is in the pipe. The consequence is deliberate and contested. On biomethane this makes hydrogen production carbon-negative — the physics of BECCS, and the place where this model will most easily mislead a reader who has not read the controversy tab.

hydrogen_electricity_per_mwhhydrogen_electricity_total / hydrogen_demand_total if hydrogen_demand_total > 0 else 0MWh of electricity per MWh of hydrogen

The mix's average. Each consumer's electricity-for-hydrogen is its own hydrogen times this, so reforming half the country's hydrogen halves the electricity every hydrogen user draws.

energy_electricity_hydrogen
per row of post
row.energy_hydrogen * hydrogen_electricity_per_mwhTWh/y—
energy_electricity_efuel
per row of post
passenger_mobility: passenger_electricity_efuel
freight_mobility: freight_electricity_efuel
default: 0
TWh/y—
energy_gas_raw
per row of post
passenger_mobility: passenger_gas
freight_mobility: freight_gas
residential_heating: building_gas_residential
tertiary_heating: building_gas - building_gas_residential
residential_uses: usages_gas_residential
tertiary_uses: usages_gas_tertiary
energy_production: generation_gas_fuel
hydrogen_production: hydrogen_methane_total
waste_to_energy: 0
steel: sum(industry_chain.chain_gas, industry_chain.subpost == "steel")
ammonia: sum(industry_chain.chain_gas, industry_chain.subpost == "ammonia")
olefins: sum(industry_chain.chain_gas, industry_chain.subpost == "olefins")
cement: sum(industry_chain.chain_gas, industry_chain.subpost == "cement")
food_heat: food_gas
other_metals: sum(industry_other.other_energy, industry_other.group == "metals_machinery" and industry_other.carrier == "gas") + sum(industry_other.other_energy, industry_other.group == "metals_machinery" and industry_other.carrier == "steam")
other_minerals: sum(industry_other.other_energy, industry_other.group == "minerals" and industry_other.carrier == "gas") + sum(industry_other.other_energy, industry_other.group == "minerals" and industry_other.carrier == "steam")
other_chemicals: sum(industry_other.other_energy, industry_other.group == "chemicals_other" and industry_other.carrier == "gas") + sum(industry_other.other_energy, industry_other.group == "chemicals_other" and industry_other.carrier == "steam")
other_paper: sum(industry_other.other_energy, industry_other.group == "paper" and industry_other.carrier == "gas") + sum(industry_other.other_energy, industry_other.group == "paper" and industry_other.carrier == "steam")
other_diverse: sum(industry_other.other_energy, industry_other.group == "other_industries" and industry_other.carrier == "gas") + sum(industry_other.other_energy, industry_other.group == "other_industries" and industry_other.carrier == "steam")
livestock: 0
crops: 0
farm_machinery: 0
TWh/y

Before any waste heat is recovered against it.

energy_biofuel_raw
per row of post
passenger_mobility: passenger_biofuel
freight_mobility: freight_biofuel
cement: sum(industry_chain.chain_liquid, industry_chain.subpost == "cement")
residential_heating: building_liquid_residential
tertiary_heating: building_liquid - building_liquid_residential
residential_uses: usages_liquid_residential
tertiary_uses: usages_liquid_tertiary
other_metals: sum(industry_other.other_energy, industry_other.group == "metals_machinery" and industry_other.carrier == "oil")
other_minerals: sum(industry_other.other_energy, industry_other.group == "minerals" and industry_other.carrier == "oil")
other_chemicals: sum(industry_other.other_energy, industry_other.group == "chemicals_other" and industry_other.carrier == "oil")
other_paper: sum(industry_other.other_energy, industry_other.group == "paper" and industry_other.carrier == "oil")
other_diverse: sum(industry_other.other_energy, industry_other.group == "other_industries" and industry_other.carrier == "oil")
default: 0
TWh/y—
energy_wood_raw
per row of post
residential_heating: building_wood_residential
tertiary_heating: building_wood - building_wood_residential
residential_uses: usages_wood_residential
tertiary_uses: usages_wood_tertiary
energy_production: generation_wood_fuel
cement: kiln_biomass_heat
other_metals: sum(industry_other.other_energy, industry_other.group == "metals_machinery" and industry_other.carrier == "biomass")
other_minerals: sum(industry_other.other_energy, industry_other.group == "minerals" and industry_other.carrier == "biomass")
other_chemicals: sum(industry_other.other_energy, industry_other.group == "chemicals_other" and industry_other.carrier == "biomass")
other_paper: sum(industry_other.other_energy, industry_other.group == "paper" and industry_other.carrier == "biomass")
other_diverse: sum(industry_other.other_energy, industry_other.group == "other_industries" and industry_other.carrier == "biomass")
default: 0
TWh/y—
energy_coal_raw
per row of post
steel: sum(industry_chain.chain_coal, industry_chain.subpost == "steel")
cement: sum(industry_chain.chain_coal, industry_chain.subpost == "cement") + kiln_fossil_heat
residential_heating: building_coal_residential
tertiary_heating: building_coal - building_coal_residential
other_metals: sum(industry_other.other_energy, industry_other.group == "metals_machinery" and industry_other.carrier == "coal")
other_minerals: sum(industry_other.other_energy, industry_other.group == "minerals" and industry_other.carrier == "coal")
other_chemicals: sum(industry_other.other_energy, industry_other.group == "chemicals_other" and industry_other.carrier == "coal")
other_paper: sum(industry_other.other_energy, industry_other.group == "paper" and industry_other.carrier == "coal")
other_diverse: sum(industry_other.other_energy, industry_other.group == "other_industries" and industry_other.carrier == "coal")
default: 0
TWh/y—
efficiency_elec_factor
per row of post
1 - industryEfficiency * row.elec_efficiency_ceilingfraction of the electricity remaining

The effort lever times this post's own ceiling, so the lever can never buy more efficiency than RTE identified for that branch. Only direct electricity is affected: the electricity that goes into hydrogen and e-fuel is set by conversion efficiencies declared elsewhere.

efficiency_fuel_factor
per row of post
1 - industryEfficiency * (fuel_efficiency_ceiling if row.sector == "industry" else 0)fraction of the fuel remaining

RTE gives no branch breakdown on the fuel side, so one ceiling applies across industry. Transport and buildings are untouched: their own levers already carry demand and equipment efficiency.

energy_electricity_efficient
per row of post
row.energy_electricity_direct_raw * row.efficiency_elec_factorTWh/y—
energy_electricity_added
per row of post
cement: cement_capture_power
waste_to_energy: wte_capture_power + plastic_recycling_power
default: 0
TWh/y

What the two capture levers draw, since 0.32.0, and the plastic recycling lines, since 0.33.0. Outside the efficiency lever and inside the direct demand, so the mix has to produce it.

energy_electricity_direct
per row of post
row.energy_electricity_efficient + row.energy_electricity_addedTWh/y—
energy_gas_gross
per row of post
row.energy_gas_raw * row.efficiency_fuel_factorTWh/y—
energy_coal
per row of post
row.energy_coal_raw * row.efficiency_fuel_factorTWh/y—
energy_biofuel
per row of post
row.energy_biofuel_raw * row.efficiency_fuel_factorTWh/y—
energy_wood
per row of post
row.energy_wood_raw * row.efficiency_fuel_factorTWh/y—
combustion_fuel_gross
per row of post
row.energy_gas_gross + row.energy_coal + row.energy_biofuel + row.energy_woodTWh/y

Everything burned, before recovery. ADEME expresses the waste-heat gisement against exactly this — fossil fuels and biomass together.

waste_heat_potential
per row of post
row.combustion_fuel_gross * row.waste_heat_shareTWh/y

The recoverable gisement of this post, at the fuel it actually burns in this scenario. It is not a fixed reserve: electrify the heat and the gisement goes with it, because there is no combustion left to reject heat from. That is the trade-off the lever exists to show.

waste_heat_recovered
per row of post
min(row.waste_heat_potential * wasteHeatRecovery, row.energy_gas_gross)TWh/y

Recovered heat is assumed to displace gas, the marginal fuel, and cannot displace more gas than the post burns. The second-order feedback — less gas means a slightly smaller gisement — is neglected; at full recovery it is under half a percent.

energy_gas
per row of post
row.energy_gas_gross - row.waste_heat_recoveredTWh/y—
energy_electricity_total
per row of post
row.energy_electricity_direct + row.energy_electricity_hydrogen + row.energy_electricity_efuelTWh/y—
energy_total
per row of post
row.energy_electricity_total + row.energy_gas + row.energy_biofuel + row.energy_wood + row.energy_coalTWh/y—
emissions_electricity
per row of post
0MtCO₂/y

Zero, and that is the accounting scope, not an omission. The model is a scope-1 account: emissions are booked where the combustion happens. A power station's emissions belong to the power station, so they sit on the energy_production post, computed from the fuel the chosen mix actually burns — not spread back over everyone who used a kilowatt-hour. This is the same convention SECTEN and the SNBC use, which is why the national reconciliation no longer needs a life-cycle line to undo it. The consequence a reader should hold onto: electrifying a sector moves its emissions rather than removing them, and where they land depends on the electricity mix, which is a separate choice.

emissions_gas
per row of post
row.energy_gas * efGas / 1000MtCO₂/y—
emissions_biofuel
per row of post
row.energy_biofuel * efLiquid / 1000MtCO₂/y—
emissions_wood
per row of post
row.energy_wood * efWood / 1000MtCO₂/y—
emissions_coal
per row of post
row.energy_coal * ef_coal / 1000MtCO₂/y—
emissions_process
per row of post
steel: sum(industry_chain.chain_process, industry_chain.subpost == "steel")
ammonia: sum(industry_chain.chain_process, industry_chain.subpost == "ammonia")
olefins: sum(industry_chain.chain_process, industry_chain.subpost == "olefins")
cement: sum(industry_chain.chain_process, industry_chain.subpost == "cement")
other_metals: sum(industry_other.other_energy, industry_other.group == "metals_machinery" and industry_other.carrier == "process")
other_minerals: sum(industry_other.other_energy, industry_other.group == "minerals" and industry_other.carrier == "process")
other_chemicals: sum(industry_other.other_energy, industry_other.group == "chemicals_other" and industry_other.carrier == "process")
other_paper: sum(industry_other.other_energy, industry_other.group == "paper" and industry_other.carrier == "process")
other_diverse: sum(industry_other.other_energy, industry_other.group == "other_industries" and industry_other.carrier == "process")
hydrogen_production: -hydrogen_carbon_captured
waste_to_energy: wte_fossil_co2
livestock: agriculture_livestock_post
crops: agriculture_crops_post
farm_machinery: agriculture_fuel_post
default: 0
MtCO₂/y—
emissions_combustion
per row of post
row.emissions_gas + row.emissions_biofuel + row.emissions_wood + row.emissions_coal + row.emissions_processMtCO₂/y

Everything except the electricity, which the inventory attributes elsewhere.

emissions_total
per row of post
row.emissions_electricity + row.emissions_combustionMtCO₂/y—

Waste to energy

The incinerators that turn residual waste into heat and power. The inventory books their fossil CO₂ to the energy sector, not to waste, and until 0.28.0 this model booked it nowhere: national_waste slides between two published waste totals that exclude it by construction, and the power sector here is the electricity mix alone.

NameFormulaUnitNotes and sources
wte_fossil_co2wte_fossil_burned * (1 - wteCapture)MtCO₂/y

The base year's fossil CO₂, of which the plastic share follows plastic demand: plasticReduction at 30% takes 28.5% off it, at 70% two thirds. This is what turns plastic sobriety the right way round. The lever used to scale only the olefins a French plant makes, so a scenario that asked for less plastic lost part of its olefin credit and saw its emissions rise; the plastic it no longer burns now counts, and over the lever's range it is worth ten times the credit. Three things it assumes, and says. The plastic burned is the plastic consumed, wherever it was made, so olefinRoute does not reach it — whether France cracks its ethylene, synthesises it or imports it, the packaging ends in a French furnace. It is all fossil: bio-based plastic is about 1% of the European market, and the IPCC's default for plastics is 100% fossil carbon. And landfill stands still. Since 0.33.0 recycling does not: plasticRecycling takes plastic out of the furnace. Landfill has no variable because the evidence says it does not reach this term: French landfill fell 3.1 Mt between 2020 and 2022 while the incinerators, which are full and already turn waste away, burned no more, and what leaves landfill goes to refuse-derived fuel for kilns and boilers. wteCapture then takes its share of what is left, stack by stack.

wte_fossil_burnedwte_fossil_co2_base * (1 - wte_plastic_fossil_share + wte_plastic_fossil_share * (1 - plasticReduction) * (1 - plasticRecycling))MtCO₂/y

The fossil CO₂ the incinerators release before any capture. The plastic part follows what is consumed, plasticReduction, and then what is recycled of it rather than burned, plasticRecycling; the other 5% — textiles, nappies, leather — follows neither.

plastic_recycledwte_fossil_co2_base * wte_plastic_fossil_share * (1 - plasticReduction) * plasticRecycling / plastic_fossil_co2_per_tonneMt/y

The tonnes of plastic the recycling lever takes away from the incinerators, read back from their CO₂ at 2.75 t a tonne.

plastic_recycling_powerplastic_recycled * plastic_recycling_electricityTWh/y

What the recycling lines draw, booked on the waste-to-energy post for want of a post of their own.

wte_fossil_capturedwte_fossil_burned * wteCaptureMtCO₂/y

The fossil CO₂ the capture plants take, which is what lowers the total.

wte_biogenic_capturedwte_fossil_co2_base * wte_biogenic_share / (1 - wte_biogenic_share) * wteCaptureMtCO₂/y

Shown, not counted. The biogenic CO₂ the same capture plants take with the fossil: 1.5 tonnes for every fossil tonne of the base year in France, one in Germany, and it does not fall with plastic demand, because it is the food, paper and wood in the bin. It would be a removal, and removals are what techSink stands for; adding it here would count one tonne twice.

wte_capture_power(wte_fossil_captured + wte_biogenic_captured) * wte_capture_electricityTWh/y

The electricity the incinerators stop exporting to run their capture plants, booked as a demand on their own post: every tonne captured, fossil or biogenic, at 0.315 MWh. Since 60% of what French plants capture is biogenic, 0.79 MWh of it is spent for each fossil tonne the total loses, and more once plastic sobriety has thinned the fossil part.

Sector and resource totals

NameFormulaUnitNotes and sources
transport_emissionssum(post.emissions_total, post.sector == "transport")MtCO₂/y—
building_emissionssum(post.emissions_total, post.sector == "building")MtCO₂/y—
industry_emissionssum(post.emissions_total, post.sector == "industry")MtCO₂/y—
game_emissionssum(post.emissions_total)MtCO₂/y—
electricity_demand_before_power_hydrogensum(post.energy_electricity_total)TWh/y

Everything the sectors consume, before the power system's own electrolysis.

power_hydrogen_feedbackclamp(sum(generation_technology.generation_share_thermal_gas) * gasPlantHydrogen / efficiency_electricity_to_h2, 0, 0.9)fraction of total demand

The share of total electricity that goes back into making the hydrogen the gas plants burn. It depends on the mix's shares and on two efficiencies, never on the demand itself, which is what makes the loop solvable rather than iterative. Clamped below one: a fleet consuming more electricity than it produces has no solution, and the model says so by refusing to divide rather than by returning a negative demand.

electricity_demandelectricity_demand_before_power_hydrogen / (1 - power_hydrogen_feedback)TWh/y

base / (1 - k). Closing the loop in one line rather than iterating: demand sets the mix, the mix sets the fuel, the fuel sets the electrolysis, and the electrolysis is demand — but k depends only on shares and efficiencies, so the fixed point is linear. It matters. Converting the whole gas fleet adds around a ninth of national demand, and reporting that beside the total instead of inside it would let a scenario buy clean combustion for free.

electricity_direct_demandsum(post.energy_electricity_direct)TWh/y—
electricity_hydrogen_demandsum(post.energy_electricity_hydrogen)TWh/y—
electricity_efuel_demandsum(post.energy_electricity_efuel)TWh/y—
biogas_demandsum(post.energy_gas)TWh/y

The methane resource the scenario needs. It includes about 23 TWh of international air-freight fuel, which the workbook classes as gas — worth knowing before reading this against a biomethane potential.

biofuel_demandsum(post.energy_biofuel)TWh/y—
wood_demandsum(post.energy_wood)TWh/y—
coal_demandsum(post.energy_coal)TWh/y—
efficiency_savingsum(post.energy_electricity_direct_raw) - sum(post.energy_electricity_efficient) + sum(post.energy_gas_raw) - sum(post.energy_gas_gross) + sum(post.energy_coal_raw) - sum(post.energy_coal) + sum(post.energy_biofuel_raw) - sum(post.energy_biofuel) + sum(post.energy_wood_raw) - sum(post.energy_wood)TWh/y

What the effort lever removes from final energy, all carriers together.

efficiency_saving_fuelsum(post.energy_gas_raw) - sum(post.energy_gas_gross) + sum(post.energy_coal_raw) - sum(post.energy_coal) + sum(post.energy_biofuel_raw) - sum(post.energy_biofuel) + sum(post.energy_wood_raw) - sum(post.energy_wood)TWh/y

The fuel part of the saving. It is the part that also removes waste heat, which is why it is reported separately from the electricity.

waste_heat_potential_totalsum(post.waste_heat_potential)TWh/y—
waste_heat_recovered_totalsum(post.waste_heat_recovered)TWh/y—
waste_heat_potential_hotsumproduct(post.waste_heat_potential, post.waste_heat_hot_share)TWh/y

The part of the gisement above 100 °C, which is the part that can displace process heat directly.

total_final_energysum(post.energy_total)TWh/y—
electric_shareelectricity_demand / total_final_energyfraction—

Land, forest and the carbon sink

Stage A of the land module. It replaces a slider that had no driver — a natural sink set by hand, anywhere between 5 and 40 MtCO₂e absorbed — with a physical account: seven land classes that add up to a fixed territory, three flows that move hectares between them, and a forest whose sink is an identity in cubic metres rather than a number somebody chose. Three things are worth understanding before reading the formulas. The account closes by construction, and nothing absorbs a residual. Every flow is a signed transfer with a named source and a named destination, and the destination gains exactly what the source loses, so the seven classes sum to the same territory at every position of every lever. Nothing is clamped: land_clamped_kha reports how much flow a class could not have supplied, and it is zero everywhere inside the declared bounds. Clamping would have been the alternative, and it would have broken the closure it was meant to protect. The forest sink is k · (P·A − M·A − H) and nothing else. Gross production less mortality less removals, in cubic metres, times a carbon coefficient. A harvest lever therefore moves the sink, which is exactly the argument the forestry literature is having, and a wood-heavy scenario no longer gets its biomass for free. What the identity does not book is substitution — the fossil fuel and the concrete that wood displaces — for the reason the whole model is built on: the game already charges fossil fuel where it burns, so a substitution credit here would count it twice. The base year is checked, the horizon is not. A parallel set of *_2024 equations recomputes each pool at the base year, on base-year quantities and with no climate factor, and the tests hold them against the published inventory pool by pool. The 2050 figures are results, and two of them are uncomfortable: under the severe climate case with a hard harvest the forest becomes a net source, which is reachable inside the declared bounds and is reported rather than clamped away. Read the 2050 sink as an endpoint, not as an average — published projections usually quote a 2020–2050 mean, which is higher because the sink is still falling.

NameFormulaUnitNotes and sources
land_setting_artificialisationland_module_active * artificialisationRate + (1 - land_module_active) * artificialisation_rate_basekha/y

The module's switch applied to a lever. Where land_module_active is 0 the whole module is read at its base year, so a package that does not carry it reports no land movement rather than another country's, and a lever hidden in that package cannot move a number. Both sides always evaluate — this is arithmetic and never a branch — so the three back-ends see one expression and cannot take different paths through it.

land_setting_afforestationland_module_active * afforestationRate + (1 - land_module_active) * afforestation_rate_basekha/y—
land_setting_grasslandland_module_active * grasslandConversion + (1 - land_module_active) * grassland_conversion_basekha/y—
land_setting_soil_practicesland_module_active * soilCarbonPractices + (1 - land_module_active) * soil_practice_basefraction of the identified potential—
land_setting_harvestland_module_active * forestHarvest + (1 - land_module_active) * forest_harvest_baseMm³/y—
land_setting_long_livedland_module_active * harvestToProducts + (1 - land_module_active) * hwp_long_lived_share_basefraction of the harvest—
land_setting_peat_rewettingland_module_active * peatRewetting + (1 - land_module_active) * peat_rewetting_basefraction of the drained organic soil

The same switch on the peat lever. It is a share of the drained organic soil rewetted by the horizon, not a rate: rewetting is a one-off change of state, and a country that has already rewetted part of its peat declares that as peat_rewetting_base so the base year reads what it observed rather than a bare zero.

forest_production_factorland_module_active * sum(forest_climate.production_factor, forest_climate.position == forestClimate) + (1 - land_module_active)factor on the base-year production

The climate case, read out of the table by the position the control sits at — a plain filtered column total, the same idiom the electricity mix uses, and no loader change. Switched off, the factor is 1: a forest whose growth has not changed, which is the state the base-year check is written in.

forest_mortality_factorland_module_active * sum(forest_climate.mortality_factor, forest_climate.position == forestClimate) + (1 - land_module_active)factor on the base-year mortality—
land_flow_artificialisedland_setting_artificialisation * land_horizon_years / 1000Mha over the horizon

A rate in thousand hectares a year, sustained over the whole horizon, in million hectares. Artificialisation is measured on the land survey the account is written in, not on the cadastre: the cadastre counts parcels newly built on and the survey counts every garden and verge as well, so the two differ by a factor of two or three, and the emission content of the artificial pool only closes on the survey's rate. The cadastral measure belongs beside the result as a comparison, not inside it as the driver.

land_flow_afforestedland_setting_afforestation * land_horizon_years / 1000Mha over the horizon—
land_flow_grassland_to_arableland_setting_grassland * land_horizon_years / 1000Mha over the horizon

Signed: positive ploughs grassland into arable land, negative puts arable land back to grass. One flow rather than two levers, because the two directions are one decision and a country cannot do both at once.

land_arableland_class["arable"].area_2023 - land_flow_artificialised * artificialisation_to_arable_share + land_flow_grassland_to_arableMha

Land take draws on three named classes and the semi-natural residual, and the four shares are declared rather than assumed. A country whose building spreads onto arable land alone declares 1, 0 and 0 and the other two terms are exactly zero; a country whose forest inventory measures how much woodland the roads and the industrial estates took declares that share too.

land_grasslandland_class["grassland"].area_2023 - land_flow_grassland_to_arable - land_flow_artificialised * artificialisation_to_grassland_shareMha—
land_perm_cropsland_class["perm_crops"].area_2023Mha

Vines and orchards. No lever moves them, and saying so as an equation rather than leaving the class out is what keeps the account a partition of the whole territory.

land_forestland_class["forest"].area_2023 + land_flow_afforested - land_flow_artificialised * artificialisation_to_forest_shareMha

The forest class of the land account, which is not the forest area the sink identity runs on: the identity uses the area available for wood production, a smaller and differently drawn perimeter. The two are kept apart on purpose, and afforestation adds hectares to this one while the identity's area stays where it is — new forest is booked at the expansion storage rate instead, because a young stand does not store like a mature one.

land_other_naturalland_class["other_natural"].area_2023 - land_flow_artificialised * (1 - artificialisation_to_arable_share - artificialisation_to_grassland_share - artificialisation_to_forest_share) - land_flow_afforestedMha

Heath, scrub, copses and bare ground — the class both other flows draw on, and the one that empties first. It is also where the largest unreconciled disagreement in the account sits: a forest inventory sees canopy closing on former heath and calls it new forest, while a land survey still sees heath, and the two published expansion rates differ by a factor of nearly three.

land_waterland_class["water"].area_2023Mha—
land_artificialland_class["artificial"].area_2023 + land_flow_artificialisedMha—
land_area_2023
per row of land_class
row.area_2023Mha

The base-year column, re-emitted as a result so the partition chart reads both of its bars from one place instead of one from the model and one from the raw table.

land_area_2050
per row of land_class
arable: land_arable
grassland: land_grassland
perm_crops: land_perm_crops
forest: land_forest
other_natural: land_other_natural
water: land_water
artificial: land_artificial
Mha

One formula per class, side by side, which is what makes the transfers auditable: every hectare that leaves a class arrives in another, and reading the seven lines together is how you see it. This is also what makes land_class a fixed-row table — the row set is derived from this map, not restated by hand.

land_peat_emission
per row of land_class
row.peat_area * (row.peat_ef - land_setting_peat_rewetting * (row.peat_ef - peat_rewetted_emission))MtCO₂e/y emitted

A drained peat soil is a chimney, and in some countries it is the largest one on the land. Per land class, the area of organic soil the inventory maps under it times the emission factor that class's drained peat carries, with the share the player rewets moved onto the much smaller wet factor. The two are declared in land_class beside the area, because an organic-soil area is a fact about a land class and putting it anywhere else would let the two drift apart. Three things about it are deliberate. The peat area does not follow the class area: a peat deposit is where it is, and ploughing a hectare of grassland does not move the peat under it. The rewetted hectare keeps emitting — peat_rewetted_emission, mostly methane — rather than going to zero, because a wet peatland is not a sink on this timescale. And the factors are the inventory's implied ones, so a country with no mapped organic soil declares zero areas and every term here is exactly zero, which is what keeps this addition inert where it does not apply.

land_peat_emission_2024
per row of land_class
row.peat_area * (row.peat_ef - peat_rewetting_base * (row.peat_ef - peat_rewetted_emission))MtCO₂e/y emitted—
land_peat_arablesum(land_class.land_peat_emission, land_class.id == "arable")MtCO₂e/y emitted—
land_peat_grasslandsum(land_class.land_peat_emission, land_class.id == "grassland")MtCO₂e/y emitted—
land_peat_forestsum(land_class.land_peat_emission, land_class.id == "forest")MtCO₂e/y emitted—
land_peat_watersum(land_class.land_peat_emission, land_class.id == "water")MtCO₂e/y emitted—
land_peat_artificialsum(land_class.land_peat_emission, land_class.id == "artificial")MtCO₂e/y emitted—
land_peat_totalsum(land_class.land_peat_emission)MtCO₂e/y emitted—
land_peat_unbookedland_peat_total - land_peat_arable - land_peat_grassland - land_peat_forest - land_peat_water - land_peat_artificialMtCO₂e/y emitted

Zero, and asserted rather than assumed. Five of the seven classes hand their peat to a named pool of the inventory; the two that do not — permanent crops and semi-natural land — have no pool of their own to book it in, so a country that declared organic soil under them would otherwise lose it silently. This is the line that refuses to.

land_peat_area_totalsum(land_class.peat_area)Mha—
land_peat_rewetted_arealand_peat_area_total * land_setting_peat_rewettingMha

The hectares the lever puts back under water, over the whole horizon. It is reported because it is the quantity a rewetting programme is actually written in — Germany's own targets are in hectares, not in megatonnes — and because it is what the grassland the herd can graze loses.

land_total_2023sum(land_class.area_2023)Mha—
land_total_2050sum(land_class.land_area_2050)Mha—
land_account_residualland_total_2050 - land_total_2023Mha

Zero, at every position of every lever, and a test asserts it over the corners of the three flow levers and a seeded sweep between them. It is emitted rather than assumed because an account that closes by construction is a claim about the algebra, and a claim worth making is worth showing.

land_clamped_kha(max(0, -land_arable) + max(0, -land_grassland) + max(0, -land_perm_crops) + max(0, -land_forest) + max(0, -land_other_natural) + max(0, -land_water) + max(0, -land_artificial)) * 1000 / land_horizon_yearskha/y

How much annual flow would have to be given back for every class to stay non-negative — the answer to the author's own question, "should the extreme corner be clamped, or reported?". It is reported. Inside the declared bounds it is exactly zero, with the smallest margin on the semi-natural class, which both artificialisation and afforestation draw on; a bound loosened without checking this number would silently start taking hectares out of a class that does not have them.

forest_production_2050forest_production * forest_production_factorm³/ha/y—
forest_mortality_2050forest_mortality * forest_mortality_factorm³/ha/y—
forest_volume_balance(forest_production_2050 - forest_mortality_2050) * forest_production_area - land_setting_harvest * forest_harvest_volume_factorMm³/y

Production less mortality less removals — the volume the forest gains in a year. It is the quantity every argument about the forest is really about, and it has roughly halved in a decade as mortality doubled. Negative means the standing stock is falling.

forest_removal_rateland_setting_harvest * forest_harvest_volume_factor / (forest_production_2050 * forest_production_area)fraction of gross production

Removals over gross production, the ratio the forestry debate is usually conducted in. Quote it with its base: the same forest is at 60% on the inventory's production and at 70% on the industry's "availability", and the two numbers are not comparable.

forest_volume_balance_2024(forest_production - forest_mortality) * forest_production_area - forest_harvest_base * forest_harvest_volume_factorMm³/y

The same balance on base-year quantities: no climate factor, and the inventory's own harvest — 19.9 Mm³/y in France, against the +19.5 IGN measures. It is the point the living-biomass line is anchored at: the inventory's pair sets the level there, and the marginal coefficient carries it to 2050. Its quantities are IGN's 2014–2022 means, so the point is the campaign's median year, 2018, under the base year's label: the inventory's 2024, extrapolated on a mortality still rising, splits the same total differently (forest_dead_wood_coefficient).

forest_carbon_growthforest_carbon_k + (forest_carbon_ratio_base - forest_carbon_k) * forest_volume_balance_2024 / (forest_production * forest_production_area)tCO₂/m³

What a cubic metre of gross production stores in the living trees. It is derived, not declared: the marginal forest_carbon_k, which a cubic metre cut or dead takes with it, plus what the inventory's own pair says the living biomass gains beyond that, spread over the base year's gross production. In France that is 1.5 plus 0.11, 1.61 tCO₂/m³. The inventory measures 39 MtCO₂/y for a 19.5 Mm³/y balance, 2.0 per cubic metre of balance, while a cubic metre taken out of the stock moves the sink by 1.5: the two fit only if growth stores more per cubic metre of stem than the trees that leave take with them. A plausible reading is that growth is carried by younger trees, which hold more branch and root per cubic metre of stem, and by the stems that cross the inventory threshold each year. Put on growth, the excess falls with production in the harsher climate cases. Where a package's ratio and its k are the same number, this is k and the line is proportional.

land_sink_forest_biomassforest_carbon_k * forest_volume_balance + (forest_carbon_growth - forest_carbon_k) * forest_production_2050 * forest_production_areaMtCO₂/y absorbed

g·P·A − k·(M·A + H): what grows, less what dies and what is cut. k — forest_carbon_k — is what a cubic metre leaving the living stock takes with it, cut or dead alike, and it is the marginal: the response of this pool to one cubic metre more harvested, or one more killed by the climate. g — forest_carbon_growth — is what a cubic metre of growth stores, derived so that the base year is the inventory's own pair, forest_carbon_ratio_base times the base-year balance, to the bit. The level comes from the inventory and the slope from the projections, and they are declared apart because the evidence for them is not the same. Until stage B one coefficient did both, k · (P·A − M·A − H), and no single number can: in the same document the inventory's ratio of sink to balance is 1.51 over 2005–2013 and 2.00 over 2014–2022. The projections the climate cases come from move this pool by 1.44 to 1.56 tCO₂ per cubic metre harvested, on their 2020–2050 means, and the span they publish between their mildest and their severest case at a constant harvest, about 51 MtCO₂/y in 2045–2050, is what 1.5 gives on this identity's own balance. Two things k is not. It is not the response of the land account: a cubic metre not harvested also never enters the wood-products pool, so the whole sink moves by k less that pool's share. And it is not a price: nothing here says what happens to the wood that is not cut, which the scoreboard answers separately, by charging a scenario that leans on its land for more than its own strategy does.

land_sink_forest_dead_wood_2024forest_dead_wood_coefficient * forest_mortality * forest_production_areaMtCO₂/y absorbed

The dead-wood sink of the base year: what the inventory added to the forest line in its 2025 edition, when it began to model dead wood explicitly from the observed mortality, and what the pool is calibrated on.

forest_dead_wood_retentionland_module_active * 0.5 ** (land_horizon_years / forest_dead_wood_half_life) + (1 - land_module_active)fraction

What is left at the horizon of a tonne of dead wood from the base year: 0.5 ^ (years / half-life), the wood-products idiom with the dead wood's own half-life. At 26 years and a half-life of ten it is 0.165 — five sixths of today's dead wood is gone by 2050. It is 1 where the land module is switched off, so that a package that does not carry the module still reproduces its base year.

land_sink_forest_dead_woodforest_dead_wood_retention * (land_sink_forest_dead_wood_2024 + forest_carbon_k * (forest_mortality_2050 - forest_mortality) * forest_production_area)MtCO₂/y absorbed

Dead wood as a first-order stock, in the closed form of the wood-products pool: with a constant inflow from the base year on, the horizon flux is retention × (base-year flux + change in inflow). The change in inflow is the change in mortality at the living pool's marginal k, so that a tree that dies leaves one pool and enters the other with the same carbon, and the stock itself drops out. Today's sink is a transient. It was about 10 MtCO₂/y at the campaign's median year, 2018, and the inventory puts it at 22.6 in 2024, because mortality doubled in a decade and the dead wood has not caught up. The closed form books the 2050 mortality from 2025, so the central case's step from 16.6 to 23.2 Mm³/y stands in for the rise the inventory already sees by 2024; in 2050 the two readings differ by 0.3. The inventory itself calls it a buffer, which the forest gives back by oxidation as mortality comes down, and the study the climate cases come from decomposes it with a half-life of ten years. At constant mortality the pool fills and stops absorbing; a climate case that kills more trees refills it only by what has not decomposed by 2050 — 2.1, 3.3 or 4.9 MtCO₂/y from the mildest case to the severest, where until stage B this line gave 11, 14 and 18 and never decayed. Harvest residues are not in the inflow: the study counts them, and finds that the management scenario hardly moves this pool.

land_sink_forest_afforestationafforestation_storage_rate * land_setting_afforestation * max(0, land_horizon_years - afforestation_lag) / 1000MtCO₂/y absorbed

New forest, booked at the expansion storage rate on the hectares planted more than the establishment lag before the horizon. Hectares planted later store nothing here — a step where the truth is a curve, and the honest alternative was a curve nobody published.

land_sink_forestland_sink_forest_biomass + land_sink_forest_dead_wood + land_sink_forest_afforestation + forest_litter_soil_sink + forest_overseas_sink - land_peat_forestMtCO₂/y absorbed—
hwp_inflow_2024forest_harvest_base * hwp_long_lived_share_base * hwp_carbon_per_m3MtCO₂/y

The carbon that entered the long-lived wood-products pool in the base year: the base-year harvest, times the share that became sawn timber and panels, times the carbon a cubic metre of that share carries. The coefficient is derived so that this reproduces the national inventory report's own inflow, 10.0 MtCO₂/y, and it lands within half a per cent of the IPCC's default carbon density of sawnwood without having been fitted to it.

hwp_inflowland_harvest_long_lived * hwp_carbon_per_m3MtCO₂/y—
hwp_decay_rateln_two / hwp_half_life1/y—
hwp_stock_2024(hwp_inflow_2024 - hwp_base_sink) / hwp_decay_rateMtCO₂

The stock the pool must hold for the base year to balance: a first-order pool releases k · stock a year, so a pool that takes in 10.0 MtCO₂ and is measured as a source of 0.4 holds (10.0 + 0.4) / k. It is derived from the base-year balance rather than declared, which is what makes the base-year check hold by construction — and it is reported beside the stock the inventory report's own outflows imply, hwp_stock_nir_2021, which is a fifth smaller because the two inventory vintages do not agree on the sign of the 2021 balance.

hwp_retention0.5 ** (land_horizon_years / hwp_half_life)fraction

What is left of a tonne put into the pool at the base year by the horizon: 0.5 ^ (years / half-life), which is e^(−k·T) written with the half-life a reader knows. At 26 years and a half-life of 28.9 it is 0.536 — roughly half of what stands today is still standing in 2050, and roughly half of what is added between now and then.

hwp_stock_2050hwp_stock_2024 * hwp_retention + hwp_inflow / hwp_decay_rate * (1 - hwp_retention)MtCO₂

The first-order-decay stock at the horizon, in closed form for a constant inflow from the base year on: what remains of the base-year stock, plus what the horizon inflow has built towards its own equilibrium inflow / k. A constant inflow is the assumption to name — the lever is a 2050 setting and the model has no trajectory to integrate — and it errs on the side of a larger stock for a rising harvest, because it books the 2050 inflow from 2025.

hwp_decay_2050hwp_decay_rate * hwp_stock_2050MtCO₂/y—
land_sink_hwphwp_inflow - hwp_decay_2050MtCO₂/y absorbed

Harvested wood products as a stock, since stage E: the inflow of long-lived products less the decay of everything already standing, at the horizon. With a constant inflow the closed form collapses to retention × (inflow − base-year inflow + base-year balance), so the stock itself drops out of the flux — which is why the base stock is derived rather than fetched — and the pool responds to the change in what is put in, damped by half over the horizon. That damping is what the flow reading of stage A lacked: at the reference it gives 2.5 MtCO₂/y where the flow gave 3.0, and hwp_flow_reading keeps the old figure beside it. Raising the harvest and the long-lived share together is still the one move that deepens this pool and the wood supply at once.

hwp_flow_readinghwp_coefficient * (land_setting_harvest * land_setting_long_lived - forest_harvest_base * hwp_long_lived_share_base) + hwp_base_sinkMtCO₂/y absorbed

The stage-A flow reading of the same pool — a coefficient on the change in long-lived volume plus the base-year balance — kept as a comparison line and read by nothing else. It overstates the 2050 flux by the decay of what is added, which the stock reading carries.

hwp_stock_checkhwp_stock_2024 - hwp_stock_nir_2021MtCO₂

The derived base-year stock less the stock the inventory report's own 2021 outflows imply. Positive, and not meant to be zero: the balance this model is held to is the 2026 vintage's, which books a source where the 2023 report booked a sink.

land_soil_practice_gain(soil_practice_potential_arable + soil_practice_potential_grassland) * land_setting_soil_practicesMtCO₂/y absorbed

The identified soil-carbon potential, taken at the share the lever asks for, split between the two land uses it sits on. Reduced tillage is deliberately excluded: the study that sizes the potential calls it a redistribution down the soil profile rather than a gain, and including it would add about a seventh. The headline "4 per 1000" figure quoted in public is larger still, because it counts no-till and forest land together; this one is the agricultural part without them, and the split between arable and grassland follows the itemised practices rather than the areas they sit on.

land_soil_conversion_flux(max(0, land_setting_grassland) * soil_carbon_grass_to_crop - max(0, -land_setting_grassland) * soil_carbon_crop_to_grass) * min(land_horizon_years, soil_carbon_conversion_years) / 1000MtCO₂/y emitted

The soil-carbon tail of ploughing grassland, or of putting arable land back to grass. Only the last twenty years of conversions are still in the flux at the horizon, and the two directions carry different coefficients — loss is about twice as fast as gain, so re-grassing repairs more slowly than ploughing broke. Written with two max terms rather than a conditional so that nothing branches: at a conversion of zero both terms are zero, which is where the reference scenario sits. It is booked on top of the per-hectare cropland and grassland coefficients, and only for the change the player makes: those coefficients are calibrated on a base year that already contains the historic conversions, so charging the base year twice would have been the mistake to avoid here.

land_sink_grasslandgrassland_sink_coefficient * land_grassland + soil_practice_potential_grassland * land_setting_soil_practices - land_peat_grasslandMtCO₂/y absorbed

Mineral grassland absorbs; the organic soil under part of it emits ten times as much per hectare, and which of the two wins is a national fact rather than a general one. Splitting the line is what lets the same equation carry a country whose grassland is a sink and a country whose grassland is its second largest source — and it is what stops a herd cut from raising emissions, which is what a single negative per-hectare coefficient would have done.

land_sink_cropland-(cropland_source_coefficient * land_arable) + soil_practice_potential_arable * land_setting_soil_practices - land_soil_conversion_flux - land_peat_arableMtCO₂/y absorbed

A source, not a sink, and it has been one in every year the inventory covers: arable soil loses carbon under crops, and the drained organic soils and the historic conversions are booked here too. Soil practices are what pushes back against it, and the conversion flux of a grassland decision lands here as well, because that is where the inventory puts it.

land_sink_artificial-(artificialisation_carbon_content * land_setting_artificialisation / 1000) - land_peat_artificialMtCO₂/y absorbed

Always a source. A standing emission per unit of annual flow rather than a one-off per hectare, because sealing and the biomass it removes are booked over a twenty-year tail: stop artificialising and this line goes to zero, which is exactly what the net-zero-artificialisation target claims.

land_sink_wetland-wetland_other_source - land_peat_waterMtCO₂/y absorbed—
land_sink_totalland_sink_forest + land_sink_hwp + land_sink_grassland + land_sink_cropland + land_sink_artificial + land_sink_wetlandMtCO₂/y absorbed

The six pools, added up, positive for absorption — the module's own sign, which national_natural_sink then negates once, where the national account needs it. The specification calls this quantity lulucf_absorbed; the name here follows the land_ prefix the rest of the module carries.

land_sink_forest_2024forest_carbon_ratio_base * forest_volume_balance_2024 + land_sink_forest_dead_wood_2024 + forest_litter_soil_sink + forest_overseas_sink - land_peat_forest_2024MtCO₂/y absorbed

The same lines on base-year quantities, with no climate factor and no afforestation term: the living biomass at the inventory's own pair, the dead wood at its base-year flux, and a standing forest that already contains everything planted before the base year, which the inventory's forest line already counts. This and the five pools after it are what the module is calibrated on, and the only numbers in the block that are checked against an observation rather than produced as a result. Two dates under one label, in France. The living biomass and the dead wood are read at the IGN campaign's median year, 2018, because that is where the production, mortality and removals come from; the total they are closed on, and so the litter-and-soil residual and the French Guiana line, is the inventory's 2024. The inventory splits the same total at its own 2024, after six more years of mortality: 25.5 of living biomass and 22.56 of dead wood. Re-anchoring the two pools there was measured in stage C and not taken: it would move the 2050 natural sink by −2.2 to +2.2 MtCO₂e depending on the cubic metre the inventory's mortality is converted at, which no source fixes, against a reference margin of 2.63 under its band and a pinned winner's of 2.04 (docs/forest/stage_b.md).

land_sink_hwp_2024hwp_inflow_2024 - hwp_decay_rate * hwp_stock_2024MtCO₂/y absorbed

The base-year inflow less the decay of the base-year stock, which is the published balance to the bit, because the stock was derived from it. Written out rather than restated as the constant so that the identity the stock rests on is on the page.

land_peat_arable_2024sum(land_class.land_peat_emission_2024, land_class.id == "arable")MtCO₂e/y emitted—
land_peat_grassland_2024sum(land_class.land_peat_emission_2024, land_class.id == "grassland")MtCO₂e/y emitted—
land_peat_forest_2024sum(land_class.land_peat_emission_2024, land_class.id == "forest")MtCO₂e/y emitted—
land_peat_water_2024sum(land_class.land_peat_emission_2024, land_class.id == "water")MtCO₂e/y emitted—
land_peat_artificial_2024sum(land_class.land_peat_emission_2024, land_class.id == "artificial")MtCO₂e/y emitted—
land_peat_total_2024sum(land_class.land_peat_emission_2024)MtCO₂e/y emitted—
land_sink_grassland_2024grassland_sink_coefficient * land_class["grassland"].area_2023 - land_peat_grassland_2024MtCO₂/y absorbed—
land_sink_cropland_2024-(cropland_source_coefficient * land_class["arable"].area_2023) - land_peat_arable_2024MtCO₂/y absorbed—
land_sink_artificial_2024-(artificialisation_carbon_content * artificialisation_rate_base / 1000) - land_peat_artificial_2024MtCO₂/y absorbed—
land_sink_wetland_2024-wetland_other_source - land_peat_water_2024MtCO₂/y absorbed—
land_sink_total_2024land_sink_forest_2024 + land_sink_hwp_2024 + land_sink_grassland_2024 + land_sink_cropland_2024 + land_sink_artificial_2024 + land_sink_wetland_2024MtCO₂/y absorbed—
land_sink_check_2024-land_sink_total_2024 - official_natural_sink_2024MtCO₂e/y

What the module reproduces for the base year, less what the inventory books, in the inventory's sign. It is not zero and is not meant to be: it is the rounding of the published sub-sector lines against their own published total, and a residual that had been tuned away would have told a reader nothing. Watch it after any change to the calibrated coefficients — it is the first place a mis-calibration shows.

land_harvest_long_livedland_setting_harvest * land_setting_long_livedMm³/y—
land_timber_headroomland_harvest_long_lived - construction_timber_roundwoodMm³/y

What the long-lived harvest has left for everything else made of wood — furniture, joinery, panels, packaging — once the built square metres have taken theirs. At the reference construction takes 1.8 of 18.0 Mm³; at the top of the timber slider it takes 12.2, which is two thirds of the pool. It goes negative inside the declared ranges only in one corner — the harvest at its floor and the timber share at its top, −0.2 Mm³, or −6.2 with the long-lived share at its minimum too — and where it is positive that is not reassurance: the binding constraint is not the standing harvest but the sawmill. New-building structure alone asks for 6.1 Mm³ of sawn product at the top of the slider, against a French softwood sawnwood production of about 7.0 Mm³ — and France already imports a quarter of what it uses, while the national forest inventory's own projection finds additional sawlog supply short of additional demand by one to one and a half million cubic metres a year in 2050 even under its increased-harvest cases. And imported timber does not store carbon here. The harvested-wood- products pool is kept on the production approach, so a beam sawn in Finland and bolted into a French building adds nothing to the French inventory's wood pool: the carbon is Finland's. A scenario that builds in timber on imports gets the cement saving and none of the sink. That is also why timberShare leaves the wood-products pool where it is, and a test pins it: the pool follows what French sawmills cut, which harvestToProducts sets, not what French buildings use. The 4.65 MtCO₂/y that looks unbooked at the top of the slider is the flux of a France sawing ten million cubic metres more, and that lever reaches three.

land_harvest_otherland_setting_harvest - land_harvest_long_livedMm³/y

Everything the harvest is not turning into sawn timber and panels: pulp, packaging, fuel and what is burned without being sold. Stage C converts it into a wood supply and puts it beside the game's wood demand; stage A only says how large it is.

forest_material_share_base(forest_harvest_sawlogs + forest_harvest_industrial) / forest_harvest_basefraction of the harvest

Sawlogs and industrial wood over the whole base-year harvest — the share that leaves the forest as material rather than as fuel. It is not the long-lived share: pulp and packaging are material and come back within a few years, which is why the harvested-wood-products pool reads the smaller number.

forest_unutilised_share_baseforest_harvest_unutilised / forest_harvest_basefraction of the harvest

Wood that was felled, left the live stock, and supplies nothing. Windthrow and beetle-killed stems cut and abandoned on the forest floor: the harvest statistic counts them, the forest identity must count them because the tree is no longer growing, and the boiler never sees them. A fifth row rather than a fold into the informal firewood, which was the other option and would have handed the wood supply three million cubic metres of fuel that does not exist. Zero in a country whose statistic does not report the category, and then every term below is unchanged.

land_harvest_checkforest_harvest_sawlogs + forest_harvest_industrial + forest_harvest_energy_commercial + forest_informal_firewood + forest_harvest_unutilised - forest_harvest_baseMm³/y

Zero: the four declared uses of the base-year harvest add up to the harvest. It matters because one of the four — the firewood cut and never sold — is an estimate by difference, so the closure is what makes it visible instead of leaving it inside a larger number. It is about a quarter of the whole harvest and the independent estimates of it span two and a half million cubic metres.

Livestock, crops, nitrogen and diet

Stage B of the land module. It replaces the second of the two sliders that had no driver — an agriculture sector sliding along a published trajectory between the observed year and the strategy's horizon — with a chain that runs from a plate to a herd to a field, and it makes the agriculture sector a sum of the constructive account like every other sector. Four things are worth understanding before reading the formulas. Causality runs demand → production → herd, and trade sits in the middle. What a country eats, times its population, times what it no longer wastes, is a domestic demand; what it imports is subtracted and what it exports is added; the result is production, and production divided by a yield per head is a herd. The export term is indexed on volumes rather than on a share, because a share runs away as it approaches one and because a country that exports two fifths of its milk while importing a third of the dairy it eats has no single share to move. Without it a diet change would move the herd one for one, which is wrong for every exporting country. The dairy herd sells its culls whatever the diet does. Two fifths of French beef is a by-product of the dairy herd, so the suckler herd is the residual: it supplies the beef the dairy herd did not. Cut the milk and beef still reaches the market; cut the beef and the milk decides how much of the cut the suckler herd absorbs. That coupling is in the equations rather than in a footnote, and dairy_beef_coupling_share is the one number it rests on. Nitrogen is one decision with two consequences. The mineral nitrogen the fields receive drives the soil N₂O and the urea and liming CO₂ in agriculture, and it drives the ammonia the industry chain has to make and the hydrogen that ammonia draws. Until this module those were two unconnected numbers — a fertiliser dose nobody chose and an ammonia tonnage nobody explained. They are now one lever and a domestic share. The base year is checked by source, the horizon is not. A parallel set of *_2024 equations recomputes the livestock and the crops blocks on base-year quantities with no lever at all, and the tests hold them against the published inventory line by line. Every figure in this module is traced through docs/agriculture/agriculture_food_fertilisers.md, the sourced study behind it, to the publication named in its own sources; what is cited here is that publication rather than the study, because a citation has to be findable by somebody who does not have this repository. The 2050 figures are results, and the reference scenario's is uncomfortable: at the national strategy's own settings this module lands about three megatonnes above the strategy's own 2050 agriculture figure, because the strategy reaches it through practices it does not fully publish. That gap is information, and closing it by construction would have thrown the information away.

NameFormulaUnitNotes and sources
food_setting_red_meatland_module_active * dietRedMeat + (1 - land_module_active) * diet_red_meat_basekgec/cap/y

The land module's switch applied to a lever, the same arithmetic the seven land levers use. Where land_module_active is 0 the whole food block is read at its base year, so a package that does not carry the module reports its own observed farm projected forward rather than another country's diet, and a lever hidden in that package cannot move a number. Both sides always evaluate — this is arithmetic and never a branch — so the browser engine, the Python evaluator and the solver see one expression and cannot take different paths through it.

food_setting_poultryland_module_active * dietPoultry + (1 - land_module_active) * diet_poultry_basekgec/cap/y—
food_setting_dairyland_module_active * dietDairy + (1 - land_module_active) * diet_dairy_index_baseindex, base year = 1—
food_setting_wasteland_module_active * foodWaste + (1 - land_module_active) * food_waste_cut_basefraction of edible waste removed—
food_setting_exportland_module_active * livestockExport + (1 - land_module_active) * livestock_export_baseindex, base year = 1—
food_setting_nitrogenland_module_active * nIntensity + (1 - land_module_active) * n_intensity_baseindex, base year = 1—
food_setting_legume_arealand_module_active * legumeArea + (1 - land_module_active) * legume_area_baseMha—
food_setting_entericland_module_active * entericMitigation + (1 - land_module_active) * enteric_mitigation_basefraction of cattle—
food_setting_manureland_module_active * manureMethanised + (1 - land_module_active) * manure_methanised_basefraction of manure—
food_setting_farm_fuelland_module_active * agriFuelSwitch + (1 - land_module_active) * agri_fuel_switch_basefraction of farm fuel—
food_setting_ammonia_shareland_module_active * ammoniaDomesticShare + (1 - land_module_active) * ammonia_domestic_share_basefraction—
food_setting_organicland_module_active * organicShare + (1 - land_module_active) * organic_share_basefraction of the arable area—
food_setting_crop_exportland_module_active * cropExport + (1 - land_module_active) * crop_export_baseindex, base year = 1—
plant_food_waste_factor(1 - crop_food_waste_share) / (1 - crop_food_waste_share * (1 - food_setting_waste))factor on demand

Apparent consumption is published on today's losses, so cutting waste does not cut consumption — it cuts the supply the same nutrition needs. (1 − w) / (1 − w·(1 − cut)) is that: at no cut it is one, and at a complete cut it is 1 − w. Since stage E the share w is per product: this one is the plant-food basket's, read from the wheat-to-bread chain, and the animal products carry their own in animal_product.waste_share — a fifth of the poultry that leaves the farm never reaches a plate, a tenth of the milk, a twelfth of the beef and pork. The whole-basket figure the environment statistician publishes, 7% of the supply on the European definition, is a different perimeter and is reported beside these rather than used for them.

product_waste_factor
per row of animal_product
(1 - row.waste_share) / (1 - row.waste_share * (1 - food_setting_waste))factor on demand

The same identity, on each product's own downstream loss share. It is what makes the waste lever a large lever on poultry and a small one on beef — the chain-loss study finds them two and a half times apart — where a single basket share made it the same size on everything.

food_waste_basket_sharesumproduct(animal_product.consumption_base, animal_product.waste_share) / sum(animal_product.consumption_base)fraction of the animal supply

The per-product shares weighted by what the country eats — the animal basket's own downstream loss, about 12% — for comparison with the 7% the environment statistician counts as edible waste on the whole food supply. Not an identity: the two perimeters differ, and the difference is reported rather than reconciled.

population_ratiopopulation_horizon / population_basefactor on demand

Demography is a constant here and not a lever: the module does not offer the size of the population as a choice a player makes. It moves every diet-driven quantity by about a per cent, which is small beside the diet levers and large beside the food-waste one.

demand_index_red_meatfood_setting_red_meat / diet_red_meat_base * population_ratioindex, base year = 1

Diet and population in one multiplier, one for the base year by construction; the waste factor joins it per product, below. Beef, pork and sheep meat share it because every published diet scenario moves the three together and none of them publishes a separate trajectory for sheep.

demand_index_poultryfood_setting_poultry / diet_poultry_base * population_ratioindex, base year = 1—
demand_index_dairyfood_setting_dairy / diet_dairy_index_base * population_ratioindex, base year = 1—
product_demand_index
per row of animal_product
beef: demand_index_red_meat * row.product_waste_factor
pork: demand_index_red_meat * row.product_waste_factor
sheep: demand_index_red_meat * row.product_waste_factor
poultry: demand_index_poultry * row.product_waste_factor
milk: demand_index_dairy * row.product_waste_factor
index, base year = 1

Which diet lever drives which product, written out one line per product rather than hidden in a conditional. This map is also what makes animal_product a fixed-row table: every row has to have a formula, so a country cannot quietly drop a product the account needs.

product_domestic_demand
per row of animal_product
row.consumption_base * row.product_demand_indexkt/y—
product_production
per row of animal_product
row.consumption_base * row.product_demand_index * (1 - row.import_share) + row.export_base * food_setting_exportkt/y

Domestic demand less what is imported, plus what is exported. The import share is held at the base year's — a country that eats less meat is not assumed to import a different fraction of it — while the export volume is the lever. That asymmetry is deliberate: the import share is an observed market position, and the export volume is the policy choice, because it is the one that decides whether a herd exists to feed this country or another.

product_self_sufficiency
per row of animal_product
row.product_production / row.product_domestic_demand if row.product_domestic_demand > 0 else 0fraction

Production over domestic demand. Above one the country is a net exporter of that product, below one a net importer, and the two can coexist inside one product — France exports two fifths of its milk and imports a third of the dairy it eats — which is why the ratio is reported beside the trade terms rather than instead of them.

product_production_2024
per row of animal_product
row.production_2024kt/y—
product_trade_check
per row of animal_product
row.consumption_base * (1 - row.import_share) + row.export_base - row.production_2024kt/y

Zero for every product: consumption net of imports, plus exports, is production. It is the identity the base-year trade position rests on, and it is emitted rather than assumed because the export volumes are derived from it — a country that declared all four numbers independently would find out here, and not in a footnote, that its statistics do not agree.

milk_productionsum(animal_product.product_production, animal_product.id == "milk")kt/y—
beef_productionsum(animal_product.product_production, animal_product.id == "beef")kt/y—
pork_productionsum(animal_product.product_production, animal_product.id == "pork")kt/y—
poultry_productionsum(animal_product.product_production, animal_product.id == "poultry")kt/y—
sheep_productionsum(animal_product.product_production, animal_product.id == "sheep")kt/y—
milk_per_dairy_cowanimal_product["milk"].production_2024 / livestock["dairy_cow"].heads_2024kg/head/y

Derived from the base-year production and the base-year herd rather than declared beside them, because a yield declared next to the two numbers it is the ratio of would be a third copy of the same fact and could drift from them. Every yield in this block is derived the same way.

beef_per_dairy_cowdairy_beef_coupling_share * animal_product["beef"].production_2024 / livestock["dairy_cow"].heads_2024kg/head/y

The beef a dairy cow sends to market anyway — cull cows and the calves the dairy herd does not keep. It is dairy_beef_coupling_share of the whole beef production divided by the dairy herd, so the coupling rests on that one share, which is estimated rather than published: a herd-flow account is what would replace it, and the alternative split, proportional to cow numbers, gives a very different pair of yields.

beef_per_suckler_cow(1 - dairy_beef_coupling_share) * animal_product["beef"].production_2024 / livestock["suckler_cow"].heads_2024kg/head/y—
other_cattle_per_cowlivestock["other_cattle"].heads_2024 / (livestock["dairy_cow"].heads_2024 + livestock["suckler_cow"].heads_2024)head per cow

Heifers, bullocks, calves and everything else in the herd that is neither a dairy cow nor a suckler cow, per cow. The ratio is held at the base year's: the module sizes a herd, not a herd structure, and a changed rearing pattern is a decision the model does not carry.

dairy_cowsmilk_production / milk_per_dairy_cowM head—
suckler_cowsmax(0, (beef_production - dairy_cows * beef_per_dairy_cow) / beef_per_suckler_cow)M head

The residual herd: the beef the market wants, less the beef the dairy herd sells anyway, over what a suckler cow produces. It is the line that makes a dairy-only diet cut still send beef to market, and the line that makes a beef-only cut fall hardest on the suckler herd. Floored at zero rather than allowed to go negative. The floor is reachable: a diet that cuts beef far harder than dairy asks for less beef than the dairy herd already supplies, and the honest answer there is that the suckler herd disappears and the surplus dairy beef is exported or not produced — not that the country keeps a negative number of cows. Where the floor binds, self-sufficiency in beef rises above one and says so.

other_cattle_heads(dairy_cows + suckler_cows) * other_cattle_per_cowM head—
pig_herdlivestock["pig"].heads_2024 * pork_production / animal_product["pork"].production_2024M head—
poultry_headslivestock["poultry"].heads_2024 * poultry_production / animal_product["poultry"].production_2024M head—
small_ruminant_herdlivestock["small_ruminant"].heads_2024 * sheep_production / animal_product["sheep"].production_2024M head—
livestock_heads
per row of livestock
dairy_cow: dairy_cows
suckler_cow: suckler_cows
other_cattle: other_cattle_heads
pig: pig_herd
poultry: poultry_heads
small_ruminant: small_ruminant_herd
M head

One formula per animal category, side by side, which is what makes the chain auditable: a dairy cow is sized by milk, a suckler cow by the beef the dairy herd did not supply, the rest of the cattle by the cows, and a pig, a bird and a ewe by their own product. This map is what makes livestock a fixed-row table.

livestock_heads_2024
per row of livestock
row.heads_2024M head

The base-year column, re-emitted as a result so a chart that compares the herd with the herd it started from reads both from one place instead of one from the model and one from the raw table.

cattle_base_headssum(livestock.heads_2024, livestock.species_group == "cattle")M head—
cattle_headssum(livestock.livestock_heads, livestock.species_group == "cattle")M head—
cattle_indexcattle_heads / cattle_base_headsindex, base year = 1

The cattle herd against the base year's. It is what the manure and grazing nitrogen are scaled by, and using cattle alone for all of it is an approximation: cattle are about five sixths of the nitrogen excreted here, but a scenario that cut pigs and kept cattle would be charged too much organic nitrogen. manure_nitrogen_excreted is the same quantity computed species by species and is reported beside it, so the size of the approximation is visible rather than argued about.

livestock_row_base
per row of livestock
row.livestock_heads * row.emission_factor / 1000 * (1 - food_setting_enteric * enteric_lipid_effect * row.enteric_mitigable)MtCO₂e/y

Heads times a per-head factor, less what a low-methane ration removes where one is fed. The factor covers enteric fermentation and manure management together because that is how the inventory publishes it; manure_ch4_share splits the result below, and the split is the module's, not the inventory's.

livestock_row_enteric
per row of livestock
row.livestock_row_base * (1 - row.manure_ch4_share)MtCO₂e/y—
livestock_row_manure
per row of livestock
row.livestock_row_base * row.manure_ch4_share * (1 - food_setting_manure * methanisation_abatement)MtCO₂e/y

The manure half, and the only half a digester can take. Sending manure to a digester removes methanisation_abatement of the methane the store would have released, on the share that goes there. Both coefficients are provisional, and they are the module's weakest pair: the inventory publishes enteric and manure methane as one number, so the share each species carries is an assumption rather than a measurement, and the detailed reporting tables are what would settle it.

livestock_row_emissions
per row of livestock
row.livestock_row_enteric + row.livestock_row_manureMtCO₂e/y—
livestock_enteric_emissionssum(livestock.livestock_row_enteric)MtCO₂e/y—
livestock_manure_emissionssum(livestock.livestock_row_manure)MtCO₂e/y—
livestock_emissionslivestock_enteric_emissions + livestock_manure_emissions + refrigerants_fixedMtCO₂e/y

The whole livestock block, refrigerant leakage included. The refrigerants are a constant because no lever in this module drives them and because the inventory books them inside the agriculture sector; leaving them out would break the base-year closure by exactly their own size.

livestock_row_manure_n
per row of livestock
row.manure_n_2024 * row.livestock_heads / row.heads_2024kt N/y—
manure_nitrogen_excretedsum(livestock.livestock_row_manure_n)kt N/y

The nitrogen the herd excretes, scaled species by species — the quantity the crops block approximates with a cattle index, reported here so the approximation can be measured instead of taken on trust. It is also the feedstock a digester eats, which is what stage C will read it for.

manure_nitrogen_excreted_2024sum(livestock.manure_n_2024)kt N/y—
livestock_row_grassland
per row of livestock
row.grassland_ha_per_head * row.livestock_headsMha—
grassland_requiredsum(livestock.livestock_row_grassland)Mha

The permanent grassland the herd needs, at per-head requirements calibrated so the base-year herd needs exactly the grassland the base year has. It is grassland only: the fodder maize, the cereals and the imported protein the same herd eats are not in it, and neither is temporary grassland, which the land account books inside arable land.

grassland_availableland_grassland + grassland_rough - land_class["grassland"].peat_area * land_setting_peat_rewettingMha

The land account's permanent grassland plus the rough grazing the farm survey counts and the land survey books under heath. Two statistics, reconciled in the open: the livestock block reads the farm survey's total while the land account still closes on the land survey's.

grassland_releasedgrassland_available - grassland_requiredMha

Grassland available less grassland required. Positive means a shrinking herd has freed hectares; negative means the herd asks for more grass than the land account has, which is a tension the module reports rather than resolves — nothing here plants a forest on freed grassland, and nothing forces a herd onto land that does not exist. Whether freed grassland should afforest automatically is a decision, and it is left to the land levers.

legume_creditlegume_n_credit * (food_setting_legume_area - legume_area_base) / legume_credit_spankt N/y

The mineral nitrogen the rotation no longer needs, read linearly over the span of hectares the study that measured it used. Outside that span the extrapolation belongs to the reader, and the lever's bounds are set so it is not left far outside.

mineral_nitrogenmax(0, mineral_n_base * food_setting_nitrogen * organic_nitrogen_factor - legume_credit)kt N/y

The dose the conventional fields receive, less the hectares gone organic and less the legume credit, floored at zero. It is the module's most consequential single number: it sets the soil N₂O and the urea and liming CO₂ in agriculture, and it sets the ammonia the industry chain has to make and the hydrogen that ammonia draws. Two things that were unconnected — how much nitrogen the fields get and how much hydrogen the country must produce — are one decision here.

organic_nitrogen_factor(1 - food_setting_organic) / (1 - organic_share_base)factor on the mineral dose

(1 − organic share) / (1 − base-year organic share): an organic hectare takes no mineral nitrogen, and the base-year delivery already excludes the hectares that were organic then, so only the change moves the dose. It multiplies nIntensity, which since stage E is the dose on the hectares that stay conventional; at the reference the two together deliver 55% of 2024, the strategy's −54%, without counting the organic extension twice. INRAE books −330 kt N for the same extension; this factor gives −360 at the base-year dose.

nitrogen_manure_spreadmanure_n_spread_base * cattle_indexkt N/y—
nitrogen_manure_grazingmanure_n_grazing_base * cattle_indexkt N/y—
nitrogen_fixationfixation_n_base * (1 + fixation_gain * (food_setting_legume_area - legume_area_base) / legume_credit_span)kt N/y—
nitrogen_input_totalmineral_nitrogen + nitrogen_manure_spread + nitrogen_manure_grazing + nitrogen_fixationkt N/y

Mineral, spread manure, grazing deposits and biological fixation. Atmospheric deposition is not in it — the inventory books it elsewhere — and neither is seed or irrigation nitrogen. Legumes appear twice, on purpose and in opposite directions, and the result is worth stating because it surprises people: they take mineral nitrogen out through legume_credit and put fixed nitrogen in through nitrogen_fixation, and the second is the larger. A hectare of legumes fixes more nitrogen than the mineral fertiliser it saves the next crop, so the total input rises with the legume area even as the mineral dose falls. Emissions still fall, because a tonne of mineral nitrogen is charged at more than twice what a tonne of total input costs on the indirect line — but a scenario that reads the nitrogen balance as a proxy for emissions would get the sign wrong here.

agricultural_arealand_arable + land_perm_crops + grassland_availableMha—
nitrogen_input_per_hectarenitrogen_input_total / agricultural_areakg N/ha/y

Total nitrogen input over the agricultural area — arable, permanent crops and grassland, the farm survey's grassland included. It is an input intensity and not the gross nitrogen surplus the environmental accounts publish: a surplus subtracts the nitrogen the harvest removes, and this model has no crop-offtake account to subtract with. The two are different numbers and the surplus is much the smaller — about 45 kg/ha against an input of 123 in the base year — so read this as a trend against its own base year and not against a published surplus.

crop_soil_n2o(mineral_nitrogen * ef_mineral_n2o + nitrogen_manure_spread * ef_organic_n2o + nitrogen_manure_grazing * ef_grazing_n2o + nitrogen_input_total * ef_other_crop_n2o) / 1000MtCO₂e/y

The four nitrogen sources at their own emission factors. Mineral nitrogen is charged the heaviest one, grazing deposits the next, spread manure the lightest, and the whole input again at the factor that covers residues, mineralisation, leaching and the indirect pathways. That last term is the module's largest approximation: it lumps an area-driven quantity with a nitrogen-driven one, which the inventory's detailed tables separate.

crop_fertiliser_co2mineral_nitrogen * ef_mineral_co2 / 1000MtCO₂/y

Urea hydrolysis and liming, charged on mineral nitrogen. Liming is driven by area and soil pH rather than by nitrogen, so this is a stated approximation and not a measurement of liming; it is kept on the nitrogen because the inventory publishes the two on one line.

peat_agriculture_n2o(land_class["arable"].peat_area + land_class["grassland"].peat_area) * peat_agri_n2o_ef * (1 - land_setting_peat_rewetting)MtCO₂e/y

The nitrous oxide of a drained agricultural peat soil, taken out of the nitrogen dose. The inventory books it in agriculture, not in land use, so it cannot live in the land module's peat term; and it is not a response to fertiliser — it is what a drained organic soil mineralises out of its own carbon and nitrogen — so leaving it inside ef_other_crop_n2o would have let a nitrogen cut switch off a chimney that fertiliser never lit. Rewetting is what stops it, and the whole of it stops: the emission is a drainage emission.

peat_agriculture_n2o_2024(land_class["arable"].peat_area + land_class["grassland"].peat_area) * peat_agri_n2o_ef * (1 - peat_rewetting_base)MtCO₂e/y—
digestate_emissionsbioenergy_setting_energy_maize * energy_maize_digestate_efMtCO₂e/y

The methane and nitrous oxide a digester's own store and its digestate release, per hectare of the main crop grown to feed it. The inventory gives it a line of its own inside agriculture where the practice is large enough to have one, and it is booked on the area rather than on the gas because that is the quantity the lever moves. Zero where no main crop is grown for methane, and then the line is not there.

digestate_emissions_2024energy_maize_area_base * energy_maize_digestate_efMtCO₂e/y—
crop_emissionscrop_soil_n2o + crop_fertiliser_co2 + residue_burning_fixed + crop_carbon_fixed + peat_agriculture_n2o + digestate_emissionsMtCO₂e/y—
arable_committedfood_setting_legume_area + bioenergy_setting_energy_crop + bioenergy_setting_energy_maizeMha

The arable hectares two levers have spoken for by name: the legumes in the rotation and the land growing a first-generation biofuel. Since stage E it is a readout rather than the headroom's numerator — the headroom is now the whole arable area the diet, the herd, the exports and the fuel crops need at the yield the organic share leaves, arable_needed — and it is kept because the two levers still compete for the same hectares and a reader wants to see how many. The cover crops are deliberately not here. A winter intermediate crop occupies the same hectare as the spring crop that follows it, so it commits no land; what limits it is the spring-crop area, and cive_headroom reports that separately.

crop_mineral_input_sharemineral_n_base / (mineral_n_base + manure_n_spread_base + fixation_n_base)fraction of the field nitrogen input

Mineral fertiliser's share of the nitrogen the fields receive in the base year — mineral, spread manure and biological fixation, from the module's own base-year inputs: 0.62 in France, 0.49 in Germany, where manure carries more of the load. These are national totals, grassland included. A cropland-only budget, which takes grassland's share of the fixation and the manure out and adds deposition, puts France at 0.65 to 0.71, and the stockless Seine basin at 0.76: the response here is, if anything, a little gentle — about one point of yield at the reference.

nitrogen_plateau_input1 - crop_mineral_input_share * (1 - n_yield_plateau)fraction of the base-year input

The nitrogen a conventional field receives at the plateau's edge, against the base year: the excess above n_yield_plateau removed, the manure and fixation held. The crop harvests the same there, so the field is more efficient at the edge than in the base year — which is what makes the excess an excess.

nitrogen_useful_dosemin(food_setting_nitrogen, n_yield_plateau)fraction of the base-year dose

The conventional dose, capped at the plateau: above n_yield_plateau the extra nitrogen is what the crop does not take up, and a heavier dose buys nothing — French doses sit at or above the technical optimum, and yields have risen since the 1980s on a flat or falling input.

nitrogen_input_index(1 - crop_mineral_input_share * (1 - nitrogen_useful_dose)) / nitrogen_plateau_inputindex, plateau edge = 1

The nitrogen a conventional field receives against the plateau's edge: one on the plateau, less below it, by the mineral nitrogen cut there.

crop_nue_plateaucrop_nue_base / nitrogen_plateau_inputfraction of the nitrogen input

The cropland's nitrogen use efficiency at the plateau's edge: the same harvest as the base year on less input. It fixes the hyperbola's one free parameter, Ymax = Y/(1 − NUE), at the point the curve starts from.

nitrogen_yield_factornitrogen_input_index / (nitrogen_input_index + crop_nue_plateau * (1 - nitrogen_input_index))index, base year = 1

The yield of a conventional hectare at this dose, against the base year's. Above the plateau, one. Below it, the hyperbola the GRAFS school fits to every country's cropland, Y = Ymax·F/(F + Ymax) (Lassaletta et al. 2014), passed through the plateau's edge and divided by its value there: φ/(φ + NUE·(1 − φ)), with φ the input index and NUE the efficiency at the edge. The yield falls slowly at first and faster as the input shrinks, and never to zero, because manure and fixation still feed the crop. Written so that it is exactly one on the plateau, which keeps the base year and every edition without the module bit-identical. Legumes do not move it: their credit replaces mineral nitrogen with the rotation's own and is taken off mineral_nitrogen, not off the dose.

crop_yield_index((1 - food_setting_organic) * nitrogen_yield_factor + food_setting_organic * organic_yield_ratio) / (1 - organic_share_base + organic_share_base * organic_yield_ratio)index, base year = 1

The average yield of the arable area against the base year's: the conventional hectares at nitrogen_yield_factor, the organic ones at organic_yield_ratio, over the same mix at the base-year organic share. One at the base year by construction; 0.66 with every hectare organic, whatever the dose. Two things move it, the organic share and the mineral dose below its plateau; neither the climate nor the breeding progress the strategy's own modelling assumes at +0.16% a year does, and that is a named gap rather than a number.

organic_areafood_setting_organic * land_arableMha—
crop_food_indexpopulation_ratio * plant_food_waste_factorindex, base year = 1

The plant food people eat, per person held at the base year — the module offers no plant-diet lever, so a shift to pulses and cereals is not in it and is a named gap — times the population, times what is no longer wasted downstream of the farm.

poultry_indexpoultry_heads / livestock["poultry"].heads_2024index, base year = 1—
pig_indexpig_herd / livestock["pig"].heads_2024index, base year = 1—
small_ruminant_indexsmall_ruminant_herd / livestock["small_ruminant"].heads_2024index, base year = 1—
feed_grain_indexcompound_feed_share_poultry * poultry_index + compound_feed_share_cattle * cattle_index + compound_feed_share_pig * pig_index + (1 - compound_feed_share_poultry - compound_feed_share_cattle - compound_feed_share_pig) * small_ruminant_indexindex, base year = 1

The grain the herd eats, weighted by which herd eats it: the compound-feed industry's species mix — poultry two fifths, cattle and pigs a quarter each — with the rest read as the small ruminants. Poultry is the point: a diet that swaps beef for chicken frees grassland and takes arable land, and a feed index that followed the cattle alone would have hidden it.

crop_feed_indexfeed_forage_share * cattle_index + (1 - feed_forage_share) * feed_grain_indexindex, base year = 1—
arable_base_non_energyland_class["arable"].area_2023 - energy_crop_area_base - energy_maize_area_baseMha

The base-year arable area less the base-year fuel crops — the area the four use shares are declared on, because the fuel crops are a lever of their own and enter arable_needed at the player's value.

arable_share_checkarable_share_food + arable_share_feed + arable_share_export + arable_share_other - 1fraction

Zero: the four use shares of the base-year arable area sum to one, so arable_needed equals the base-year arable area at the base-year settings. Emitted because the shares are four numbers from two statistics and the rounding of three of them was put in the fourth.

arable_need_energybioenergy_setting_energy_crop + bioenergy_setting_energy_maizeMha

The arable hectares a digester and a fuel plant take out of the food chain: the first-generation fuel crop, and the main crop grown for methane. The second is separated from the cover crops on purpose — a winter intermediate crop shares its hectare with the spring crop that follows, and a field of silage maize cut for a digester does not share anything. Both are read at the player's value, so a scenario that grows its own gas pays for it in food land here rather than nowhere.

arable_need_foodarable_base_non_energy * arable_share_food * crop_food_index / crop_yield_indexMha—
arable_need_feedarable_base_non_energy * arable_share_feed * crop_feed_index / crop_yield_indexMha—
arable_need_exportarable_base_non_energy * arable_share_export * food_setting_crop_export / crop_yield_indexMha—
arable_need_otherarable_base_non_energy * arable_share_otherMha—
arable_neededarable_need_food + arable_need_feed + arable_need_export + arable_need_other + arable_need_energyMha

The arable land this scenario's plates, herd, exports and fuel crops need, at the yield its organic share leaves — the crop block stage E added, and the module's answer to its own largest simplification, which was an arable area held at the base year while everything on it moved. Demand ÷ yield, use by use: the plant food people eat, scaled by population and waste; the feed the herd eats, scaled by the herd; the exports, scaled by their lever; fallow and seed held; the fuel crops at the player's value. The land account does not resolve the difference with land_arable: arable_headroom reports it, and a negative headroom is a diet, a herd and an export position the country's fields cannot carry at that yield.

arable_headroomland_arable - arable_neededMha

What the land account holds less what the scenario needs. Positive is arable land the fields could spare; negative is the tension the crop block exists to show, reported rather than clamped. At the reference it is 1.5 Mha short: the strategy's organic share costs 7% of the yield, its dose cut below the nitrogen plateau another 8%, and the strategy's herd gives a little of that back in feed.

crop_self_sufficiency(land_arable - arable_need_other - arable_need_energy) * crop_yield_index / (arable_base_non_energy * (arable_share_food * crop_food_index + arable_share_feed * crop_feed_index))fraction

What the arable land the account holds can grow at this yield, over what the country's own plates and herd need of it — fallow, seed and fuel crops set aside on both sides. 1.4 at the base year: France grows two fifths more than it eats, which is the cereal exporter the trade statistics describe. Below one the country would import grain to feed itself, whatever the export lever says.

crop_output_index(land_arable - arable_need_other - arable_need_energy) * crop_yield_index / (arable_base_non_energy * (1 - arable_share_other))index, base year = 1

What the fields the account holds produce, against the base year: the arable area net of fallow and fuel crops, times the yield index. It moves with the land levers and the organic share and with nothing the plates decide, which is the point of showing it beside arable_needed.

farm_fuel_emissionsfarm_fuel_2024 * (1 - food_setting_farm_fuel)MtCO₂e/y

The combustion of tractors, engines and farm boilers, taken to zero by the lever. It is booked as a named process term rather than as energy times a factor, and that is a deliberate departure from the rule the rest of the account follows. The reason is the model's own liquid fuel: efLiquid is a horizon-year assumption of about 25 gCO₂/kWh, because the model's 2050 leaves no fossil liquid, and charging farm diesel at it would put the base-year farm at about one megatonne against an inventory that measures ten and a half. The inventory measures this combustion directly, so the module books the measured quantity and lets the lever remove it. What that costs, stated rather than hidden: the roughly forty terawatt-hours of fuel behind the line are not in the model's carrier pools, so a farm that keeps burning diesel does not show up in the liquid-fuel demand the scoreboard scores. Neither does whatever replaces it — the national strategy sets the target of zero fossil fuel without publishing what carries the tractors afterwards, and inventing an electricity demand for them would be inventing a number. Both are reported as farm_fuel_energy_2024 and are the first thing stage C should close.

farm_fuel_energy_2024farm_fuel_2024 / ef_liquid_fossil_observed * 1000TWh/y

The base-year farm fuel, converted to energy at the observed emission factor of fossil liquid fuel — a diagnostic, and the size of the hole the line above describes. No equation reads it.

agriculture_livestock_postland_module_active * livestock_emissionsMtCO₂e/y

The module's switch again, this time on what reaches the constructive account. Gating the levers is not enough here: a package that does not carry the module would otherwise find three agriculture rows in its post table, computed on placeholder data, adding some seventy megatonnes to a total that is meant not to move. At zero the three rows are present, empty, and visible as such.

agriculture_crops_postland_module_active * crop_emissionsMtCO₂e/y—
agriculture_fuel_postland_module_active * farm_fuel_emissionsMtCO₂e/y—
agriculture_emissionssum(post.emissions_total, post.sector == "agriculture")MtCO₂e/y

A sum of the post table filtered on the sector, exactly as transport, building, industry and energy already are. That is the point of the three new rows: the sector total is now a sum of the constructive account and nothing else, so a missing sub-sector would be visible instead of invisible.

livestock_emissions_2024sumproduct(livestock.heads_2024, livestock.emission_factor) / 1000 + refrigerants_fixedMtCO₂e/y

The same per-head factors on the published base-year herd, with no lever and no diet: this is what the factors are calibrated on, and the only number of the livestock block that is held against an observation rather than produced as a result. It is deliberately not the chain evaluated at base-year lever positions — the chain's own agreement with the published herd is a separate identity, checked separately, and folding the two together would let a demand error hide behind a factor error.

nitrogen_input_2024mineral_n_base + manure_n_spread_base + manure_n_grazing_base + fixation_n_basekt N/y—
crop_emissions_2024(mineral_n_base * (ef_mineral_n2o + ef_mineral_co2) + manure_n_spread_base * ef_organic_n2o + manure_n_grazing_base * ef_grazing_n2o + nitrogen_input_2024 * ef_other_crop_n2o) / 1000 + residue_burning_fixed + crop_carbon_fixed + peat_agriculture_n2o_2024 + digestate_emissions_2024MtCO₂e/y—
agriculture_emissions_2024livestock_emissions_2024 + crop_emissions_2024 + farm_fuel_2024MtCO₂e/y—
livestock_check_2024livestock_emissions_2024 - citepa_livestock_2024MtCO₂e/y—
crops_check_2024crop_emissions_2024 - citepa_crops_2024MtCO₂e/y—
agriculture_check_2024agriculture_emissions_2024 - official_agriculture_2024MtCO₂e/y

What the module reproduces for the base year, less what the inventory books. It is not zero and it is not meant to be: three of the five sources are reproduced from published quantities and published implied factors, and what is left is the rounding of the published lines against their own published total. Watch it after any change to the calibrated factors — it is the first place a mis-calibration shows.

ammonia_productionmineral_nitrogen * food_setting_ammonia_share / nh3_nitrogen_fraction + ammonia_non_fertiliserkt NH₃/y

The nitrogen the fields receive, times the share made at home, divided by the nitrogen fraction of ammonia, plus the ammonia the chemical industry makes for something other than fertiliser. At the base year's nitrogen and the base year's domestic share it reproduces the tonnage the model used to carry as a free-standing lever to within a fraction of a per cent — a cross-check rather than a fit, because the domestic share comes from the fertiliser industry and the nitrogen from the inventory, and neither was chosen to land there. The consequence is that a fertiliser decision is now a hydrogen decision. At the reference nitrogen dose the ammonia demand is little more than half what the lever used to assert, and the hydrogen it draws falls with it.

ammonia_production_2024mineral_n_base * ammonia_domestic_share_base / nh3_nitrogen_fraction + ammonia_non_fertiliserkt NH₃/y—
chain_ammonia_productionland_module_active * ammonia_production + (1 - land_module_active) * ammoniaProductionkt NH₃/y

Which of the two the industry chain reads. Where the module is carried, the ammonia tonnage is derived from the nitrogen the fields ask for and the ammoniaProduction slider is retired and hidden; where it is not, the slider is the model exactly as it was. The switch is arithmetic and not a branch, which is what lets one shared equation serve both and lets the retired slider be provably inert rather than merely invisible. Restructuring the entry itself — moving the lever out of the shared model — would have been a change to the country contract, and this is the same result without one.

Bioenergy — what the land supplies

Stage C of the land module, and the last of the four first-order objects the module replaces. Three threshold rows — biogas 70/150, biofuels 40/50, wood 80/120 — were game rules: numbers the teaching team chose so the game would be playable, declared as such, and argued over in the controversy table because a resource limit that nobody sourced is a resource limit nobody has to believe. They are now computed, from the same land account, the same herd and the same forest the rest of this module already builds. What that changes is not the difficulty but the kind of statement the band makes. A player who breaches the biogas band is no longer over a rule; they are asking the country for more methane than its manure, its cover crops and its straw can make, and the panel can say which of the three would have to move. Push civeArea and the supply rises and so does the band. Push forestHarvest and the wood band rises while the forest sink falls, in the same scenario, from one identity — which is the whole reason the land account was built first. Three things a reader should know before quoting a number from here. The biogas supply carries a calibrated residual, biogas_other, which is 78% of the base year and is the module's largest declared hole; every build prints it. The residue pool is genuinely shared — a tonne of straw is either methane or a second-generation liquid and cannot be both — and residue_to_biogas_share splits it exhaustively, which a test asserts. And the good band is the domestic supply: bioImports moves the warning band and never the target, so a scenario that meets its liquid demand on imports is amber by construction.

NameFormulaUnitNotes and sources
bioenergy_setting_civeland_module_active * civeArea + (1 - land_module_active) * cive_area_baseMha

The switch idiom the whole module uses: where land_module_active is 1 the lever is read, where it is 0 the base-year value is, and both branches always evaluate so nothing about the arithmetic depends on which country is being built.

bioenergy_setting_residuesland_module_active * residueMobilisation + (1 - land_module_active) * residue_mobilisation_basefraction of the residue pool—
bioenergy_setting_energy_cropland_module_active * energyCropArea + (1 - land_module_active) * energy_crop_area_baseMha—
bioenergy_setting_energy_maizeland_module_active * energyMaizeArea + (1 - land_module_active) * energy_maize_area_baseMha

The main crop grown for a digester, on the same switch. It is a separate lever from civeArea because the two are separate facts about the land: a cover crop grows in the gap between two main crops and costs no hectare, while a field of silage maize cut for methane is that field's whole season and is booked in arable_needed as such. Where a country's digesters run on manure and cover crops alone the area is zero and every term it enters is unchanged.

bioenergy_setting_importsland_module_active * bioImports + (1 - land_module_active) * bio_imports_baseTWh/y—
manure_dm_collectablemanure_dm_per_cattle_head * cattle_heads + manure_dm_per_pig_head * pig_herdMt DM/y

The manure a digester could actually take, from the herd the food module sizes. Cattle and pigs only: poultry litter and sheep manure are outside every source's own accounting of the feedstock, and adding them at an invented coefficient would have been inventing a number. Cattle carry about nine tenths of it. A tonne of dry matter times a megawatt-hour per tonne is a terawatt-hour, so the units below need no conversion factor — that is not a coincidence but it is worth stating, because a stray thousand is the easiest error to make here.

biogas_from_manuremanure_dm_collectable * food_setting_manure * biomass_biogas_yieldTWh/y

One lever, two effects. manureMethanised removes part of the methane a manure store would have released — that is livestock_row_manure in the food module — and produces the methane a digester makes, which is this. The abatement is provisional and the supply is not: the yield per tonne is measured, the split between enteric and manure methane that the abatement rests on is not.

biogas_from_civebioenergy_setting_cive * cive_dm_yield * cive_biogas_yieldTWh/y—
biogas_from_energy_maizebioenergy_setting_energy_maize * energy_maize_dm_yield * cive_biogas_yieldTWh/y

Area × dry-matter yield × the same methane yield a tonne of green matter gives a digester. It is the largest single feedstock of the German fleet and the reason the German biogas residual is a sixth of the base year rather than three quarters of it — the feedstock is published as an area and a tonnage, so the module can build it instead of calibrating it away.

residue_dm_poolland_arable * residue_dm_yieldMt DM/y

Straw and stubble the arable area produces, whether or not anybody takes it. It follows land_arable, so ploughing grassland raises it and building on cropland lowers it — the residue supply is a consequence of the land account rather than a parameter beside it.

residue_dm_mobilisedresidue_dm_pool * bioenergy_setting_residuesMt DM/y—
biogas_from_residuesresidue_dm_mobilised * residue_to_biogas_share * biomass_biogas_yieldTWh/y—
biogas_supplybiogas_from_manure + biogas_from_cive + biogas_from_energy_maize + biogas_from_residues + biogas_otherTWh/y

Manure, cover crops, straw and a residual. The residual is 19 TWh and the base year's whole biogas consumption was 24.25, so at the base year this equation is three quarters an admission that the feedstock split is not published. At the reference the three built terms are worth about 51 TWh and the residual is unchanged, which is the right way round — the module grows what it can account for and leaves the hole the size it was.

wood_material_shareforest_material_share_base + land_setting_long_lived - hwp_long_lived_share_basefraction of the harvest

The share of the harvest that leaves the forest as material — sawn timber, panels, pulp, packaging — and therefore does not arrive at a boiler as a log. It starts at the base year's 53.3% and moves one-for-one with harvestToProducts, because a strategy that puts more of the cut into long-lived products is taking it out of the fuel pile and out of nowhere else. It is reported rather than clamped, on the land account's own rule. Inside the declared sliders it stays between 0.458 and 0.658, so neither term below can go negative; a country that widened either lever would see that in the supply before it saw it here.

wood_direct_supplyland_setting_harvest * (1 - wood_material_share - forest_unutilised_share_base) * wood_energy_per_m3TWh/y

The part of the cut that goes straight to energy: commercial fuelwood, and the firewood cut and never sold, which is about a quarter of the French harvest and is estimated by difference.

wood_byproduct_supplywood_byproduct_share * land_setting_harvest * wood_material_share * wood_energy_per_m3TWh/y

What comes back from the material half: sawmill offcuts and bark, panel residues and black liquor. It is 58% of the material harvest and about 35 TWh at the base year — bigger than the direct fuelwood in every scenario where the material share is above a half, which is every scenario the sliders reach.

wood_supplywood_direct_supply + wood_byproduct_supply + non_forest_wood + waste_woodTWh/y

The forest, plus two terms it does not produce: hedges and orchards, and end-of-life wood. Those two are 31.8 TWh and fixed, so a quarter of the wood supply answers to no lever in this game at all. There is no import line. France imports a few terawatt-hours of pellets and chips and exports about half as much again, and both are small enough beside 120 that adding a lever for them would have been decoration.

biofuel_1g_supplybioenergy_setting_energy_crop * biofuel_1g_yieldTWh/y

Area times the mix's average yield. The mix is held fixed while the area moves, which is the simplification worth naming: a sugar-beet hectare yields three times an oilseed hectare, so a scenario that wanted more beet would get a different answer from the same hectares.

biofuel_2g_supplyresidue_dm_mobilised * (1 - residue_to_biogas_share) * residue_liquid_yieldTWh/y

The other half of the residue pool, at the same 2.0 MWh a tonne the digester gets. The two are exclusive and the split is exhaustive: residue_to_biogas_share and its complement are the only claims on residue_dm_mobilised, so raising the mobilisation lever raises both bands together and nothing can be counted twice. A test asserts that the two terms add back to the pool exactly.

biofuel_domestic_supplybiofuel_1g_supply + biofuel_2g_supply + waste_fats_supplyTWh/y

Crops, straw and waste fats — everything the country's own land and bins produce. This is the good band.

biofuel_supplybiofuel_domestic_supply + bioenergy_setting_importsTWh/y

Domestic supply plus the import allowance. This is the warning band, and it is the only place in the three pools where an import appears: wood imports are small and left at zero, and no French study publishes a biomethane import at all.

biogas_headroombiogas_supply - biogas_demandTWh/y

Supply less demand, so a negative number is a scenario asking for more than the country can make. At the reference it is about −238 TWh, and that is the single most important thing this module surfaces: the game's methane demand is 308 TWh against a supply near 70. Part of it is an artefact worth naming — some 23 TWh of international air-freight fuel the source workbook classes as gas — and a large part is the methane a steam reformer turns into hydrogen. Most of it is neither, and is simply a scenario that has not electrified.

biofuel_headroombiofuel_supply - biofuel_demandTWh/y—
biofuel_domestic_headroombiofuel_domestic_supply - biofuel_demandTWh/y

The same against the domestic supply alone, which is the band the score reads. The difference between the two is exactly bioImports.

wood_headroomwood_supply - wood_demandTWh/y—
cive_headroomcive_land_ceiling - bioenergy_setting_civeMha

Cover crops against the land that could carry one. A cover crop occupies the same hectare as the spring crop that follows it, so it takes nothing from the food chain and moves no class of the land account — what limits it is how much spring cropping there is. Reported, never clamped: at the slider's maximum of 3.0 Mha against a ceiling of 4.0 it is a diagnostic and stays positive.

band_biogas_goodland_module_active * biogas_supply + (1 - land_module_active) * threshold["biogas"].goodTWh/y

The domestic biogas supply, and there is no import allowance above it — no French study publishes a biomethane import — so the warning band equals it and a scenario over the supply is straight into the red. That is deliberate: an amber band nothing can buy would be a suggestion that something can.

band_biogas_warningland_module_active * biogas_supply + (1 - land_module_active) * threshold["biogas"].warningTWh/y—
band_biofuel_goodland_module_active * biofuel_domestic_supply + (1 - land_module_active) * threshold["biofuel"].goodTWh/y

The domestic liquid supply — crops, straw and waste fats — and not the imports. This is where bioImports earns its why: it buys the amber band and never the green one.

band_biofuel_warningland_module_active * biofuel_supply + (1 - land_module_active) * threshold["biofuel"].warningTWh/y—
band_wood_goodland_module_active * wood_supply + (1 - land_module_active) * threshold["biomass"].goodTWh/y

The wood supply, and the one band that rises when the forest sink falls. Cutting more wood feeds the boiler and costs the sink, in the same scenario and from the same cubic metres, which is the coupling the whole module was built to show.

band_wood_warningland_module_active * wood_supply + (1 - land_module_active) * threshold["biomass"].warningTWh/y—
manure_dm_collectable_2024manure_dm_per_cattle_head * cattle_base_heads + manure_dm_per_pig_head * livestock["pig"].heads_2024Mt DM/y

The same pool on the published herd rather than on the modelled one. Cattle and pigs, as above.

residue_dm_pool_2024land_class["arable"].area_2023 * residue_dm_yieldMt DM/y

The residue pool on the land account's own base-year arable area. It is 57.0 Mt DM by construction — residue_dm_yield is derived as the published national tonnage over exactly this area — so what the equation shows is that the two definitions were reconciled rather than carried across.

biogas_supply_2024manure_dm_collectable_2024 * manure_methanised_2024 * biomass_biogas_yield + cive_area_base * cive_dm_yield * cive_biogas_yield + energy_maize_area_base * energy_maize_dm_yield * cive_biogas_yield + residue_dm_pool_2024 * residue_mobilisation_base * residue_to_biogas_share * biomass_biogas_yield + biogas_otherTWh/y

The base-year herd, the base-year cover-crop area, the base-year arable and the base-year mobilisation — and biogas_other, which is fitted so this closes. It therefore closes by construction, and the check below is zero by construction, which is worth saying rather than presenting as a result: what this equation demonstrates is the size of the residual, not the quality of the coefficients.

biogas_check_2024biogas_supply_2024 - sdes_biogas_2024TWh/y—
biogas_other_share_2024biogas_other / sdes_biogas_2024fraction of the base-year total

The number gap 3 exists to make impossible to forget. The share of the base year's biogas that this module cannot account for: 78%. The build prints it, the annex carries it in the residual's own why, and a test asserts that the printed figure and the model's are the same.

wood_supply_2024forest_harvest_base * (1 - forest_material_share_base - forest_unutilised_share_base) * wood_energy_per_m3 + wood_byproduct_share * forest_harvest_base * forest_material_share_base * wood_energy_per_m3 + non_forest_wood + waste_woodTWh/y

The base-year harvest at the base-year material share. Unlike the biogas one this is a real check: wood_byproduct_share is the only fitted term in it, and it is fitted on this identity, so what the residual below measures is how much the other four terms — the harvest, the material share, the conversion factor and the two fixed waste terms — miss the observed total by once the fitted one has done its work. It lands at +0.009 TWh.

wood_check_2024wood_supply_2024 - sdes_wood_2024TWh/y—
biofuel_domestic_2024energy_crop_area_base * biofuel_1g_yield + residue_dm_pool_2024 * residue_mobilisation_base * (1 - residue_to_biogas_share) * residue_liquid_yield + waste_fats_supplyTWh/y—
biofuel_supply_2024biofuel_domestic_2024 + bio_imports_baseTWh/y

The only one of the three base-year checks that nothing was fitted to. The 1G yield is the published crop areas times published yields, the 2G term shares the residue pool with the biogas one, the waste fats are observed and the imports are derived from the trade balance. It lands 0.05 TWh under the 41.7 the statistician observes — a tenth of a per cent — which is the closest thing this module has to independent evidence that the liquid coefficients are right.

biofuel_check_2024biofuel_supply_2024 - sdes_biofuel_2024TWh/y—

National reconciliation

Since v0.11.0 the game and the inventory share an accounting scope, and this module has much less to do. Both are scope 1: emissions are booked where the combustion happens, so a power station's emissions belong to the power station and not to everyone who used a kilowatt-hour. One difference remains, and it is real rather than conventional: the game includes international aviation and shipping, which the inventory reports as a memo item outside the national total. That is subtracted as its own named line. What is left is the perimeter the model does not cover at all — refining, fugitive emissions, and the sub-sectors nobody has modelled — and it stays visible rather than being divided away.

NameFormulaUnitNotes and sources
footprint_electricitysum(post.emissions_electricity)MtCO₂/y

Zero since v0.11.0, and kept as a line so the change is visible rather than silent. The game used to charge every sector the life-cycle emissions of its electricity, and this memo undid that to reach the inventory's basis. Now that the game books electricity where it is burned, there is nothing left to undo.

bunker_liquidsum(passenger.passenger_energy, passenger.in_inventory == 0) + sum(freight.freight_energy, freight.in_inventory == 0 and freight.vector == "liquid")TWh/y

International aviation and maritime shipping. Computed from the same rows the game already models, so the exclusion is a consequence of the data rather than an assertion.

bunker_gassum(freight.freight_energy, freight.in_inventory == 0 and freight.vector == "gas")TWh/y—
bunker_emissions_combustion(bunker_liquid * biofuelShare * efLiquid + bunker_gas * efGas) / 1000MtCO₂/y—
transport_combustionsum(post.emissions_combustion, post.sector == "transport")MtCO₂/y—
building_combustionsum(post.emissions_combustion, post.sector == "building")MtCO₂/y—
industry_combustionsum(post.emissions_combustion, post.sector == "industry")MtCO₂/y—
national_transporttransport_combustion - bunker_emissions_combustionMtCO₂e/y

Domestic transport only, on a combustion basis, comparable with SECTEN.

national_buildingbuilding_combustionMtCO₂e/y—
industry_perimeter_differenceofficial_industry_2024 - industry_covered_2020MtCO₂e/y

A diagnostic, not a term of the total. Until the rest of industry was modelled this was a hole in the account and had to be added back; now that all seventeen remaining manufacturing branches are in the model, what is left is a difference of perimeter and of year, and it is shown rather than absorbed. A positive value means the inventory sector is larger than what the model represents — construction and refining sit in SECTEN's industry and not in the manufacturing survey the model is built from, while the survey is a 2019 base compared with a 2024 inventory.

national_industryindustry_combustionMtCO₂e/y

No residual is added any more: every manufacturing branch is in the post table, so the sector total is a sum of the model and nothing else. See industry_perimeter_difference for what still separates it from the inventory sector.

national_agricultureland_module_active * agriculture_emissions + (1 - land_module_active) * (official_agriculture_2024 + (official_agriculture_2050 - official_agriculture_2024) * agriPathway)MtCO₂e/y

Which of the two it reads is land_module_active, the same switch the natural sink is behind. Where the food module is carried, agriculture is a sum of the post table filtered on the sector — three constructive rows, a herd, a nitrogen balance and a fuel line — and the agriPathway slider is retired and hidden; where it is not, the slider is the model exactly as it was, sliding between the observed year and the strategy's horizon. Both sides always evaluate: the switch is arithmetic and never a branch. No perimeter line is needed on either side. Agriculture has no electricity worth the detour and no international bunkers, so the game's basis and the inventory's coincide here — which is why this module lost a line when the food block arrived rather than gaining one.

national_wasteofficial_waste_2024 + (official_waste_2050 - official_waste_2024) * wastePathwayMtCO₂e/y—
national_energysum(post.emissions_combustion, post.sector == "energy")MtCO₂e/y

Computed, not taken from the SNBC. It is what the chosen electricity mix actually burns, at the emission factors the rest of the model uses — so a mix without combustion lands near zero and one leaning on biomass or methane does not. Until v0.11.0 this was a first-order trajectory sliding between two published values, which meant the sector the whole electrification story pushes emissions into was the one sector the player could not affect. What it omits. The inventory's energy branch is power generation plus refining, fugitive emissions and the rest of energy industry transformation; this is power generation and, since 0.28.0, the fossil carbon of the incinerators, because that is all the model has. Expect it to sit below the published figure for that reason and not because the mix is clean.

national_grossnational_transport + national_building + national_industry + national_agriculture + national_waste + national_energyMtCO₂e/y—
national_natural_sink-(land_module_active * land_sink_total + (1 - land_module_active) * naturalSink)MtCO₂e/y

Negated here: both of the things it can read are a magnitude absorbed, so a slider runs the way a reader expects, and the sign is applied once, where the account needs it. Which of the two it reads is land_module_active. Where the land module is carried, the natural sink is computed — seven land classes, six inventory pools and a forest identity in cubic metres — and the naturalSink slider is retired and hidden. Where it is not, the slider is the model, exactly as it was, and the computed side contributes nothing. Both sides always evaluate: the switch is arithmetic and not a branch, so the browser engine, the Python evaluator and the solver see one expression and cannot take different paths through it.

national_technological_sink-techSinkMtCO₂e/y—
national_total_sinknational_natural_sink + national_technological_sinkMtCO₂e/y

The two sinks added up, because what a net-zero claim rests on is the total and not either half. They are very different objects, though, and the dashboard keeps them visible separately: the natural sink is a forest that the official pathway expects to weaken, while the technological one is a closure residual rather than a published target.

sink_reliance-national_natural_sinkMtCO₂e/y absorbed

How much of net zero this scenario buys with the land: the natural sink as a magnitude, so it can be read against the trajectory the country's own strategy publishes for it. Scored on a line of its own, and not only inside the net, for two reasons. The two sinks are different objects — one is a forest, reversible, exposed to drought, fire and pests, and expected by the official pathways themselves to weaken; the other is a closure residual — which is the High Council on Climate's case for budgeting reversible sequestration and permanent removals separately. And the net line is hinged at zero: once a scenario crosses it, it stops reading either sink, so a player could buy the last megatonnes by cutting less wood and see no score move at all. This line has no hinge.

tech_sink_reliance-national_technological_sinkMtCO₂e/y absorbed

The engineered removals a scenario counts on, as a magnitude, so they can be read against the volume the country's own strategy plans. The natural sink has its own line; this is the other half of the High Council on Climate's recommendation to budget the two apart. Scored the way the net line is, against gross emissions and not as a percentage of its band, because the published volumes run from zero to forty-odd megatonnes and a percentage of nothing is undefined.

national_netnational_gross + national_natural_sink + national_technological_sinkMtCO₂e/y—
snbc_gross_gapnational_gross - snbc_gross_2050MtCO₂e/y

The number that matters: how far the scenario sits from the published SNBC 3 gross total. It is not zero by construction, and it is not meant to be — a large gap tells you where the scenario or the model disagrees with the national strategy.

Annualised cost layer

Real euros, no inflation, no subsidy or transfer, at full utilisation of installed capacity. For every asset the annualised cost is CAPEX × CRF(rate, lifetime) + fixed O&M + Σ(input intensity × price) + on-site CO₂ × carbon price. The governing principle is that the cost layer prices the quantities the game already shows: it never substitutes a different intensity, so where the physical description of a chain is incomplete its cost is understated by the same amount.

NameFormulaUnitNotes and sources
route_annuity
per row of cost_route
row.capex * crf(discountIndustry, row.life) + row.fixed€/t of capacity/y—
price_methane_mwhprice_methane_per_tonne / lhv_methane€/MWh—
price_coal_mwhprice_coal_per_tonne / lhv_coal€/MWh—
cost_hydrogen_electrolyticcost_route["electrolyser"].route_annuity / lhv_hydrogen + elecPriceIndustry / efficiency_electricity_to_h2€/MWh

Electrolyser annuity spread over its hydrogen output, plus the electricity it consumes at the workbook's 60% efficiency rather than the 74% POMMES uses. Hydrogen is therefore about 40% dearer here than a POMMES-native calculation gives, and everything hydrogen-based inherits that.

cost_hydrogen_smr(cost_route["smr"].route_annuity + smr_methane_per_tonne_h2 * price_methane_per_tonne + smr_electricity_per_tonne_h2 * elecPriceIndustry + smr_emission_per_tonne_h2 * carbonPrice) / lhv_hydrogen€/MWh—
cost_hydrogen_atr_ccscost_route["smr"].route_annuity / lhv_hydrogen + hydrogen_route["atr_ccs"].methane * price_methane_mwh + hydrogen_route["atr_ccs"].electricity * elecPriceIndustry + carbon_in_methane * hydrogen_route["atr_ccs"].methane * (1 - hydrogen_route["atr_ccs"].carbon_captured) * carbonPrice / 1000000€/MWh

The reformer's own cost plus the capture: no separate plant cost is declared for the capture train, so this uses the SMR annuity and adds the methane an ATR needs, which understates the capital. The carbon price applies only to what escapes.

cost_hydrogen_blendedhydrogen_route["electrolysis"].route_share * cost_hydrogen_electrolytic + hydrogen_route["smr"].route_share * cost_hydrogen_smr + hydrogen_route["atr_ccs"].route_share * cost_hydrogen_atr_ccs€/MWh

What a tonne of hydrogen costs on average, given the mix. Everything that buys hydrogen buys it at this price, which is what makes the route choice show up in the cost of steel and ammonia alike.

chain_cost_capital
per row of industry_chain
steel_bf: cost_route["steel_bf"].route_annuity
steel_dri: cost_route["steel_dri"].route_annuity
steel_eaf: cost_route["steel_eaf"].route_annuity
ammonia: cost_route["haber_bosch"].route_annuity
olefins: cost_route["methanol_to_olefins"].route_annuity + cost_route["methanol"].route_annuity * methanol_per_olefin
cement: cost_route["cement_kiln"].route_annuity * (1 - carbonCapture) + cost_route["cement_kiln_ccs"].route_annuity * carbonCapture
€/t of product—
chain_cost_variable
per row of industry_chain
steel_bf: row.coal * price_coal_mwh + row.gas * price_methane_mwh + row.electricity * elecPriceIndustry + iron_ore_per_steel_bf * price_iron_ore
steel_dri: row.hydrogen * cost_hydrogen_electrolytic + row.gas * price_methane_mwh + row.electricity * elecPriceIndustry + iron_ore_per_steel_dri * price_iron_ore
steel_eaf: row.electricity * elecPriceIndustry + scrap_per_steel_eaf * price_scrap
ammonia: industry_chain["ammonia"].electricity * elecPriceIndustry + industry_chain["ammonia"].hydrogen * cost_hydrogen_blended
olefins: row.electricity * elecPriceIndustry + row.hydrogen * cost_hydrogen_electrolytic
cement: kiln_heat_per_clinker * coal_per_kiln_heat * price_coal_per_tonne + limestone_per_clinker * price_limestone + (row.electricity + cement_capture_extra_electricity * carbonCapture / cement_capture_reference_rate) * elecPriceIndustry + carbonCapture * (cement_process_per_tonne + kiln_fuel_co2_per_tonne + kiln_biomass_co2_per_tonne) * co2_transport_storage_cost
€/t of product

Energy and feedstock. Ammonia buys its hydrogen at the mix's blended price rather than at one route's, because since v0.12.0 it no longer owns a route: the same reformers and electrolysers serve steel and everything else.

chain_cost_carbon
per row of industry_chain
row.chain_emissions_per_tonne * carbonPrice€/t of product—
chain_cost_total
per row of industry_chain
row.chain_cost_capital + row.chain_cost_variable + row.chain_cost_carbon€/t of product—
steel_outputsum(industry_chain.chain_production, industry_chain.subpost == "steel")kt/y—
steel_cost_blendedsumproduct(industry_chain.chain_production, industry_chain.chain_cost_total, industry_chain.subpost == "steel") / max(1, steel_output)€/t—
industry_cost_chainssumproduct(industry_chain.chain_production, industry_chain.chain_cost_total) / 1000M€/y—
industry_cost_food_energyfood_gas * price_methane_mwh + food_electricity * elecPriceIndustryM€/y

Food-industry heat is priced on its energy alone: the workbook does not describe its equipment, so no annuity can be attached to it.

industry_cost_totalindustry_cost_chains + industry_cost_food_energyM€/y—
cement_capture_costcement_production * carbonCapture * (cost_route["cement_kiln_ccs"].route_annuity - cost_route["cement_kiln"].route_annuity + cement_capture_extra_electricity / cement_capture_reference_rate * elecPriceIndustry) / 1000 + (cement_captured_fossil + cement_captured_biogenic) * co2_transport_storage_costM€/y

What carbonCapture adds to the clinker bill, read out of the chain cost so it can be set beside the incinerators': the capture kiln's extra annuity, its electricity, and transport and storage on every tonne it stores. Already inside industry_cost_total.

wte_capture_cost_total(wte_fossil_captured + wte_biogenic_captured) * (wte_capture_cost + co2_transport_storage_cost) + wte_capture_power * elecPriceIndustryM€/y

What wteCapture costs: the capture plants, the electricity the incinerators no longer sell, at the industrial price, and transport and storage — on the biogenic tonnes as much as on the fossil ones that lower the total.

retrofit_deep_equivalentmin(1, bldgRetrofit / deep_retrofit_saving)fraction of the stock

The average stock improvement expressed as an equivalent number of deep renovations, capped at the whole stock.

retrofit_investmentbuilding_surface_2020 * retrofit_deep_equivalent * retrofitCost * renovation_vatM€—
retrofit_annualretrofit_investment * crf(discountResidential, retrofit_life)M€/y—
heat_pump_investmentheat_pump_surface_added * heat_pump_cost_per_m2M€

Priced on the surface that actually gains a heat pump between 2020 and 2050, which the stock model now knows. The aggregate module could only charge the whole electrically heated stock, equipment already installed included.

heat_pump_annualheat_pump_investment * crf(discountResidential, heat_pump_life)M€/y—
building_energy_costbuilding_electricity * price_household_electricity + building_gas * price_household_gas + building_wood * price_woodM€/y—
building_cost_totalretrofit_annual + heat_pump_annual + building_energy_costM€/y—
building_cost_per_m2building_cost_total / building_surface_2020€/m²/y—
residential_areabuilding_surface_residentialMm²

The model's own heated surface, 3 654.9 Mm², rather than the 4 200 Mm² of total floor area ADEME reports after CEREN: the stock segments only what is heated by one of the eight systems. Cost and energy now share one denominator, which they did not before.

tertiary_areabuilding_surface_2020 - building_surface_residentialMm²—
residential_energy_costbuilding_electricity_residential * price_household_electricity + building_gas_residential * price_household_gas + building_wood_residential * price_woodM€/y

The split is now counted, not assumed: every segment carries its building type, so each vector is divided where it is actually used. The residential stock takes most of the wood and about half the gas, and a floor-area split would have misstated both. The retrofit and equipment annuities are still split by area, because one retrofit lever drives the whole stock.

tertiary_energy_costbuilding_energy_cost - residential_energy_costM€/y—
residential_cost_total(retrofit_annual + heat_pump_annual) * residential_area / building_surface_2020 + residential_energy_costM€/y—
tertiary_cost_totalbuilding_cost_total - residential_cost_totalM€/y—
residential_cost_per_m2residential_cost_total / residential_area€/m²/y—
tertiary_cost_per_m2tertiary_cost_total / tertiary_area€/m²/y—
car_vehicle_kmsum(passenger.passenger_demand / passenger.occupancy, passenger.id == "car_fuel" or passenger.id == "car_gas" or passenger.id == "car_electric")Gvkm/y—
car_fleetcar_vehicle_km * 1000000000 / km_per_car_per_yearcars—
car_fleet_ratiocar_fleet / reference_car_fleetratio—
car_ownership_costcar_ownership_reference * car_fleet_ratio€/household/y

Purchase, insurance and maintenance are deliberately technology-neutral: the electric-versus-thermal purchase premium and maintenance saving are not sourced, so they are excluded rather than guessed. Only the size of the fleet moves this block.

car_electricitysum(passenger.passenger_energy, passenger.id == "car_electric")TWh/y—
car_moleculessum(passenger.passenger_energy, passenger.id == "car_fuel" or passenger.id == "car_gas")TWh/y—
car_energy_cost(car_electricity * price_household_electricity + car_molecules * liquidFuelPrice) / households€/household/y—
transport_cost_per_householdcar_ownership_cost + car_energy_cost€/household/y—

Aviation — the price of a ticket

What decarbonised flying costs the passenger. The fuel side is computed from the same energy the emissions account charges, at a synthetic-fuel price the player sets; everything else — aircraft, crew, airport charges, maintenance — is derived from today's ticket through the fuel share of airline operating cost and held constant. That last assumption is the weak one, and it is stated rather than buried: a 2050 airline may have a different cost structure and nothing here models it.

NameFormulaUnitNotes and sources
jet_price_per_mwh_todayjet_fuel_price_2023 / lhv_kerosene€/MWh—
saf_price_per_tonnebiofuelShare * safBioPrice + (1 - biofuelShare) * safEfuelPrice€/t

The same biofuel/e-fuel split the transport module applies to every litre of liquid fuel, so the ticket and the emissions account describe the same fuel.

saf_price_per_mwhsaf_price_per_tonne / lhv_kerosene€/MWh—
flight_distance
per row of flight_type
row.pkt_2023 / row.pax_2023 * 1000km

Passenger-kilometres divided by passengers, one way.

flight_energy_today
per row of flight_type
row.flight_distance * passenger[row.game_row].unit_consumption / passenger[row.game_row].occupancy / 100kWh per passenger—
flight_energy_2050
per row of flight_type
row.flight_distance * passenger[row.game_row].unit_consumption_2050 / passenger[row.game_row].occupancy / 100kWh per passenger—
flight_fuel_cost_today
per row of flight_type
row.flight_energy_today / 1000 * jet_price_per_mwh_today€ per passenger—
flight_ticket_today
per row of flight_type
row.flight_fuel_cost_today / fuelShareOperating€ per passenger

Not an observed fare: the fuel bill grossed up by the fuel share of operating cost. It carries no margin, no tax and no yield management, so it is a cost, not a price, and it will sit below what a traveller actually pays on a route with high margins and above it on a route sold at a loss.

flight_non_fuel_cost
per row of flight_type
row.flight_ticket_today - row.flight_fuel_cost_today€ per passenger—
flight_fuel_cost_2050
per row of flight_type
row.flight_energy_2050 / 1000 * saf_price_per_mwh€ per passenger—
flight_ticket_2050
per row of flight_type
row.flight_non_fuel_cost + row.flight_fuel_cost_2050€ per passenger—
flight_ticket_ratio
per row of flight_type
row.flight_ticket_2050 / row.flight_ticket_today×—
flight_co2_today
per row of flight_type
row.flight_energy_today / 1000 / lhv_kerosene * co2_per_tonne_kerosene * 1000kgCO₂ per passenger

Combustion of the kerosene only. It excludes the upstream fuel chain and the non-CO₂ effects of aviation — contrails and nitrogen oxides — which several studies put at the same order of magnitude again.

flight_co2_2050
per row of flight_type
row.flight_energy_2050 * efLiquid / 1000kgCO₂ per passenger—
aviation_energysum(passenger.passenger_energy, passenger.aviation == 1)TWh/y—
aviation_fuel_billaviation_energy * saf_price_per_mwhM€/y

What the scenario's aviation fuel costs the sector as a whole, at the same price the tickets use.

Building usages other than heating

Space heating is about half of what a building consumes. This is the other half: hot water, cooking, air conditioning, and the specific electrical uses — lighting, appliances, screens, and the servers behind them. It carries no stock and no technology choice; each usage is its observed energy carried to 2050 and moved by an efficiency lever, a growth lever, or both. That is a weaker model than the heating one and deliberately so: the alternative was to leave 240 TWh of building energy out of the account entirely, which is what the model did until 0.8.0.

NameFormulaUnitNotes and sources
usage_factor
per row of building_usage
dhw_residential: 1 - usageDhwEfficiency
dhw_tertiary: 1 - usageDhwEfficiency
cooking_residential: 1 - usageCookingEfficiency
cooking_tertiary: 1 - usageCookingEfficiency
cooling_residential: 1 + usageCoolingGrowth
cooling_tertiary: 1 + usageCoolingGrowth
specific_residential: (1 - usageSpecificEfficiency) * (1 + usageSpecificGrowth)
specific_tertiary: (1 - usageSpecificEfficiency) * (1 + usageSpecificGrowth)
other_tertiary: 1
multiple of the observed year

Efficiency and growth act on the same usage and pull against each other, which is the point of carrying both. Cooking and hot water get efficiency only; cooling gets growth only, because nothing suggests a French air-conditioning stock that shrinks.

usage_electric_efficiency
per row of building_usage
dhw_residential: dhw_efficiency_electric
dhw_tertiary: dhw_efficiency_electric
cooking_residential: cooking_efficiency_electric
cooking_tertiary: cooking_efficiency_electric
default: 1
service per MWh—
usage_fuel_efficiency
per row of building_usage
dhw_residential: dhw_efficiency_fuel
dhw_tertiary: dhw_efficiency_fuel
cooking_residential: cooking_efficiency_fuel
cooking_tertiary: cooking_efficiency_fuel
default: 1
service per MWh—
usage_electric_target
per row of building_usage
dhw_residential: usageDhwElectric
dhw_tertiary: usageDhwElectric
cooking_residential: usageCookingElectric
cooking_tertiary: usageCookingElectric
default: -1
fraction of the service

Only hot water and cooking can be switched. Cooling and the specific electrical uses are already electric, and the tertiary "other" row is too heterogeneous to claim anything about.

usage_fuel_base
per row of building_usage
row.gas + row.heat + row.liquid + row.woodTWh/y—
usage_service
per row of building_usage
(row.electricity * row.usage_electric_efficiency + row.usage_fuel_base * row.usage_fuel_efficiency) * row.usage_factorservice units

What the usage actually delivers — hot water, hot pans — rather than what it consumes. Efficiency and growth act here, before the choice of carrier.

usage_electricity
per row of building_usage
row.usage_service * row.usage_electric_target / row.usage_electric_efficiency if row.usage_electric_target >= 0 else row.electricity * row.usage_factorTWh/y

Where a target exists, the electric share of the service divided by the electric route's efficiency. Where it does not, the observed electricity carried forward.

usage_fuel_energy
per row of building_usage
row.usage_service * (1 - row.usage_electric_target) / row.usage_fuel_efficiency if row.usage_electric_target >= 0 else row.usage_fuel_base * row.usage_factorTWh/y

The service left to the fuels, at the fuel route's efficiency.

usage_fuel_scale
per row of building_usage
row.usage_fuel_energy / row.usage_fuel_base if row.usage_fuel_base > 0 else 0multiple of the observed fuel mix

What is left to the fuels keeps the proportions it has today — gas, oil and LPG in the ratio observed — because nothing here says which of them goes first.

usage_gas
per row of building_usage
(row.gas + row.heat) * row.usage_fuel_scaleTWh/y

District heat is folded in here. The model has no heat carrier outside the heating module, and its networks are majority gas, so this is the least wrong home for 2.8 TWh — stated rather than buried.

usage_liquid
per row of building_usage
row.liquid * row.usage_fuel_scaleTWh/y—
usage_wood
per row of building_usage
row.wood * row.usage_fuel_scaleTWh/y—
usage_energy
per row of building_usage
row.usage_electricity + row.usage_gas + row.usage_liquid + row.usage_woodTWh/y—
usages_electricity_residentialsum(building_usage.usage_electricity, building_usage.segment == "residential")TWh/y—
usages_electricity_tertiarysum(building_usage.usage_electricity, building_usage.segment == "tertiary")TWh/y—
usages_gas_residentialsum(building_usage.usage_gas, building_usage.segment == "residential")TWh/y—
usages_gas_tertiarysum(building_usage.usage_gas, building_usage.segment == "tertiary")TWh/y—
usages_liquid_residentialsum(building_usage.usage_liquid, building_usage.segment == "residential")TWh/y—
usages_liquid_tertiarysum(building_usage.usage_liquid, building_usage.segment == "tertiary")TWh/y—
usages_wood_residentialsum(building_usage.usage_wood, building_usage.segment == "residential")TWh/y—
usages_wood_tertiarysum(building_usage.usage_wood, building_usage.segment == "tertiary")TWh/y—
usages_energy_totalsum(building_usage.usage_energy)TWh/y—
usages_energy_dhwsum(building_usage.usage_energy, building_usage.usage == "dhw")TWh/y—
usages_energy_cookingsum(building_usage.usage_energy, building_usage.usage == "cooking")TWh/y—
usages_energy_coolingsum(building_usage.usage_energy, building_usage.usage == "cooling")TWh/y—
usages_energy_specificsum(building_usage.usage_energy, building_usage.usage == "specific")TWh/y—

Electricity supply

The mix follows the demand rather than standing beside it: whatever electricity the rest of the model turns out to need is served by the share structure of one of RTE's six 2050 scenarios. Choosing a scenario answers "with what", never "how much". Capacity follows from energy through a load factor, and what has to be built each year follows from capacity through a lifetime — a fleet of that size has to be renewed at that rate, and it is the build rate rather than the standing fleet that consumes materials. The result feeds the material account, which is why the seven build-rate sliders it used to carry are gone. This does not check that the mix works. There is no hourly balance, no adequacy calculation and no storage: a 100%-renewable share structure is applied here exactly as a nuclear-heavy one is. The winter peak the building module computes is still a demand-side number that nothing on this side has to meet.

NameFormulaUnitNotes and sources
generation_share
per row of generation_technology
nuclear: sum(rte_scenario.nuclear, rte_scenario.scenario_index == rteScenario)
pv_ground: sum(rte_scenario.pv_ground, rte_scenario.scenario_index == rteScenario)
pv_roof: sum(rte_scenario.pv_roof, rte_scenario.scenario_index == rteScenario)
wind_onshore: sum(rte_scenario.wind_onshore, rte_scenario.scenario_index == rteScenario)
wind_offshore_fixed: sum(rte_scenario.wind_offshore_fixed, rte_scenario.scenario_index == rteScenario)
wind_offshore_floating: sum(rte_scenario.wind_offshore_floating, rte_scenario.scenario_index == rteScenario)
hydro: sum(rte_scenario.hydro, rte_scenario.scenario_index == rteScenario)
bioenergy: sum(rte_scenario.bioenergy, rte_scenario.scenario_index == rteScenario)
gas_turbine: sum(rte_scenario.gas_turbine, rte_scenario.scenario_index == rteScenario)
combined_cycle: sum(rte_scenario.combined_cycle, rte_scenario.scenario_index == rteScenario)
fraction of supply

The selected scenario's row, picked by a filtered sum over the one row whose index matches the lever.

generation_share_totalsum(generation_technology.generation_share)fraction

The declared shares are rounded, so they sum to one only to about six decimals. Dividing by their own total makes supply equal demand exactly rather than nearly, which is the difference between an identity a test can assert and one it can only approximate.

generation_share_thermal_gas
per row of generation_technology
row.generation_share / generation_share_total / row.thermal_efficiency if row.thermal_efficiency > 0 and row.fuel_carrier == "gas" else 0fraction of demand, per unit of fuel

Share of supply divided by thermal efficiency: how much fuel each gas plant needs per unit of national demand. Zero for anything that burns no gas.

generation_energy
per row of generation_technology
electricity_demand * row.generation_share / generation_share_total if generation_share_total > 0 else 0TWh/y—
generation_capacity
per row of generation_technology
row.generation_energy / row.load_factor / 8.76 if row.load_factor > 0 else 0GW

Energy divided by a load factor and by the 8 760 hours in a year. The load factors are RTE's own, read back out of its capacity and generation tables, and they barely move between scenarios — onshore wind 23%, offshore 41%, solar 14%.

generation_build
per row of generation_technology
row.generation_capacity * 1000 / row.lifetimeMW/y

A fleet of this size has to be renewed at this rate. It is the steady-state build, which understates the years when the fleet is still growing and overstates them once it is not — a build rate rather than a build programme, and the material account reads it as such.

generation_fuel
per row of generation_technology
row.generation_energy / row.thermal_efficiency if row.thermal_efficiency > 0 else 0TWh/y

Electricity out divided by thermal efficiency gives fuel in. Zero for everything that burns nothing, which in these scenarios is all of it bar the biomass plants and a sliver of combined cycle.

generation_switchable_fuelsum(generation_technology.generation_fuel, generation_technology.fuel_carrier == "gas")TWh/y

Every gas-fired plant. The model does not distinguish a combined cycle from an open-cycle turbine from a gas engine — RTE's categories are fuels, not machines — so it cannot claim that one of them can burn hydrogen and another cannot. A plant that burns biogas burns it in a turbine, and that turbine is as convertible as any other.

generation_gas_fuelgeneration_switchable_fuel * (1 - gasPlantHydrogen)TWh/y—
generation_hydrogen_fuelgeneration_switchable_fuel * gasPlantHydrogenTWh/y—
generation_hydrogen_electricitygeneration_hydrogen_fuel / efficiency_electricity_to_h2TWh/y

What the electrolysers would draw. It is not added to the electricity the mix has to serve: demand sets the mix and the mix would then set demand, which is a fixed point this compiler cannot express. It is reported rather than hidden. Because the switch reaches the combined cycle alone, and RTE keeps barely a percent of supply there, the number is around one TWh — small enough that leaving it out of the demand changes nothing a reader would notice.

generation_wood_fuelsum(generation_technology.generation_fuel, generation_technology.fuel_carrier == "wood")TWh/y

Biomass electricity at 25% efficiency needs four units of wood for one of power, so this is large — and it competes for the same resource the buildings burn. The scoreboard counts it.

generation_fuel_costgeneration_gas_fuel * price_methane_mwh + generation_hydrogen_fuel * cost_hydrogen_electrolyticM€/y

What the combustion plants burn, priced. Hydrogen is much the dearer of the two and the model charges it at the electrolytic price the industry module already computes — which is the point of the switch being a lever rather than an assumption.

generation_annual_cost
per row of generation_technology
row.generation_capacity * (row.capex_per_kw * crf(discountResidential, row.lifetime) + row.opex_per_kw_year)M€/y

Capital recovered over the technology's own life at the residential discount rate, plus fixed operating cost. No fuel, no carbon, no network, no storage — this is the plant, and it is the floor of what a mix costs rather than its price.

generation_total_capacitysum(generation_technology.generation_capacity)GW—
generation_total_costsum(generation_technology.generation_annual_cost) + generation_fuel_costM€/y

Plant plus fuel. Still no carbon, no network and no storage.

generation_cost_per_mwhgeneration_total_cost / electricity_demand€/MWh—
grid_emission_factornational_energy / electricity_demand * 1000 if electricity_demand > 0 else 0gCO₂/kWh

What a kilowatt-hour actually carries, derived from the fuel the mix burns rather than declared. It replaced a 40 gCO₂/kWh lever in v0.11.0: under a scope-1 account the number is a result of the generation choice, and letting a player set it independently of the mix they had just chosen was the inconsistency that prompted the whole change. It is a combustion figure, not a life-cycle one — no construction, no fuel chain, no decommissioning — which is why it lands near zero for a mix that burns almost nothing, and why it is not comparable with the 80-ish gCO₂/kWh a life-cycle study reports for the same grid.

generation_renewable_sharesum(generation_technology.generation_share, generation_technology.renewable == 1)fraction—

Materials of the transition

A satellite account, and deliberately a one-way one: it reads the scenario, nothing reads it back. The steel a wind farm needs is not charged to the steel industry the model already has, the concrete is not charged to cement, and none of it emits. Wiring it back would double-count against an industry module whose output is set by its own levers, so the honest thing is to compute the demand and put it beside the supply rather than inside it. What it is for: a decarbonisation pathway is usually argued in TWh and MtCO2. This says what the same pathway weighs. Three of the numbers are worth reading against the industry module directly — the transition's steel against French steel output, its concrete against French cement.

NameFormulaUnitNotes and sources
vehicle_electric_share
per row of vehicle_type
car: carElectric
truck: truckElectric
default: row.electric_share
fraction of production

Cars and trucks follow the player's own electrification levers, which is the whole point of a satellite account that reacts to the scenario. The rest keep the share derived from the source's battery-capacity row. Note the levers are shares of demand rather than of production; over a thirty-year horizon the two converge, and the approximation is stated rather than hidden.

vehicle_battery_capacity
per row of vehicle_type
row.production_2050 * row.vehicle_electric_share * row.battery_kwh / 1000000GWh/y—
battery_capacity_vehiclessum(vehicle_type.vehicle_battery_capacity)GWh/y—
battery_capacity_totalbattery_capacity_vehiclesGWh/y

Vehicle batteries only. Grid storage had its own slider until the supply mix started following demand; at the rate the source scenario built it — 1 GWh a year against 159 in vehicles — it was rounding, and carrying a lever for it implied a precision the model does not have.

vehicle_steelsumproduct(vehicle_type.production_2050, vehicle_type.steel) / 1000000kt/y

Kilogrammes per vehicle times units per year, so 10^6 carries kg to kt.

vehicle_aluminiumsumproduct(vehicle_type.production_2050, vehicle_type.aluminium) / 1000000kt/y—
generation_steelsumproduct(generation_technology.generation_build, generation_technology.steel) / 1000kt/y—
generation_concretesumproduct(generation_technology.generation_build, generation_technology.concrete) / 1000kt/y—
generation_aluminiumsumproduct(generation_technology.generation_build, generation_technology.aluminium) / 1000kt/y—
generation_coppersumproduct(generation_technology.generation_build, generation_technology.copper) / 1000kt/y—
generation_lithiumsumproduct(generation_technology.generation_build, generation_technology.lithium) / 1000kt/y—
generation_cobaltsumproduct(generation_technology.generation_build, generation_technology.cobalt) / 1000kt/y—
generation_nickelsumproduct(generation_technology.generation_build, generation_technology.nickel) / 1000kt/y—
generation_rare_earthsumproduct(generation_technology.generation_build, generation_technology.rare_earth) / 1000kt/y—
battery_intensity_steelbattery_chemistry["lfp"].steel * batteryLfpShare + battery_chemistry["nmc_811"].steel * (1 - batteryLfpShare)t per MWh—
battery_intensity_aluminiumbattery_chemistry["lfp"].aluminium * batteryLfpShare + battery_chemistry["nmc_811"].aluminium * (1 - batteryLfpShare)t per MWh—
battery_intensity_copperbattery_chemistry["lfp"].copper * batteryLfpShare + battery_chemistry["nmc_811"].copper * (1 - batteryLfpShare)t per MWh—
battery_intensity_lithiumbattery_chemistry["lfp"].lithium * batteryLfpShare + battery_chemistry["nmc_811"].lithium * (1 - batteryLfpShare)t per MWh—
battery_intensity_cobaltbattery_chemistry["lfp"].cobalt * batteryLfpShare + battery_chemistry["nmc_811"].cobalt * (1 - batteryLfpShare)t per MWh—
battery_intensity_nickelbattery_chemistry["lfp"].nickel * batteryLfpShare + battery_chemistry["nmc_811"].nickel * (1 - batteryLfpShare)t per MWh—
battery_steelbattery_capacity_total * battery_intensity_steelkt/y—
battery_aluminiumbattery_capacity_total * battery_intensity_aluminiumkt/y—
battery_copperbattery_capacity_total * battery_intensity_copperkt/y—
battery_lithiumbattery_capacity_total * battery_intensity_lithiumkt/y—
battery_cobaltbattery_capacity_total * battery_intensity_cobaltkt/y—
battery_nickelbattery_capacity_total * battery_intensity_nickelkt/y—
construction_concrete(sum(construction_use.construction_use_cement, construction_use.cement_intensity > 0) - construction_cement_saved) / cement_per_concrete * concrete_densitykt/y

The concrete of the buildings the scenario puts up, from the cement the construction module says they carry. Converted at the cement content of a cubic metre and the density of concrete rather than at the whole-economy "béton équivalent" bookkeeping factor of 266 kg a cubic metre: that factor already absorbs mortars, renders and bagged cement, and pushing building cement through it inflates the answer by about seven tenths — enough to make a collective dwelling come out as 98% concrete by mass, which it is not.

material_steelgeneration_steel + vehicle_steel + battery_steel + construction_steel_demandkt/y—
material_concretegeneration_concrete + construction_concretekt/y—
material_aluminiumgeneration_aluminium + vehicle_aluminium + battery_aluminiumkt/y—
material_coppergeneration_copper + battery_copperkt/y—
material_lithiumgeneration_lithium + battery_lithiumkt/y—
material_cobaltgeneration_cobalt + battery_cobaltkt/y—
material_nickelgeneration_nickel + battery_nickelkt/y—
material_rare_earthgeneration_rare_earthkt/y—
french_steel_productionsum(industry_chain.chain_production, industry_chain.subpost == "steel")kt/y—
material_steel_share_of_french_steelmaterial_steel / french_steel_productionfraction

The transition's annual steel demand against what the scenario's own steel industry produces. Both move with the player, which is the comparison worth making: electrifying harder raises the steel needed and, if the output levers are left alone, does not raise the steel made.

material_concrete_vs_cementmaterial_concrete / sum(industry_chain.chain_production, industry_chain.subpost == "cement")fraction

Against clinker rather than concrete, because clinker is what the model produces and what carries the process CO2. A ratio above one is not an error: concrete is mostly aggregate, and a tonne of clinker makes several tonnes of concrete.

Cost layer — method and sources

The cost layer prices the physical flows the game already computes. It never uses a different quantity from the one shown in the emissions dashboard: if the physical description of a chain is incomplete, its cost is understated by the same amount, and that is stated rather than patched.

Whose costs these are

Almost none of this layer is German. The plant costs, the commodity prices and the conversion economics are the French package's, which took them from a France-2050 modelling study; only the two household energy prices and the VAT multiplier are German. German household electricity is 383.5 €/MWh against 267 in France and German gas 121.6 against 129.9, so the electricity-to-gas ratio a heat pump has to beat is 3.15 in Germany and 2.06 in France — and German renovation carries the full 19% VAT where France charges 5.5%. Everything else here should be read as an order of magnitude carried across a border.

Convention

Real euros, no inflation, no subsidy or tax transfer. Annualised cost = CAPEX × CRF(rate, lifetime) + fixed O&M + Σ (input × price) + CO₂ × carbon price, with CRF(r, n) = r / (1 − (1+r)−n) and full utilisation of installed capacity. Two discount rates are exposed because an industrial investor and a household do not face the same cost of capital: moving the residential rate from 4% to 8% raises the building indicator by roughly a third, entirely through the retrofit annuity.

Where the cost numbers come from

Same four classes as the model annex, with one addition: Provisional means the value is plausible and widely quoted but no primary publication has been secured, so it is exposed as a slider rather than fixed.
ParameterValueProvenanceSource
Industrial CAPEX, lifetime, fixed O&M, feedstock intensities e.g. BF-BOF 442 €/t over 25 years, 53 €/t/y; electrolyser 1 125 €/t H₂ over 11.42 years Published POMMES-INDUSTRY, Germany 2045 — conversion_investment.csv, conversion_operation.csv, conversion_factor.csv
Commodity prices 2045: methane 561 €/t, coal 99, iron ore 100, scrap 180, limestone 20 €/t Converted to €/MWh with lower heating values 13.9, 7.5 and 33.33 MWh/t Published POMMES-INDUSTRY import_hourly.csv. The default 8% discount rate is the finance_rate of the same dataset
Carbon price, 150 €/tCO₂ by default End point of a linear trajectory from 2021 Published POMMES-INDUSTRY carbon.csv
Household energy prices: electricity 260 €/MWh, gas 134 €/MWh incl. tax First half of 2025 Published SDES, gas and electricity prices, H1 2025
Wood pellets, 77.5 €/MWh Bulk pellets, 7.75 c€/kWh Published Propellet energy price index, Q2 2025
Floor area, 4 200 Mm² of which 77% residential Denominator of the €/m² indicator Published ADEME BatiZoom, after CEREN
Household car budget, 3 803 €/y: purchase 1 459, fuel 1 110, insurance 518, maintenance 564 Average household, 2017. Dispersion: 21.3% of disposable income in the lowest decile against 11.5% in the highest Published INSEE Première 1855, Budget de famille 2017
31.377 million households; 11 600 km per car per year Denominator and fleet conversion Published INSEE Focus 332 (1 January 2024) and SDES, Chiffres clés des transports 2026
VAT on renovation, 5.5% Applied to retrofit works Published Reduced rate, as used in the CSTB OptoBat cost chain
Deep-retrofit cost, 550 €/m² by default Adjustable between 200 and 900 €/m² Provisional ADEME / Batiprix order of magnitude. The primary publication has not been identified: every figure in circulation is a secondary citation. Exposed as a slider for that reason
Heat pump, 80 €/m² incl. tax over 17 years Applied to the heat-pump share of electrically heated area Provisional ADEME air-water heat pump, quoted at 60–100 €/m². The boiler it replaces is not netted out, so this overstates the incremental cost
Liquid fuel at the pump, 200 €/MWh by default Applied to biofuel, e-fuel and vehicle gas alike Provisional No 2045 source secured. This is the weakest number in the layer and it drives the household energy block directly
One deep renovation saves 60% of demand Converts the retrofit slider into a renovated floor area Game rule Needed because the building lever is an average demand reduction, not a share of the stock. At the default 30% lever this implies half the stock deeply renovated
Purchase, insurance and maintenance are technology-neutral Only fleet size moves them Game rule Explicit decision: the electric-versus-thermal purchase premium and maintenance saving are not yet sourced, so they are excluded rather than guessed

Two deliberate inconsistencies with POMMES

Electrolysis efficiency. POMMES uses 45 MWh of electricity per tonne of hydrogen, about 74%. The workbook uses 60%, and the cost layer follows the workbook so that the cost and the electricity KPI describe the same hydrogen. This makes hydrogen here roughly 40% more expensive than a POMMES-native calculation would give, and it is the single assumption to which the H₂-DRI steel and electrolytic ammonia figures are most sensitive.

Grey ammonia. The workbook gives grey ammonia a gas consumption of 0.91 MWh/t, an order of magnitude below the roughly 9 MWh/t of an SMR-based plant. That figure is kept in the energy balance for continuity but is not used for cost: the SMR-hydrogen ammonia row is priced from the POMMES reforming route instead. The workbook value should be reviewed.

Cross-check

At the reference settings the retrofit block implies about 1 220 bn€ of investment. Spread over the twenty-five years to 2045 that is close to 49 bn€ per year, against the 50 bn€ per year that I4CE's Panorama des financements climat (2025 edition) estimates is needed for building renovation by 2030. The two are built from completely different data, so the agreement is a genuine check rather than a construction.

What the cost layer omits

Freight, aviation and public transport; grid reinforcement; CO₂ transport, storage and the cost of the CO₂ feedstock for synthetic olefins; equipment for food-industry heat; cement kiln-fuel CO₂, which the physical model does not count either. Price base years are mixed — 2017 for the mobility budget, 2025 for household energy, 2045 for industrial commodities — with no deflator. Compare deltas across scenarios, not levels across sectors.

Build information and model limitations

This page is a self-contained artefact generated by Python: no server, external library or connection is required. The live calculation engine runs in the browser.

Transport and industry reproduce the workbook relationships algebraically. Building heating is an aggregate calibrated model because the workbook computes the stock bottom-up. Reference outputs are covered by automated regression tests.

The calculation is not written in this page. It is compiled from app/model/technology.yaml, app/model/countries/<CC>/<CC>.yaml and app/model/equations.yaml, which also generate the sources annex — so a value shown and a value used are the same value. A Python evaluator runs the same specification, and the test suite fails if the two ever disagree.

Three accounting defects inherited from the workbook have been corrected here and not yet at source, so the Excel edition and this page currently disagree: the blast furnace's coal was counted both as energy and inside its process factor; gas used by steel and grey ammonia was counted as a resource but charged no emissions; and two legacy transport aggregations (Transport parc 2050!J40 and General hypotheses!F22) added subtotals already counted elsewhere, inventing about 32 TWh of electricity.