A free software game designed to explore the orders of magnitude of CO2 footprints in our daily lives and raise awareness about climate change.
This application is based on the work of Thomas James Watson (thank you! ❤️) for wikitrivia. Original source code available on github.
This project uses open data provided by ADEME (Agence de l'Environnement et de la Maîtrise de l'Énergie, the French state agency working on climate change). The raw data is available on the ADEME website, either through a user-friendly website, or via an API. To enable offline gameplay and reduce redundant API calls (since the data doesn't change frequently), the information is stored within the app and manually updated regularly. The last update was performed on 2026-07-09.
Contributions to the project are very welcome! By contributing, you agree that your work will be licensed under the AGPL license (see the LICENSE file for details).
This project is a React single-page application built with Vite. NodeJS 24 or higher is required to build and run the project.
npm installnpm run devThen visit http://localhost:5173/ to preview the website.
To build a static version of the website to the out folder, that you can then deploy anywhere (it's plain HTML + JS, no server needed) run:
npm run builddisCO2very uses Lingui to manage translations. If you add or modify any text in the app, you must run:
npm run i18n-extractThis will modify the english keys in locales/en/messages.po. Look for entries starting with #~: these are now outdated and should be removed.
Then open the other languages files like locales/fr/messages.po and look for empty strings "" to add the missing translations.
The .po catalogs are compiled automatically when the app is built or served, there is no separate compilation step.
Say you want to add Portuguese (pt). Two kinds of text need translating: the UI strings (buttons, instructions... managed by Lingui) and the game data (item names, explanations... coming from ADEME).
-
Declare the locale: Add
"pt"to theLocaleunion intypes/i18n.ts, to theI18nStringinterface below it, and to thelocaleslist inlib/locales.ts. From here,npm run buildfails with type errors on every place that must be completed. -
UI strings: Run
npm run i18n-extract: it createslocales/pt/messages.po. Fill every emptymsgstr ""with the Portuguese translation, then register the catalog incomponents/app.tsx(add themessages.poimport and aptentry tomessagesByLocale). -
Game data: ADEME translates its data in French, English and Spanish only, so like German, Portuguese is maintained by hand in this repository:
- Copy
data/ademe/locales/de.jsontopt.jsonand translate its three sections:names(the item names),hypothesis(the explanation texts) andecv(the footprint detail labels). - Add
"pt"to thehandMaintainedLocaleslist inscripts/update-ademe-data.mjs: every future data update will then report the entries missing inpt.json. Runningnpm run update-ademewhile you translate gives you a live todo-list. - Register the file in
lib/ademe-api.ts(aptentry inlocaleImports). - Translate the category names in
data/ademe/0-categories.json(aptfield next toen/fr/es/de).
If a future locale is translated upstream by ADEME, skip the hand-maintained file and add it to the extraction list in
scripts/update-ademe-data.mjsinstead. - Copy
-
Verify:
npm run buildmust pass without type errors, thennpm run test-e2e.
The app picks the language from the browser (navigator.language), so testing locally is easiest by changing the preferred language in the browser settings.
The data used is hardcoded in the code to allow to play offline. That's why it's important to regularly pull the latest data from the ImpactCO2 github repository.
- For the data, run the extraction script against a local checkout of the impactco2 repository:
The script refreshes
git -C impactco2 pull # or clone it first npm run update-ademe # accepts a path: npm run update-ademe -- /path/to/impactco2 npm run format # the upstream files use another code style
data/ademe/categories/*.ts(the footprint numbers) anddata/ademe/locales/{fr,en,es}.json(names, hypothesis texts, footprint detail labels). Watch its output: it warns about entries missing in the upstream translations (markedMISSING_TRANSLATIONSin the files) and lists what needs translating in the hand-maintained locales likede.json.git diffthe result: if a new category appeared, completedata/ademe/0-categories.json(id, translated names, sources — compare with impactco2'ssrc/data/categories.tsx) and the category list inscripts/update-ademe-data.mjs.- New transport variants only enter the game once they have a journey length in
data/transport-distances.json.
- For the icons,
- Download all the SVG icons from the github repository
public/iconsfolder and save them inpublic/images/ademe - Execute the
./clean-ademe-image.shscript, as not all the ADEME images are used in disCO2very, so no need to bundle them
- Download all the SVG icons from the github repository
- Run
npm run build && npm run test-e2e, and play a quick game to check the values look sane. - Finish by updating the date above in this file, to inform people of the last time the data has been updated