A web-based codex for Brotato, built from decompiled game data.
I started working on this project because the wiki was outdated since the Paws and Claws update, and in addition I would like to preview the cursed effects easily.
So that's it. You've got a new codex that incorporates price, curse, and 99.99% accurate attack speed calculators (and of course you can easily search, filter, and sort the items). I really enjoy it, and I hope you will too.
In addition, you can find links to my mods and other useful resources in the "Resources" section. (Why not try Cursed & Double Sided Upgrades and One Item to Rule Them All?)
I would like to express my sincere gratitude to WL (the author of Improved Tooltips) and AroRising (the author of Brotato MultiTool) who provided me with information and inspiration for this project.
If you find it helpful, please consider giving it a star on GitHub! If you would like to contribute or have any suggestions, please feel free to open an issue or a pull request.
We recommend reading the detailed explanation of Brotato's weapon cooldown mechanics for accurate calculations here.
- Add enemy information and per-wave stats.
- Add more localization support (currently supports English and Chinese).
- Add more calculators and tools.
- Data pipeline: Python 3 — parses Godot
.tresresource files, translates effect text, generates JSON + icon assets - Frontend: Vue 3 + Element Plus + Vite (uses
pnpm) - Styling: Scoped CSS with dark/light theme toggle
- GDRE Tools to decompile the game
- Remember to choose "Add .pck" to decompile both the base game and DLC data at once
# 1. Decompile game with GDRE to a directory, e.g. D:\brotato\decompiled
# The directory should contain: .assets/, weapons/, items/, dlcs/, effects/, etc.
# 2. Clone this repo into the decompiled directory
cd D:\brotato\decompiled
git clone https://github.com/mojimoon/brotato codex
# 3. Pre-analyze missing translations
cd codex/translations
python analyze.py
# Outputs: codex/translations/merged_analysis.json
# 4. Start the translation fix web tool
pnpm install
pnpm dev
# Opens at http://localhost:3000
# 5. In the web tool: load merged_analysis.json, match translations, export
# Exported file goes to: codex/public/data/translations_merged.json
# 6. Generate the full game data
cd D:\brotato\decompiled
cd codex
python main.py
# Outputs: codex/public/data/brotato_data.json
# codex/public/icons/
# 7. Build the codex website
pnpm install
pnpm build
# Output: codex/dist/root/
├── .assets/ # Game resources (translations CSV, images, etc.)
├── weapons/ # Base weapons (melee/, ranged/)
├── items/ # Base items + characters
├── effects/ # Effect class implementations
├── dlcs/dlc_1/ # DLC1 data
└── codex/ # This repo
├── main.py # Data pipeline: .tres → JSON + icons
├── public/data/
│ ├── brotato_data.json # Generated game data
│ └── translations_merged.json # Manual translation fixes
├── src/App.vue # Vue frontend
└── translations/ # Translation fix toolchain
├── analyze.py # Scans for missing translation keys
└── web/ # Vue app for manual translation matching
- Loads translations from
.assets/resources/translations/translations.csv(base game) anddlcs/dlc_1/translations/translations.csv(DLC) - Optionally loads
translations_merged.jsonfor manually fixed entries - Parses every weapon, item, and character
.tresfile with a custom parser (not Godot runtime) - Renders effect text by replicating Godot's
Effect.get_text()→Text.text()pipeline:- Resolves translation key (
text_keyorkey, uppercased) - Builds args via each effect subclass's
get_args()logic - Applies
custom_argsoverrides (value, sign, format) - Formats with operator (+), percent (%), and color spans
- Resolves translation key (
- Copies all referenced icon files to
public/icons/
analyze.pyscans all.treseffect files, extracts translation keys, cross-references with CSV, and outputsmerged_analysis.json— a categorized list of missing keys with candidate strings- The web tool (
pnpm dev) lets you visually match missing keys to translations and export atranslations_merged.json main.pypicks up this file and fills in the gaps
extra.spawn_cooldown— already in seconds, do NOT divide by 60structure_stats.cooldown— in frames (60 fps), divide by 60weapon_stats.cooldown— in frames (60 fps), divide by 60
- Two code paths exist:
_build_effect_args_and_signs()(legacy) andrender_effect_text()(active). Changes must be applied to both. text_key = "[EMPTY]"effects are filtered out entirelystat_scaled = "different_item"maps totr("ITEM")(nottr("DIFFERENT_ITEM"))spawn_cooldown = -1is a sentinel meaning "use stats file cooldown"- Icon syntax:
<icon>short_key</icon>(e.g.,<icon>ranged_damage</icon>) — Python generates it, Vue renders as<img> - Stat icon prefix: effects with
keystarting withstat_get an icon prefix; others get・for alignment
- Left panel: grid with
repeat(auto-fill, minmax(90px, 1fr))layout - Right panel: detail view with independent scroll
- Effect items use two flex children (
eff-prefix+eff-text) to prevent line wrapping - Theme toggle:
isDarkref +watchaddslight-themeclass to<html>and<body> - Tab icons: Aim (weapons), Box (items), User (characters) from
@element-plus/icons-vue - Language switch: el-dropdown with text content (not
:iconprop, which requires a component) htmlmust have same background asbodyto prevent color bleed on wide screens