Teaching model · France 2050 · v0.11.0

The Net Zero Game

Build a national 2050 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.

2050 scenario dashboard

National view aligned with SECTEN 2026 and the current SNBC 3 sector pathway.

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.

Current fuel-car travel: destination in 2050

Allocation of passenger-kilometres currently supplied by fuel cars.

Total: 100%

Passenger mobility

Current fuel-truck freight: destination in 2050

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

Total: 100%

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.

Targets

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

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 stock does

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

Steel and ammonia

Plastics and industrial heat

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 about 174 TWh today, 68 of it electricity: more than the five chains above use between them. Output and processes move separately, because the source scenario changes both at once and only one of them is decarbonisation.

Move the output slider before you judge the process one. The 2050 scenario these levers interpolate towards is a reindustrialisation: measured branch by branch it multiplies textile output by 8.5, electronics by 3.1 and mineral extraction by 2.5, while mineral chemistry falls to half and naval and aerospace to 0.56. Growth of that size is not decarbonisation. The reference scenario therefore sits at 0% output change and 100% process change — today's output, modernised processes.

Cement

How much CO₂ a kilowatt-hour carries in 2050. 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.

2050 emission factors

Observed 2020 values, for comparison: electricity 79, methane 227, liquid fuel 264, wood 27 gCO₂/kWh. Coal is fixed at 340 gCO₂/kWh because it is a property of the fuel, not a choice. Hydrogen and e-fuel carry no factor of their own — they are converted back into the electricity used to make 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 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.

The electricity mix

One of RTE's six 2050 scenarios, from M0 at 100% renewable to N03 at about half nuclear. It selects a set of shares, not a quantity: the mix is scaled to whatever electricity the rest of the model turns out to need, so this answers with what and never how much. Capacity follows from energy through a load factor, and what has to be built each year 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.

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, 2050

MaterialGenerationVehiclesBatteriesTotal

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.

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

Aviation — what a ticket costs when the kerosene is synthetic

Flight categories and traffic are the DGAC's own, for 2023. 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 2050of which fuelChangekgCO₂ todaykgCO₂ 2050

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 published objective, side by side with the sectors the model does not compute. The reconciliation that connects them to the model is under the results, on the right, because it belongs next to the number it explains.

The published inventory and the SNBC 3 objective

Official sector1990Observed 2024SNBC3 2030SNBC3 2050Model coverage
Latest observed year: 2024 is consolidated in SECTEN 2026. The 2025 figure, 359.4 MtCO₂e gross, is a proxy and remains subject to revision.

What happens to what the model does not compute

0% keeps the consolidated 2024 value; 100% reaches the current SNBC 3 2050 order of magnitude. These are inputs, not results: at 100% agriculture, waste and energy production sit exactly on the SNBC value, so three of the six national rows are a recopy of the objective they are being compared with. Read them as an assumption about the rest of the economy, not as an answer.

The industry lever is a coverage gap, 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 in it. The size of that hole is computed from the official total rather than assumed, and this lever decides only how fast it shrinks.
Official sources and scope caveats

The consolidated 2024 values come from SECTEN 2026, on the France hexagonale + Outre-mer UE perimeter.

Current sector reductions and national totals come from the SNBC 3 ministry pages.

The combined technological sink is inferred transparently as −43 MtCO₂e: −66 MtCO₂e of total 2050 absorptions less the −23 MtCO₂e natural sink. This is a closure convention, not a separately published sector target.

Earlier versions rescaled each sector by the ratio between the live game result and the workbook's own 2020 baseline. That method transferred relative change but could never reveal a sub-sector the model omits, because the omission cancels between the numerator and the denominator. It has been replaced by the line-by-line reconciliation shown under the results.

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.

The code

Everything, including the model, the sources and this page:

Tell us what is wrong

In French or in English, whichever you prefer. Bugs, remarks, a figure you disagree with, or a source we should have used and did not.

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

These prompts help teams formulate a coherent pathway without revealing a winning combination. Each strategy creates trade-offs between emissions, electricity, molecules and demand.

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
IndustryDetailed algebraic portProduction routes, vector consumption, process emissions and indirect electricityInherits some workbook accounting conventions
Building heatingCalibrated aggregateDemand, heating mix, seasonal efficiency, emissions and peakDoes not reproduce the full building-stock calculation row by row
National inventory bridgeComplete accounting perimeterSix emitting sectors, natural sink, technological sink, gross and net totalsDetailed game scopes still differ from official inventory scopes
Agriculture, energy and wasteFirst-order trajectoriesLinear interpolation from observed 2024 to the SNBC3 2050 order of magnitudeNo bottom-up physical drivers yet
Carbon sinksFirst-order trajectoriesNatural and technological absorptions are tracked separatelyThe technological sink is a transparent closure residual
Model-risk statement: this version is suitable for teaching and scenario comparison. It should not be used as an official forecasting model until the building module is ported bottom-up and the two legacy transport aggregations are resolved in the source workbook.

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. Until v0.8.0 the model left all of it out, which meant it was scoring roughly half the sector.

The data is CEREN's, as the SDES publishes it. Residential is 2024, the latest available. Tertiary is 2019, not 2020: 2020 is a Covid year in which tertiary consumption fell from 237 to 209 TWh and recovered afterwards, so using it would have built a lockdown into the 2050 baseline.

Heat-pump ambient heat is excluded. The source reports it 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 2050 and moved by efficiency, growth, or both. The alternative was to leave 240 TWh out of the account entirely.

Three gaps, named. Fuel switching in hot water and cooking is not a lever — their carrier mix is carried forward as observed, so a scenario cannot electrify a gas water heater here. Air conditioning makes a summer peak and the only peak this model constrains is a winter one, so its growth costs energy and emissions but is never scored against a capacity limit. And district heat is folded into gas, the model having no heat carrier outside the heating module — 2.8 TWh, stated rather than buried.

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. Grow the specific electrical uses by half and building emissions do not move at all — the energy sector does.

This is the convention SECTEN and the SNBC use, which is why the national reconciliation is now 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.

Until v0.11.0 it was a footprint account — every sector charged the life-cycle emissions of its electricity at 40 gCO₂/kWh. That is a legitimate convention and it answers a different question: what does this sector cause? rather than what does this sector burn? It made the game total 61.3 MtCO₂ where it is now 30.0, and it made buildings 15.6 where they are now 5.0. Neither number is wrong; they are answers to different questions, and the model now answers the one the national inventory asks.

What the grid factor is and is not. The model derives it from the mix rather than declaring it: roughly 1.7 gCO₂/kWh at the reference. That is a combustion figure — no construction, no fuel chain, no decommissioning — so it is not comparable with the 80-odd gCO₂/kWh a life-cycle study reports for 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 RTE's six 2050 scenarios, from M0 at 100% renewable to N03 at about half nuclear. Choosing a scenario answers with what, never how much.

Capacity follows from energy through a load factor — RTE's own, read back out of its capacity and generation tables, and remarkably stable between scenarios: onshore wind 23%, offshore 41%, solar 14%. What has to be built each year follows from capacity through a lifetime, on the reasoning that a fleet of that size has to be renewed at that rate. It is a build rate, not a build programme: it understates the years the fleet is still growing and overstates them once it is not.

Two splits the source does not make are made here. Solar is halved between ground and rooftop, offshore wind between fixed and floating. Both matter to the material account — a floating foundation is 480 t of steel per MW against 250 fixed — and neither is a result.

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. The winter peak the building module computes is a demand-side number that nothing on this side has to meet, and the whole question of what a renewable-heavy mix costs in flexibility is absent. The cost shown is plant only — capital recovered over each technology's own life, plus fixed operating cost. No fuel, no carbon, no network, no storage. It lands near RTE's own figure for its scenarios, which is reassuring about the arithmetic and says nothing about the omissions.

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 2050.

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 workbook’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.

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.

The game is a footprint account. It charges every sector the life-cycle emissions of the electricity it consumes, at 40 gCO₂/kWh by default. SECTEN and the SNBC are a territorial combustion inventory: power-station emissions are booked in the energy branch, at stack level. The published SNBC energy figure for 2050 implies roughly 5 gCO₂/kWh — the two numbers count different things and must not be added. The electricity footprint is therefore reported as a memo item.

International bunkers. International aviation and maritime shipping are in the game and are a memo item outside the national inventory total. 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 and what the five chains represent — see the constant industry_covered_2020 in the generated annex for that derivation and its two caveats.

First-order sectors. Agriculture, waste and energy production interpolate linearly between observed 2024 and the current SNBC 3 2050 order of magnitude. At 100% they sit exactly on the SNBC value, so those three rows are an input, not a result.

Carbon sinks. Natural and technological sinks are separate. The −43 MtCO₂e technological value closes the ministry's −66 MtCO₂e total 2050 absorption figure after subtracting the stated −23 MtCO₂e natural sink.

Emission factors — today and in 2050

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₂/kWh40 gCO₂/kWh A life-cycle factor for the 2050 French mix, construction included. Because every hydrogen and e-fuel flow is converted back into electricity, this single number sets most of the residual emissions of an electrified scenario.
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 the DGAC's 2023 traffic statistics for flights departing France: passenger-kilometres divided by passengers, category by category. It is an average over each category, so "Paris ↔ international" blends a Barcelona hop with a Tokyo sector.

Energy is the model's own aviation consumption, not a separate figure — 0.24 kWh per passenger-kilometre for domestic flights and 0.19 for long-haul. Be careful with these: the raw French statistic for 2024 is 29.3 g of kerosene per passenger-kilometre, about 0.35 kWh, because it also carries the freight in the holds and reflects actual load factors. Corrected for both, the same series gives about 19.3 g/pkm, which is the range the model sits in. 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 review behind the two sliders spans EASA, the European Commission's ReFuelEU impact assessment, the DGAC roadmap, ISAE-Supaero, ATAG's Waypoint 2050, E-Cube, the IEA, Solakivi et al. (2022), Brynolf et al. (2020) and Massol et al. (2025). Bio-jet from waste oils is the cheapest route at 600–1 900 €/t; power-to-liquid the dearest at 1 800–10 000. The defaults sit mid-range and the ranges are the honest answer, which is why they are sliders.

Efficiency. The source workbook gives 2050 aviation the same consumption per passenger-kilometre as today, so the default gain is zero. The published trajectories converge on about 1%/year — ICAO, ADEME, T&E, the UK Committee on Climate Change and the World Economic Forum's Clean Skies for Tomorrow all sit between 0.9 and 1.0. Moving the slider to 1 compounds to a 23% saving over twenty-six years, which is less than most people expect and is the point of exposing it.

What this omits

Non-CO₂ effects — contrails and nitrogen oxides — which several studies put at the same order of magnitude again as the combustion CO₂; the upstream chain of the fuel; any change in airline cost structure between now and 2050; airport and air-traffic-control investment; and the question of whether the biomass or the electricity these fuels need is available at all. The last one is not rhetorical: the scenario's aviation fuel alone is a large share of the biofuel pool the scoreboard already flags.

The traffic categories, the fuel-cost review and the efficiency trajectories were assembled in a working file that is not public. Only the derived parameters appear here, each attributed to its primary published source.

The rest of industry — how output and processes were separated

The seventeen branches below were, until this version, a single residual line in the national reconciliation: a number added back to close the account, with no energy behind it and no lever on it. They are now modelled.

Why two levers and not one

The source scenario for 2050 is not a projection. It electrifies — and it also grows output, by very different amounts branch by branch. Measured from the branch sheets' own production data: textile ×8.5, electronics ×3.1, mineral extraction ×2.5, diverse industries ×1.8, rubber ×1.8, pharmacy ×1.5, vehicles ×1.5, machinery ×1.3, non-ferrous metals ×1.1; foundry, ceramics and glass unchanged; paper ×0.86, plastics ×0.70, plastic products ×0.67, naval and aerospace ×0.56, mineral chemistry ×0.52. A single slider would let a player appear to clean up industry while quietly assuming an eightfold textile sector, so output and process are separate.

The decomposition is exact, not fitted

Energy is output × unit consumption, so it is bilinear in the two and four corners reproduce every combination exactly: E00 the observed 2019 situation, E11 the source scenario, E10 the 2050 output at 2019 processes, E01 the 2050 processes at 2019 output. Both end points are the published branch totals. The output index between them is measured, branch by branch, as the energy-weighted ratio of 2050 to 2019 production over the product rows that reproduce their own computed total — between 75% and 100% of each branch's energy, and 100% for thirteen of the seventeen.

At today's output, the 2050 processes take the electricity of these branches from 68 to 138 TWh while cutting coal and fuel oil to zero. Output growth alone would take it from 68 to 87. Both together give the source scenario's 166.

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, which in 2050 is biofuel or e-fuel by the same assumption the transport module makes. Process emissions — glass, other building materials, mineral chemistry, 2.5 MtCO₂ in 2019 falling to 1.9 — follow the same two levers.

Not represented: any lever finer than the branch group. Cross-cutting energy efficiency and waste-heat recovery both have published ceilings that would fit here — RTE puts the electricity-efficiency potential at 9.0% for paper to 31.1% for chemistry at long payback, and ADEME finds 15.6 TWh of recoverable waste heat, 7.7 of it above 100 °C — but neither is in the model yet, because applying them correctly needs the temperature split that exists at process level in the source and has not been aggregated. Stated rather than approximated.

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 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 the 2019 industry, 7.7 of it above 100 °C, out of 248 TWh of fuel — 6.3% on average, but from 1.2% in metals to 31% in paper, where drying dominates. 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 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. RTE gives no branch breakdown on the fuel side, so one ceiling applies across industry. 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/parameters.yaml and model/equations.yaml — so what is documented here and what the engine executes are the same thing. The model has 66 levers, 76 constants, 19 data tables and 290 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 … 100Game rule
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.

Biomass for heating
bldgBiomassTwh
46 TWh/y0 … 120Game rule

A target in the unit the resource constraint is written in, so it can be read straight against the biomass limit instead of being reconstructed from two shares. 46 TWh of wood delivers 39 TWh of heat at a boiler efficiency of 0.85, which is roughly what the previous scheme produced.

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.

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
13 TWh/y0 … 80Game rule

Declared in TWh so that it, the network heat pumps and the recovered heat together say how much of the network is decarbonised, and gas absorbs whatever is left.

Recovered and waste heat
districtWasteTwh
0 TWh/y0 … 60Game rule

Industrial waste heat, incineration and geothermal. It has no emission factor and adds nothing to the winter 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 from being.

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
H-DRI steel share
steelDRI
50%0 … 100Game rule
Steel production change
steelGrowth
30%-40 … 50Game rule
Green ammonia
greenAmmonia
700 kt/y0 … 1 200Workbook
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
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
Cement-demand reduction
cementReduction
10%0 … 60Game rule
Clinker ratio
clinkerRate
60%35 … 78Game rule
CO₂ capture
carbonCapture
20%0 … 95Game rule
Output of the rest of industry
otherIndustryVolume
0%0 … 100Published

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.

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
25 gCO₂/kWh0 … 250Workbook

The model assumes all 2050 methane is biomethane, so it carries a life-cycle factor rather than the 227 gCO₂/kWh of fossil natural gas. Raising this slider towards 227 shows what happens if the biomethane assumption fails.

  • Teaching workbook, "Synthesis" sheet S15 and S42
Liquid fuel (bio and e-fuel), 2050
efLiquid
25 gCO₂/kWh0 … 300Workbook

Same logic as methane: the 2050 model leaves no fossil liquid fuel, so the factor is that of biofuel and e-fuel, against 264 gCO₂/kWh for the 2020 fossil fuel it replaces.

  • Teaching workbook, "Synthesis" sheet S17 and S44
Wood, 2050
efWood
27 gCO₂/kWh0 … 60Workbook

27 gCO₂/kWh, the same figure the workbook observes for 2020, rather than the zero its 2050 column carries. The zero is the biogenic-carbon convention: burning wood emits CO₂, but the convention books it against the forest that regrew rather than against the boiler. Applying it to one year and not the other made the two ends of the model incomparable — wood appeared to decarbonise between 2020 and 2050 without anything physical changing. Holding the factor constant means a scenario that leans on wood is charged for it in both years, and moving this slider to zero still shows exactly what the convention is worth: 2.06 MtCO₂ at the reference scenario, 1.6 of it in buildings.

  • Teaching workbook, "Synthesis" sheet S16 and S43
  • The 27 gCO₂/kWh is the workbook's own 2020 value; it covers the fossil energy of the wood chain, not the combustion CO₂ the convention omits.
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
100%0 … 100Game rule
Waste pathway position
wastePathway
100%0 … 100Game rule
Natural carbon sink
naturalSink
-23 MtCO₂e/y-40 … -5Game rule

Set directly rather than as a share of a trajectory, because the number is what a reader argues about. −23 is where the SNBC 3 pathway lands, and it is a *weakening*: the French forest sink has roughly halved since 2010 as the stock ages and dieback and drought bite. Reaching the stronger end of this range means a forest growing faster than it does today, and the model does not say what it would take to get there — that is a genuine gap, and one where defensible figures are scarce.

  • SNBC 3 — puits de carbone des terres, trajectoire 2050
Technological carbon sink
techSink
-43 MtCO₂e/y-60 … -5Game rule

Set directly, for the same reason. This is the residual that closes the published national account rather than a published target, and it is the single largest assumption in the whole model: 43 MtCO₂e a year of capture and storage that nothing here builds, powers or pays for. Its cost — in euros and in the energy the capture itself consumes — is not modelled, so moving this slider is free in a way it would not be in reality.

  • Inferred 2050 closure value; see the national-reconciliation annex
Hot-water efficiency
usageDhwEfficiency
0%0 … 40Game rule
Cooking efficiency
usageCookingEfficiency
0%0 … 40Game rule
Air-conditioning growth
usageCoolingGrowth
0%0 … 300Game rule

Cooling is the one building usage certain to grow, and the model cannot score it properly: it makes a *summer* peak, and the only peak constraint here is a winter one. The number is carried and the asymmetry is stated.

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.

RTE 2050 scenario
rteScenario
41 … 6Published

Which of RTE's six 2050 mixes the scenario is built on, from M0 at 100% renewable to N03 at about half nuclear. It selects a set of shares, not a quantity: the mix is scaled to whatever electricity the rest of the model turns out to need, so choosing a scenario here answers "with what" and never "how much".

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
70 €/MWh20 … 120Published
Deep-retrofit cost
retrofitCost
550 €/m²200 … 900Provisional

No primary publication has been secured for this figure. It is exposed as a slider rather than hidden as a constant so the uncertainty is testable. Securing the CSTB renovation-gesture database is the single change that would most improve the building cost module.

  • ADEME renovation cost orders of magnitude; CSTB gesture database derived from Batiprix 2022 (used by OptoBat, not public)
Liquid fuel at the pump
liquidFuelPrice
200 €/MWh80 … 400Provisional

A 2050 pump price for biofuel and e-fuel, taxes included. No source has been secured; the aviation module now prices synthetic fuel bottom-up and is the better anchor.

  • No primary source secured — see the aviation fuel-cost table for a bottom-up range

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 electricityWorkbook
  • Teaching workbook, "General hypotheses" sheet E10
ef_electricity_202079gCO₂/kWhWorkbook
  • Teaching workbook, "Synthesis" sheet S41 and "Industry" sheet D37
ef_gas_2020227gCO₂/kWhWorkbook
  • Teaching workbook, "Synthesis" sheet S42
ef_liquid_2020264gCO₂/kWhWorkbook
  • Teaching workbook, "Synthesis" sheet S44
ef_wood_202027gCO₂/kWhWorkbook
  • Teaching workbook, "Synthesis" sheet S43
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_production9 900kt/yWorkbook

Blast-furnace route volume in 2020, split by the H-DRI lever in 2050.

  • Teaching workbook, "Industry" sheet D44
steel_eaf_base_production5 100kt/yWorkbook
  • Teaching workbook, "Industry" sheet D46
steel_bf_process_workbook1.76tCO₂ per tonne of steelWorkbook

The workbook's single direct-emission figure for the blast-furnace route. It is almost exactly the combustion of the 0.62 t of coal the same sheet charges per tonne of steel, which is why counting both was a double count. The model now subtracts the coal at the published coal factor and keeps only the remainder as a genuine process term.

  • Teaching workbook, "Industry" sheet K44
ammonia_grey_production200kt/yWorkbook
  • Teaching workbook, "Industry" sheet E42
olefin_base_production4 605kt/yWorkbook
  • Teaching workbook, "Industry" sheet D47
olefin_process_per_biogenic_share-4.3tCO₂ per tonne of olefin, per unit of biogenic shareWorkbook

The synthetic-olefin route locks CO₂ into the product. Only the biogenic fraction counts as a removal, hence the multiplication by the biogenic share rather than a flat credit.

  • Teaching workbook, "Industry" sheet K48
cement_base_production16 500kt/yWorkbook
  • Teaching workbook, "Industry" sheet E54
cement_process_per_tonne0.792541tCO₂ per tonne of clinkerWorkbook

10.2 MtCO₂ of process emissions for 12.87 Mt of clinker in 2020. This is the decarbonation of the limestone, which no change of kiln fuel can remove — only capture or a lower clinker ratio.

  • Teaching workbook, "Industry" sheet K53
food_steam_demand21.876TWh/yWorkbook
  • Teaching workbook, "Industry" sheet, steam rows 49 and 51
food_direct_heat_demand10.693TWh/yWorkbook
  • Teaching workbook, "Industry" sheet, direct-heat rows 50 and 52
food_heat_pump_cop3MWh heat per MWh electricityWorkbook
food_hydrogen0.138TWh/yWorkbook

Residual hydrogen use in the food industry, unaffected by any lever.

building_need_calibration0.652836fractionCalibrated

Surface times surfacic need overstates the stock's real heat consumption, so the workbook scales the whole 2020 account by this one coefficient to land on the observed 359.34 TWh. It is a single stock-wide calibration, not a per-segment fudge: every segment carries the same factor, so the shape of the stock is untouched and only its level is set by observation.

  • Teaching workbook, "Building heating" sheet B53
building_peak_202040GWWorkbook

The winter power drawn by electric space heating in 2020. It anchors the 2050 peak: the model computes a peak-coincident electric load for both years from the same expression and scales this figure by their ratio, so running the 2020 stock through the calculation returns 40 GW exactly. The workbook's own version did not -- it divided by the 2020 *useful heat* rather than the 2020 peak load, and returned 36.8 GW for 2020.

  • Teaching workbook, "Building heating" sheet B55
official_transport_2024125.35MtCO₂e/yPublished
official_building_202456.073MtCO₂e/yPublished
official_industry_202461.5895MtCO₂e/yPublished
official_industry_20505.60569MtCO₂e/yPublished

4% of the 1990 level, the current SNBC 3 industry reduction.

official_agriculture_202477.5259MtCO₂e/yPublished
official_agriculture_205043.6652MtCO₂e/yPublished

47% of the 1990 level.

official_waste_202415.2952MtCO₂e/yPublished
official_waste_20507.50194MtCO₂e/yPublished

45% of the 1990 level.

official_energy_202431.1849MtCO₂e/yPublished
official_energy_20503.15447MtCO₂e/yPublished

4% of the 1990 level. Note what this implies: about 3 MtCO₂e for the whole energy branch in 2050, against roughly 600 TWh of electricity. That is around 5 gCO₂/kWh at the stack — far below the 40 gCO₂/kWh life-cycle factor the game applies, because the two count different things. This contrast is the point of the national reconciliation.

official_natural_sink_2024-51.9564MtCO₂e/yPublished
official_natural_sink_2050-23MtCO₂e/yPublished

The official pathway weakens the natural sink, it does not strengthen it.

official_technological_sink_2050-43MtCO₂e/yGame rule

A transparent closure residual, not a published sector target: −66 MtCO₂e of total 2050 absorptions less the −23 MtCO₂e natural sink.

snbc_gross_205063MtCO₂e/yPublished

The published SNBC 3 gross national total for 2050, rounded.

industry_covered_202068.9MtCO₂e/yDerived

What the model now represents of the industry sector, on the inventory's combustion-plus-process basis and with 2020 emission factors. The five value chains account for 45.3 — steel 18.8, cement 13.1, food 5.8, olefins 5.8, ammonia 1.7, electricity excluded as the inventory excludes it — and the seventeen other branches for a further 23.6, from 7.9 TWh of coal, 8.3 of fuel oil, 68.8 of gas and purchased steam, 19.4 of biomass and 2.5 MtCO₂ of process emissions. Compared with the 61.6 MtCO₂e the inventory books, the model's perimeter is now slightly the larger of the two: the manufacturing survey it is built from is a 2019 base, industry emissions have fallen since, and SECTEN's industry sector also contains construction and refining, which the survey does not. The difference is reported as a diagnostic and is no longer added to anything.

fuel_efficiency_ceiling0.19792fraction of fuel savedPublished

RTE gives the fuel-side efficiency potential for industry as a whole and does not break it down by branch, so a single ceiling applies to every industrial post. The same source retains 10% as the readily achievable part; the model exposes the full 19.8% and lets the effort lever say how much of it is captured.

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_years30yearsDerived

2020, the base year of the workbook's service demand, to 2050. It is deliberately not the same anchor as the efficiency horizon: consumption per passenger-kilometre is anchored on the 2024 statistic, demand on the 2020 workbook value.

aviation_horizon_years26yearsDerived

2024, the latest year of the traffic series, to 2050.

observed_kerosene_per_pkm_202429.28g of kerosene per passenger-kilometrePublished

The raw French statistic — 6.95 Mt of kerosene for 237.4 Gpkm in 2024. It is higher than the figure the model uses because it also carries the freight in the holds and reflects actual load factors. Corrected for both, the same series gives about 19.3 g/pkm in 2023, which is the range the model's own aviation rows sit in. A real ticket therefore emits more than the per-passenger-kilometre figure below suggests.

  • DGAC mémentos de statistiques and CPDP kerosene deliveries, compiled 1950–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_electricity260€/MWh incl. taxPublished
price_household_gas134€/MWh GCV incl. taxPublished
price_wood77.5€/MWhPublished

7.75 c€/kWh for bulk pellets.

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
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

reference_plant_CCS less reference_plant.

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_total4 200Mm²Published

France's total residential and tertiary floor area, kept as a cross-check rather than as an input: the model's own heated stock is 3 654.9 Mm², and `building_surface_coverage` reports the 87% ratio. The residential share that used to sit beside it is gone -- the stock carries the building type, so the split is counted rather than assumed.

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

Air-to-water heat pump, in the 60–100 €/m² range.

  • ADEME cost ranges for residential heat pumps
renovation_vat1.055multiplierPublished

Reduced VAT rate of 5.5% on renovation work.

  • CSTB / OptoBat convention, VAT_RENOVATION = 1.055
households31.377millionPublished
car_ownership_reference2 541€/household/yPublished

Net purchase 1 459 + insurance 518 + maintenance 564.

car_transport_reference3 803€/household/yPublished
km_per_car_per_year11 600kmPublished
reference_car_fleet2.88237e+07carsDerived

The car fleet the model computes at the reference scenario, used as the denominator of the fleet ratio so household ownership cost scales with fleet size. It is pinned rather than recomputed because the model runs in one pass; the regression test checks it still matches.

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 Workbook

Demand is 2020 service demand in billion passenger-kilometres; unit consumption is per vehicle-kilometre and occupancy converts it back to passenger-kilometres. `in_inventory` says whether the category is inside the national inventory perimeter: international aviation is reported by SECTEN as a memo item and excluded from the national total.

Rowvectorunit_consumptionoccupancydemand_2020in_inventoryaviation
Fuel car
car_fuel
liquid651.555510
Biogas car
car_gas
gas651.50.810
Electric car
car_electric
electricity201.51.233210
Fuel utility vehicle
utility_fuel
liquid851.8162.01210
Gas utility vehicle
utility_gas
gas851.84.510
Electric utility vehicle
utility_electric
electricity201.80.05986810
Fuel two-wheeler
two_wheeler_fuel
liquid501.011110
Electric two-wheeler
two_wheeler_electric
electricity151.010.1069210
Fuel bus
bus_fuel
liquid28414.2746.448910
Gas bus
bus_gas
gas28014.270.13128410
Electric bus
bus_electric
electricity7514.270.026256810
Hydrogen bus
bus_h2
hydrogen20014.27010
Long-distance train
train_long
electricity1 859457.99263.4610
Short-distance train
train_short
electricity97585.218144.610
Domestic aviation
aviation_domestic
liquid2 1609015.611
Overseas aviation
aviation_overseas
liquid3 50018033.611
International aviation
aviation_international
liquid3 50018036401

Passenger demand reallocation Workbook

Each row moves a share of one 2020 category's demand to a 2050 category. Shares that a lever drives are overridden in the equations; the rest are fixed workbook conventions. A category with no row keeps nothing, which is how fuel cars, fuel utility vehicles, fuel two-wheelers and fuel buses are retired.

  • Teaching workbook, "Transport parc 2050" sheet
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 Workbook

Demand is 2020 service demand in billion tonne-kilometres and unit consumption already includes loading. International air freight carries the gas vector in the workbook, so about 23 TWh of the game's "biogas" resource is in fact air-freight fuel — a workbook convention worth knowing before reading the biomass scoreboard.

  • Teaching workbook, "Transport parc 2050" sheet
Rowvectorunit_consumptiondemand_2020in_inventory
Hydrogen truck
truck_h2
hydrogen5001
Fuel truck
truck_fuel
liquid503001
Electric truck
truck_electric
electricity2001
Rail freight
rail_freight
electricity3.2501
Maritime
maritime
liquid0.67000
International air freight
air_freight
gas245120

Freight demand reallocation Workbook

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
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, 2020 Workbook

3 654.9 Mm2 and, after the stock-wide calibration, 359.34 TWh of heat need in 2020. Surfacic need is what the segment asks of its heating system per square metre and per year, before retrofit; it is a *need*, not a consumption, so the efficiencies in `building_vector` have not been applied yet. `dwellings` is informational and no equation reads it: the workbook counts tertiary floor area directly rather than in buildings, so it is zero on those three rows.

  • Teaching workbook, "Building parc 2020" sheet rows 3-26
Rowsystembuilding_typesurface_2020surfacic_needdwellings
Biomass, apartment
biomass_apartment
biomassapartment2.14595e+07160.745320 487
Fuel boiler, apartment
fuel_apartment
fuelapartment3.26277e+07178.999475 230
Gas boiler, apartment
gas_apartment
gasapartment3.53574e+08148.1945 334 267
Electric resistance, apartment
resistance_apartment
resistanceapartment2.11641e+0872.8233 995 209
District heating, apartment
district_apartment
districtapartment9.7389e+07186.5871 554 877
Air-air heat pump, apartment
air_air_apartment
air_airapartment2.82849e+0763.9689636 490
Air-water heat pump, apartment
air_water_apartment
air_waterapartment1.5063e+0614.7621146 882
Hybrid heat pump, apartment
hybrid_apartment
hybridapartment014.76210
Biomass, house
biomass_house
biomasshouse4.25995e+08178.4653 775 624
Fuel boiler, house
fuel_house
fuelhouse2.83748e+08189.3212 428 267
Gas boiler, house
gas_house
gashouse5.64693e+08159.0645 168 802
Electric resistance, house
resistance_house
resistancehouse4.69674e+0881.01284 442 744
District heating, house
district_house
districthouse1.15162e+06186.84813 311
Air-air heat pump, house
air_air_house
air_airhouse3.38464e+0763.7414365 908
Air-water heat pump, house
air_water_house
air_waterhouse1.80247e+0614.709684 440.2
Hybrid heat pump, house
hybrid_house
hybridhouse014.70960
Biomass, tertiary
biomass_tertiary
biomasstertiary40 726 800206.0120
Fuel boiler, tertiary
fuel_tertiary
fueltertiary210 049 200200.0510
Gas boiler, tertiary
gas_tertiary
gastertiary501 552 000198.4290
Electric resistance, tertiary
resistance_tertiary
resistancetertiary204 120 00095.57450
District heating, tertiary
district_tertiary
districttertiary67 748 400206.5580
Air-air heat pump, tertiary
air_air_tertiary
air_airtertiary13 996 80091.69180
Air-water heat pump, tertiary
air_water_tertiary
air_watertertiary89 326 80096.10590
Hybrid heat pump, tertiary
hybrid_tertiary
hybridtertiary096.10590

Heating system efficiencies and vector mix Workbook

How a segment's heat need becomes energy: need x unit consumption / efficiency, summed over the pairs below. A system can draw on several vectors -- district heating on six, a hybrid heat pump on two -- and `unit_2020` / `unit_2050` are the repartition keys, which is why they sum to one per system rather than carrying a physical unit. Two columns carry the whole argument for replacing the old aggregate. `peak_efficiency` is separate from `seasonal_efficiency` and lower for every heat pump (air-air 2.5 -> 2.0, air-water 3.0 -> 2.0, district-heating electricity 2.5 -> 1.5), because a heat pump loses efficiency exactly when the system needs it most. `peak_share` makes the hybrid heat pump run 70% on gas on the coldest evenings while running 95% on electricity over the year. The module this replaces flattened all of it into two constants, a seasonal COP of 3 and a peak COP of 2.

  • Teaching workbook, "Building heating" sheet rows 22-35
Rowsystemvectorseasonal_efficiencypeak_efficiencypeak_shareunit_2020unit_2050
Biomass, wood
biomass_wood
biomasswood0.850.85111
Fuel boiler, fuel oil
fuel_liquid
fuelliquid0.90.9111
Gas boiler, gas
gas_gas
gasgas0.950.95111
District heating, gas
district_gas
districtgas0.850.8510.3520.6
District heating, fuel oil
district_liquid
districtliquid0.850.8510.0050
District heating, wood
district_wood
districtwood0.850.8510.2380.3
District heating, coal
district_coal
districtcoal0.850.8510.0370
District heating, other
district_other
districtother0.850.8510.3680
District heating, heat pump
district_electricity
districtelectricity2.51.5100.1
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

Industrial production routes Workbook

Unit consumption per tonne of product. 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.

  • Teaching workbook, "Industry" sheet rows 41–54
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 — electrolytic
ammonia_green
ammonia0.7780005.94
Ammonia — SMR hydrogen
ammonia_grey
ammonia00.913846000
Olefins — CO₂ + H₂
olefins
olefins5.95120001.32
Cement clinker
cement
cement0.15230.1950.1470.3580

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 Published

The DGAC's own route categories for traffic departing France in 2023, with passengers and passenger-kilometres, from which an average distance follows. `game_row` says which of the model's three aviation categories supplies the unit consumption, so the ticket is priced on exactly the energy the emissions account already charges.

Rowpax_2023pkt_2023game_row
Paris ↔ province
paris_province
12.257.75aviation_domestic
Province ↔ province
province_province
8.985.46aviation_domestic
Paris ↔ international
paris_international
82.68263.17aviation_international
Province ↔ international
province_international
55.9270.58aviation_international
Paris ↔ Outre-mer
paris_overseas
4.7438.55aviation_overseas
Province ↔ Outre-mer
province_overseas
0.090.74aviation_overseas
Outre-mer ↔ international
overseas_international
2.456.68aviation_international
Outre-mer ↔ Outre-mer
overseas_overseas
2.51.26aviation_domestic

The rest of industry — energy and process emissions Published

The seventeen 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: e00 is the observed 2019 situation, e11 the source workbook's 2050 scenario, e10 the 2050 output at 2019 processes and e01 the 2050 processes at 2019 output. Both end points are the published branch totals; the output index between them is measured from the branch sheets' own production data, not assumed.

Rowgroupcarriere00e10e01e11
Metals and machinery — coal
metals_machinery__coal
metals_machinerycoal2.19812.604500
Metals and machinery — oil
metals_machinery__oil
metals_machineryoil2.03432.415300
Metals and machinery — gas
metals_machinery__gas
metals_machinerygas17.305423.052215.794217.815
Metals and machinery — biomass
metals_machinery__biomass
metals_machinerybiomass001.17411.2733
Metals and machinery — electricity
metals_machinery__electricity
metals_machineryelectricity28.31939.244465.139884.1051
Metals and machinery — hydrogen
metals_machinery__hydrogen
metals_machineryhydrogen0.02330.04810.02570.0257
Metals and machinery — steam
metals_machinery__steam
metals_machinerysteam0.63970.71660.47970.5217
Minerals and building materials — coal
minerals__coal
mineralscoal1.24441.244400
Minerals and building materials — oil
minerals__oil
mineralsoil2.16322.337300
Minerals and building materials — gas
minerals__gas
mineralsgas16.130816.44438.88888.9452
Minerals and building materials — biomass
minerals__biomass
mineralsbiomass0.40710.407100
Minerals and building materials — electricity
minerals__electricity
mineralselectricity6.4436.756512.486212.9326
Minerals and building materials — hydrogen
minerals__hydrogen
mineralshydrogen000.05820.1452
Minerals and building materials — process
minerals__process
mineralsprocess1.99121.99121.9431.943
Chemicals, other — coal
chemicals_other__coal
chemicals_othercoal4.31772.248300
Chemicals, other — oil
chemicals_other__oil
chemicals_otheroil2.90751.780400
Chemicals, other — gas
chemicals_other__gas
chemicals_othergas8.52486.8582.03871.5872
Chemicals, other — biomass
chemicals_other__biomass
chemicals_otherbiomass0.8680.45160.63460.3304
Chemicals, other — electricity
chemicals_other__electricity
chemicals_otherelectricity13.22339.807530.286120.5227
Chemicals, other — hydrogen
chemicals_other__hydrogen
chemicals_otherhydrogen1.53520.81123.06021.6041
Chemicals, other — steam
chemicals_other__steam
chemicals_othersteam5.74523.6585.15542.7832
Chemicals, other — process
chemicals_other__process
chemicals_otherprocess0.55590.289200
Paper and board — coal
paper__coal
papercoal0.12790.109600
Paper and board — oil
paper__oil
paperoil0.37220.318800
Paper and board — gas
paper__gas
papergas9.2117.89047.16016.1336
Paper and board — biomass
paper__biomass
paperbiomass14.17712.144513.793911.8164
Paper and board — electricity
paper__electricity
paperelectricity7.53626.455812.957711.1
Paper and board — steam
paper__steam
papersteam3.4892.98883.94553.3798
Other industries — coal
other_industries__coal
other_industriescoal0.02330.042900
Other industries — oil
other_industries__oil
other_industriesoil0.83741.788300
Other industries — gas
other_industries__gas
other_industriesgas6.943120.50831.50514.1839
Other industries — biomass
other_industries__biomass
other_industriesbiomass3.97757.31870.84881.5619
Other industries — electricity
other_industries__electricity
other_industrieselectricity12.409224.647216.751237.1683
Other industries — steam
other_industries__steam
other_industriessteam0.76762.00370.14640.3741

Building energy by usage, observed Published

Final energy by usage and by carrier, from the CEREN series the SDES publishes. Residential is 2024, the latest available; tertiary is **2019 rather than 2020**, because 2020 is a Covid year — tertiary consumption fell from 237 to 209 TWh and recovered afterwards, so using it would build a lockdown into the 2050 baseline. The heat harvested by heat pumps is excluded: the source reports it as a renewable input beside the electricity that drives the pump, and counting both would double the energy. `heat` is district heat, which the model has no carrier for and which the equations fold into gas — networks in this model are majority gas, so it is the least wrong of the available homes for 2.8 TWh, and it is stated rather than buried. Space heating is deliberately absent: it is the stock model, and the two perimeters do not match — this table's heating rows would say 335 TWh against the stock's 383 for 2020, different years and different methods.

Rowusagesegmentelectricitygasliquidwoodheat
Hot water, residential
dhw_residential
dhwresidential24.3413.513.320.661.24
Hot water, tertiary
dhw_tertiary
dhwtertiary7.2311.753.080.141.55
Cooking, residential
cooking_residential
cookingresidential9.3310.98000
Cooking, tertiary
cooking_tertiary
cookingtertiary4.477.10.080.070
Air conditioning, residential
cooling_residential
coolingresidential2.590000
Air conditioning, tertiary
cooling_tertiary
coolingtertiary21.660000
Specific electricity, residential
specific_residential
specificresidential67.150000
Specific electricity, tertiary
specific_tertiary
specifictertiary70.30000
Other uses, tertiary
other_tertiary
othertertiary2.133.994.410.170

RTE 2050 generation mixes Published

Each row is one of RTE's 2050 scenarios reduced to shares of total supply, so it can be applied to whatever electricity this model's own demand turns out to be rather than carrying RTE's demand with it. The range is the one RTE built it to span: M0 has no nuclear at all, N03 about half. Two splits the source does not make are made here and declared: solar is halved between ground and rooftop, and offshore wind between fixed and floating. Both matter to the material account — a floating foundation is 480 t of steel per MW against 250 fixed — and neither is a result.

Rowscenario_indexnuclearpv_groundpv_roofwind_onshorewind_offshore_fixedwind_offshore_floatinghydrobioenergygas_turbinecombined_cycle
M0 — 100% renewable
m0
100.1730820.1730820.2030740.1519990.1519990.1085420.0157780.0217630.00068
M1 — renewables, distributed
m1
20.1244510.1748770.1748770.162870.1114160.1114160.1090830.0159170.0144070.000686
M23 — renewables, large farms
m23
30.1294220.108680.108680.2064210.1529340.1529340.1110950.016480.0126440.00071
N1 — new nuclear, 4 EPR2
n1
40.2601490.1032020.1032020.1676670.1144940.1144940.1113490.0165810.0081480.000715
N2 — new nuclear, 8 EPR2
n2
50.3678230.0802240.0802240.1512680.0940690.0940690.1120660.0169050.0027690.000583
N03 — new nuclear, ~50% nuclear
n03
60.5010360.0634250.0634250.128330.0576520.0576520.1113080.0171700

Generation technologies, material intensity Workbook

Tonnes of material per MW of capacity built, 2050 values. These drive a satellite account: the model has no electricity supply module, so what is built here is a declared build rate rather than a mix sized to cover the demand the model computes. Making it cover that demand needs load factors the source does not provide — that is the next step, and until it is taken these numbers say what a build costs in materials, not whether it is enough. `thermal_efficiency` and `fuel_carrier` are what make the account scope 1: a thermal plant burns a fuel, that fuel goes through the same constructive account as every other, and it takes the emission factor of its carrier. A combined cycle running on biomethane therefore emits at 25 gCO2/kWh of fuel and not at 356 — and it draws on the same biomethane the buildings want, which is a competition the model did not previously represent. Efficiencies are RTE's own: 60% for a combined cycle, 25% for bioenergy. **The bioenergy plants burn gas here, not wood.** RTE's category mixes solid biomass, biogas and the renewable part of waste; sending it to wood would have the power system eating 54 TWh of a resource the buildings and industry are already short of, to make electricity at 25% efficiency, which is the one thing biomass should not be used for. Calling it biogas is a modelling choice and it is deliberately conservative on quantity: a gas engine would be nearer 40% efficient than 25%, so the fuel this asks for is on the high side rather than the low. The gas turbine runs on hydrogen in every RTE 2050 scenario, so it burns no fuel here; the electricity that made the hydrogen is not traced back, which is a hole and a small one at these volumes. Hydro, bioenergy and the two thermal rows carry intensities but no lever: the source scenario builds none of them after 2050, and a slider that only ever sat at zero would be decoration.

  • Offre_et_demande.xlsx, "Energie" sheet rows 19-33 — intensité matière 2050
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.140none0257471128.470635.137317.43.19.37e-070.0003202.2235e-05
Solar PV, rooftop
pv_roof
10.140none0257471116.176528.8627123.18.7e-070.00031396201.9765e-05
Wind, onshore
wind_onshore
10.230none0251 300402004500.692.67.1e-063.4e-0504.2e-05
Wind, offshore fixed
wind_offshore_fixed
10.410none0202 6008025091018.58.1e-063.65e-0500.106674
Wind, offshore floating
wind_offshore_floating
10.410none0202 600804801 7001.158.558.55e-064.8e-0500.106676
Hydro
hydro
10.2950none0701 0001598210.520.181.9e-070.0001409e-05
Bioenergy
bioenergy
10.5890.25gas0253 000120573.50.0590.127.2e-075.4e-0505.4e-06
Gas turbine
gas_turbine
00.1140none025800486.3410.750.791.5e-087.2e-0606.4e-06
Combined cycle
combined_cycle
00.1140.6gas1301 1004829361.11.23.6e-080.001802e-05

Vehicle production and material intensity Workbook

Kilogrammes of body material per vehicle and units produced per year in 2050. `electric_share` is the share of that production carrying a battery; it is derived from the source's own battery-capacity row rather than assumed, and it is overridden by the player's own electrification levers for cars and trucks. Only steel and aluminium are carried here. The source also gives flat glass, plastics and rubber per vehicle, which are real but are not what the transition changes — the battery is.

  • Offre_et_demande.xlsx, "Matériaux transports" sheet rows 2-9 and 32-33
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

Scoreboard bands Game rule

These set the difficulty of the game; they are not resource assessments from a published national study, and the biomass one in particular is argued over — see the controversy table. Declared here rather than in the interface because the feasibility tool has to score the same scenario the player does. Two copies of a rule are two rules. The four emission bands are on the *game perimeter* — the footprint basis — not on the national figures the sector cards show. The two differ by the electricity life-cycle and by international bunkers, so scoring one against the other's band would be meaningless.

Rowgoodwarning
Total emissions, game perimeter
total
1530
Transport emissions
transport
410
Building emissions
building
37
Industry emissions
industry
1015
Winter electricity peak
peak
3545
Biogas
biogas
70150
Biofuels
biofuel
4050
Wood energy
biomass
80120

Contested assumptions 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 2050. Nothing here is a secret — every one of these is visible in the annex — but a reader should not have to reverse-engineer which numbers are settled and which are live.

Rowtopicweightpositioncontestedsettles_it
Is burning wood carbon-neutral?
wood_factor
emission factorshigh27 gCO2/kWh in 2050, the same the source observes for 2020, rather than the zero the biogenic convention gives it.The convention books the CO2 against the forest that regrew, not the boiler. Whether that holds depends on the harvest, the rotation and the counterfactual, none of which this model has. Worth 2.1 MtCO2 here, and the slider goes to zero for anyone who disagrees.A carbon-debt payback period for French forestry, and a rule for which harvests qualify. It is a live scientific argument, not a missing number.
43 MtCO2 a year of capture that nothing builds
technological_sink
carbon sinkshighA residual that closes the published national account, set as a slider between -60 and -5.It is the single largest assumption in the model and the cheapest to move: nothing here builds the capture plant, powers it, or pays for it. A scenario reaches net zero partly by sliding this.Costing it — in euros and in the energy capture itself consumes — and charging that back to the scenario. Not modelled.
Can the forest sink be strengthened?
natural_sink
carbon sinksmedium-23 MtCO2e, where the SNBC 3 pathway lands, adjustable to -40.The French forest sink has roughly halved since 2010 as the stock ages and drought and dieback bite. Reaching the strong end of the range means a forest growing faster than today's, and defensible figures for that are scarce.Forest inventory projections under climate stress. Genuinely hard; expect no clean answer.
Is 45 GW the right red line?
peak_limit
system constraintsmediumTarget 35 GW, limit 45, on the electric-heating contribution alone.The band was calibrated against a peak calculation that was wrong, and was deliberately left where it was when the calculation was corrected. The reference scenario is over it at 50.6 GW. Whether that is the model failing or the scenario failing is exactly the question.An adequacy study. The model has no supply-side balance, so it cannot answer this on its own.
Nuclear or renewables?
nuclear_share
electricity supplyhighNeither. Six RTE scenarios are offered, M0 at 100% renewable to N03 at about half nuclear, and the player chooses.The most argued question in French energy policy, and the model declines to answer it. What it will not do is check that any of them works: there is no hourly balance, no storage and no adequacy calculation, so a 100%-renewable mix is applied exactly as a nuclear-heavy one is.Hourly dispatch with storage and flexibility. Until then the cost shown here is plant only and favours whichever mix has the lowest capital cost per MWh, which is not the same as the cheapest system.
How much biomass is actually available?
biomass_ceiling
resourcesmediumA scoreboard band of 80 TWh target, 120 limit.The band sets the difficulty of the game and is not a resource assessment from a published national study. Estimates of French biomass potential vary by more than a factor of two depending on what is counted as available.A sourced national potential with its own perimeter stated. Would replace a game rule with a measurement.
The gap to the SNBC
perimeter_gap
accountinglowReported as a named reconciliation, never divided away.Not really contested, and listed here so the distinction is visible: a gap that is explained line by line is a result, not a discrepancy. The model counts life-cycle electricity and international bunkers; the inventory does neither.Nothing to settle. This one is arithmetic.

Emissions and energy posts Derived

`waste_heat_share` is the recoverable waste heat ADEME finds per unit of fuel burned, and `waste_heat_hot_share` the fraction of it above 100 °C. They are attached to the fuel, not to the sector, which is the point: heat that is a by-product of combustion disappears when the combustion does. Transport and buildings carry zero because the ADEME study is industrial. The constructive account. Every emission the game reports is built up from these posts, and every post is energy times an emission factor plus a named process term. Nothing is added at the sector level that is not in this table, which is what makes a missing sub-sector visible.

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
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

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; the e-fuel half and all hydrogen are converted back into the electricity needed to make them, at the declared conversion efficiencies. 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
passenger_electricity_hydrogenpassenger_hydrogen / efficiency_electricity_to_h2TWh/y
freight_biofuelfreight_liquid * biofuelShareTWh/y
freight_electricity_efuelfreight_liquid * (1 - biofuelShare) / efficiency_electricity_to_efuelTWh/y
freight_electricity_hydrogenfreight_hydrogen / efficiency_electricity_to_h2TWh/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.

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_base_production * clinkerRate * (1 - cementReduction)kt clinker/y
chain_production
per row of industry_chain
steel_bf: steel_bf_production
steel_dri: steel_dri_production
steel_eaf: steel_eaf_production
ammonia_green: greenAmmonia
ammonia_grey: ammonia_grey_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

Only the cement kiln burns liquid fuel among the five chains, and it burns more of it than of gas or coal.

chain_hydrogen
per row of industry_chain
row.chain_production * row.hydrogen / 1000TWh/y
steel_bf_process_residualsteel_bf_process_workbook - industry_chain["steel_bf"].coal * ef_coal / 1000tCO₂ per tonne of steel

CORRECTION to the workbook. The workbook charges the blast furnace 1.76 tCO₂ per tonne of steel AND charges its coal an emission factor as well, so the coal carbon was counted twice. The 1.76 figure is almost exactly the combustion of the 0.62 t of coal the same sheet uses — 5.047 MWh/t at the published coking-coal factor gives 1.716 tCO₂/t. The model now counts the coal once, as energy, and keeps only the remainder here. That remainder, about 0.044 tCO₂/t, is the limestone flux and whatever else the workbook's single figure contained; a proper published split would replace it.

chain_process_per_tonne
per row of industry_chain
steel_bf: steel_bf_process_residual
olefins: olefin_process_per_biogenic_share * biogenicCO2
cement: cement_process_per_tonne * (1 - carbonCapture)
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 — and the blast-furnace residue left once its coal has been counted as energy.

chain_emissions_per_tonne
per row of industry_chain
row.coal * ef_coal / 1000 + row.chain_process_per_tonnetCO₂ 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 * otherIndustryProcessTWh/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.

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
TWh/y
energy_electricity_hydrogen
per row of post
passenger_mobility: passenger_electricity_hydrogen
freight_mobility: freight_electricity_hydrogen
steel: sum(industry_chain.chain_hydrogen, industry_chain.subpost == "steel") / efficiency_electricity_to_h2
ammonia: sum(industry_chain.chain_hydrogen, industry_chain.subpost == "ammonia") / efficiency_electricity_to_h2
olefins: sum(industry_chain.chain_hydrogen, industry_chain.subpost == "olefins") / efficiency_electricity_to_h2
food_heat: food_hydrogen / efficiency_electricity_to_h2
other_metals: sum(industry_other.other_energy, industry_other.group == "metals_machinery" and industry_other.carrier == "hydrogen") / efficiency_electricity_to_h2
other_minerals: sum(industry_other.other_energy, industry_other.group == "minerals" and industry_other.carrier == "hydrogen") / efficiency_electricity_to_h2
other_chemicals: sum(industry_other.other_energy, industry_other.group == "chemicals_other" and industry_other.carrier == "hydrogen") / efficiency_electricity_to_h2
other_paper: sum(industry_other.other_energy, industry_other.group == "paper" and industry_other.carrier == "hydrogen") / efficiency_electricity_to_h2
other_diverse: sum(industry_other.other_energy, industry_other.group == "other_industries" and industry_other.carrier == "hydrogen") / efficiency_electricity_to_h2
default: 0
TWh/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
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")
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
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")
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_direct
per row of post
row.energy_electricity_direct_raw * row.efficiency_elec_factorTWh/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")
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

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_demandsum(post.energy_electricity_total)TWh/y
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_direct) + 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

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_agricultureofficial_agriculture_2024 + (official_agriculture_2050 - official_agriculture_2024) * agriPathwayMtCO₂e/y
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 alone, 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_sinknaturalSinkMtCO₂e/y
national_technological_sinktechSinkMtCO₂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.

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
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_green: cost_route["haber_bosch"].route_annuity
ammonia_grey: 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_green: industry_chain["ammonia_green"].electricity * elecPriceIndustry + industry_chain["ammonia_green"].hydrogen * cost_hydrogen_electrolytic
ammonia_grey: industry_chain["ammonia_green"].electricity * elecPriceIndustry + industry_chain["ammonia_green"].hydrogen * cost_hydrogen_smr
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) * elecPriceIndustry
€/t of product

Energy and feedstock. Grey ammonia is the one deliberate departure from the physical model: the workbook's 0.914 MWh/t of gas is an order of magnitude too low for a reforming plant, so the cost is built from the POMMES reforming route instead, and the discrepancy is declared rather than hidden.

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
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_electricity
per row of building_usage
row.electricity * row.usage_factorTWh/y
usage_gas
per row of building_usage
(row.gas + row.heat) * row.usage_factorTWh/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_factorTWh/y
usage_wood
per row of building_usage
row.wood * row.usage_factorTWh/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_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.hydrogen_capable == 1)TWh/y

The combined cycle only. The bioenergy plants also burn gas here, but switching them to hydrogen would be switching a biogas plant to hydrogen, which is not what the lever is for.

generation_fixed_gas_fuelsum(generation_technology.generation_fuel, generation_technology.fuel_carrier == "gas" and generation_technology.hydrogen_capable == 0)TWh/y
generation_gas_fuelgeneration_fixed_gas_fuel + generation_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
material_steelgeneration_steel + vehicle_steel + battery_steelkt/y
material_concretegeneration_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.

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, France 2050 — conversion_investment.csv, conversion_operation.csv, conversion_factor.csv
Commodity prices 2050: 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 2050 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 2050 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, 2050 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/parameters.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.