This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Path of Building Community is an offline build planner for Path of Exile, written in Lua (LuaJIT 5.1). It runs on a custom 2D graphics host (SimpleGraphic) and provides comprehensive offense/defense calculations, passive tree planning, item/gem configuration, and build sharing.
Running via LÖVE (cross-platform, recommended for Linux):
cd love && love .Requires LÖVE 11.5+ and TTF fonts in love/fonts/. The shim layer in love/shim/ bridges LÖVE to SimpleGraphic's API — PoB's src/ code runs unmodified.
Running via SimpleGraphic (Windows only):
./runtime/Path\ of\ Building.exe
Dev mode (enabled automatically on the dev branch or when running from source) features: F5 restart, Ctrl+~ console, Alt for debug tooltips, Ctrl+F5 regenerate ModCache.
Tests use the Busted framework. Tests are in spec/System/ with build regression tests in spec/TestBuilds/.
# Run tests via Docker
docker-compose up
# Or directly with Docker
docker run ghcr.io/pathofbuildingcommunity/pathofbuilding-tests:latest busted --lua=luajitConfiguration is in .busted. Tests tagged builds are excluded from the default run.
- Indentation: Tabs (not spaces)
- Line length: 120 characters max
- Lua version: LuaJIT 5.1
- File naming: PascalCase (e.g.,
CalcOffence.lua,PassiveTree.lua) - Functions/variables: camelCase (e.g.,
GetProperty(),AddMod())
src/Launch.lua— Application bootstrap, dev mode detection, renderer initsrc/Modules/Main.lua— Loads game data, manages two modes: build list and build editor
Custom OOP via newClass() in src/Modules/Common.lua:
newClass("ClassName", "ParentClass", function(self, ...)
-- constructor
end)Classes are registered in common.classes. All UI controls inherit from Control base class. Properties can be functions or values (lazy evaluation via GetProperty()).
src/Modules/— Core logic: calculations, data loading, mod parsing, common utilitiessrc/Classes/— UI controls (buttons, dropdowns, tabs) and data structures (ModDB, Item, PassiveSpec)src/Data/— Game data, mostly auto-generated from GGPK. Do not edit files with the header-- This file is automatically generated, do not edit!src/Export/— Scripts to extract and regenerate data files from the GGPKsrc/TreeData/— Passive skill tree data per game version
- CalcSetup.lua — Builds modifier databases for player and enemy actors
- CalcOffence.lua — DPS and offense calculations
- CalcDefence.lua — Defense and mitigation calculations
- CalcPerform.lua — Performance breakdown display
- CalcActiveSkill.lua — Individual skill processing
- CalcTriggers.lua — Trigger/proc mechanics
- Calcs.lua — Orchestrates calculation modules, computes node/item/gem changes for sidebar and calcs tab
- ModParser.lua — Parses game mod text into internal format; generates
ModCache.lua - ModDB.lua — Stores modifiers indexed by stat name
- ModStore.lua — Extended modifier storage
- ModTools.lua — Mod creation, formatting, and ModCache loading
Build editor uses tabs: TreeTab, ItemsTab, SkillsTab, CalcsTab, ConfigTab, ImportTab, NotesTab, PartyTab. Each is a class in src/Classes/.
Cross-platform frontend using LÖVE 2D as an alternative to the Windows-only SimpleGraphic host.
love/shim/— Implements all ~50 SimpleGraphic API functions (rendering, input, text, images, file search, sub-scripts) and injects them into_Glove/shim/render.lua— Command-buffer renderer with layer sorting; handlesCMD_RECT,CMD_IMAGE,CMD_MESH,CMD_POLYGON,CMD_TEXT, etc.love/shim/init.lua— Orchestrator; also sets_G.LOVE_VERSION_TAGfor UI displaylove/lib/— Compatibility shims:lua-utf8.lua,lcurl/safe.lua,lzip.lualove/scripts/generate-manifest.sh— Regeneratesmanifest.xmlwith correct SHA1 hashes (run at build time, not on every push)
src/Launch.luaenablesdevModewhenmanifest.xmlhasbranch="dev"or is missing version info- Dev mode disables the auto-update checker and hides the "Check for Update" button
- Release builds have
branch="master"(set by CI at build time) so updates work normally
- A pre-push git hook runs cspell on all changed files vs the remote branch
- The dictionary config is fetched from an external repo at push time (not controlled locally)
- When adding new files or code with technical terms, add
cspell:wordsdirectives at the top of the file (e.g.,-- cspell:words LÖVE cdeffor Lua,# cspell:words LÖVE pacmanfor shell) - For upstream code with typos, use
cspell:ignoreon the line above to avoid modifying upstream lines - Do NOT skip the hook with
--no-verify— fix the spelling issues with inline directives
- This fork tracks
upstream/master(stable releases only), notupstream/dev - All our changes (LÖVE port) are rebased on top of
upstream/master - When upstream cuts a new release:
git fetch upstream && git rebase upstream/master - Before rebasing, squash fixup commits:
git rebase -i upstream/master
- Target
masterbranch - If mod parsing logic changes, regenerate ModCache with Ctrl+F5 and commit
src/Data/ModCache.lua - Changes to
src/Export/scripts must include the regeneratedsrc/Data/output files
- CI (
.github/workflows/love-build.yml) triggers onlove-v*tags and builds Windows + Linux packages - At build time, CI: (1) injects the git tag into
LOVE_VERSION_TAGvia sed, (2) runsgenerate-manifest.shto regenerate SHA1 hashes, (3) sets manifest branch tomaster manifest.xmlis not auto-committed on push — it is only regenerated during release builds- To release:
git tag love-v0.X.Y && git push origin love-v0.X.Y
Many files in src/Data/ are generated by scripts in src/Export/Scripts/. To modify these, change the export scripts and rerun the exporter — don't edit the generated files directly.
When a new PoE patch drops (e.g. 3.27), game data is extracted from the GGPK (Grinding Gear Package) — the game's binary data archive containing .dat64 tables, stat description text files, and item/monster metadata.
Dat Viewer tool (src/Export/Launch.lua): A separate GUI that opens the GGPK, extracts ~80 .dat64 tables using bun_extract_file.exe (Oodle decompressor in src/Export/ggpk/), and runs export scripts to regenerate Lua files.
Export scripts (src/Export/Scripts/) — key mappings:
statdesc.lua→src/Data/StatDescriptions/*.lua(~20 files) — must run firstmods.lua→ModItem.lua,ModJewel.lua,ModJewelAbyss.lua,ModJewelCluster.lua,ModMap.lua,ModVeiled.lua,ModGraft.lua,ModTincture.lua,ModNecropolis.lua,ModFoulborn.luabases.lua→src/Data/Bases/*.lua(one per item type)skills.lua→src/Data/Skills/act_str.lua,act_dex.lua,act_int.lua,other.lua,sup_*.lua,glove.lua,minion.lua,spectre.luaenchant.lua→EnchantmentBoots.lua,EnchantmentGloves.lua,EnchantmentHelmet.lua, etc.essence.lua→Essence.lua|cluster.lua→ClusterJewels.lua|masters.lua→ModMaster.luaminions.lua→Minions.lua|pantheons.lua→Pantheons.lua|miscdata.lua→Misc.luacrucible.lua→Crucible.lua|costs.lua→Costs.lua|bossData.lua→Bosses.lua,BossSkills.lua
Passive tree update: Tree data comes from PoE's passive tree API endpoint, placed into src/Export/Tree/tree_in.lua as a Lua table. psg.lua processes it into src/TreeData/<version>/tree.lua + sprites.lua + PNG assets. New versions are registered in src/GameVersions.lua (treeVersionList and treeVersions tables).
Manually maintained files (not overwritten by the export pipeline):
src/Data/Uniques/*.lua— unique item definitionssrc/Data/SkillStatMap.lua— stat-to-mod mappingssrc/Export/Skills/*.txt,src/Export/Bases/*.txt— template files for export scriptssrc/Data/Global.lua— enums, color codes, flags
ModCache (src/Data/ModCache.lua): Generated at runtime via Ctrl+F5 in dev mode (not by the export pipeline). Must be regenerated and committed if mod parsing logic changes.
ConPrintf()outputs to the dev console- Hold Alt in tooltips to see internal modifiers
- Hold Alt in Tree tab to highlight nodes with unrecognised modifiers
- Profiler available via Pause key, or
profiler.start()/profiler.stop()in code - EmmyLua debugger support for VSCode/JetBrains IDEs
docs/rundown.md— Detailed codebase layoutdocs/addingMods.md— How mods are parseddocs/modSyntax.md— Mod syntax referencedocs/addingSkills.md— How skills work in PoBCONTRIBUTING.md— Full contribution guidesrc/Data/Global.lua— Color codes, mod flags, skill type enumerationslove/shim/init.lua— LÖVE shim orchestrator, version taglove/shim/render.lua— LÖVE rendering pipeline