Skip to content

Latest commit

 

History

History
170 lines (132 loc) · 9.57 KB

File metadata and controls

170 lines (132 loc) · 9.57 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

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.

Development Setup

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.

Testing

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

Configuration is in .busted. Tests tagged builds are excluded from the default run.

Code Style

  • 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())

Architecture

Entry Points

  • src/Launch.lua — Application bootstrap, dev mode detection, renderer init
  • src/Modules/Main.lua — Loads game data, manages two modes: build list and build editor

Class System

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()).

Core Directories

  • src/Modules/ — Core logic: calculations, data loading, mod parsing, common utilities
  • src/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 GGPK
  • src/TreeData/ — Passive skill tree data per game version

Calculation Pipeline

  1. CalcSetup.lua — Builds modifier databases for player and enemy actors
  2. CalcOffence.lua — DPS and offense calculations
  3. CalcDefence.lua — Defense and mitigation calculations
  4. CalcPerform.lua — Performance breakdown display
  5. CalcActiveSkill.lua — Individual skill processing
  6. CalcTriggers.lua — Trigger/proc mechanics
  7. Calcs.lua — Orchestrates calculation modules, computes node/item/gem changes for sidebar and calcs tab

Modifier System

  • 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

UI Tab Structure

Build editor uses tabs: TreeTab, ItemsTab, SkillsTab, CalcsTab, ConfigTab, ImportTab, NotesTab, PartyTab. Each is a class in src/Classes/.

LÖVE Port (love/)

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 _G
  • love/shim/render.lua — Command-buffer renderer with layer sorting; handles CMD_RECT, CMD_IMAGE, CMD_MESH, CMD_POLYGON, CMD_TEXT, etc.
  • love/shim/init.lua — Orchestrator; also sets _G.LOVE_VERSION_TAG for UI display
  • love/lib/ — Compatibility shims: lua-utf8.lua, lcurl/safe.lua, lzip.lua
  • love/scripts/generate-manifest.sh — Regenerates manifest.xml with correct SHA1 hashes (run at build time, not on every push)

Dev Mode and Updates

  • src/Launch.lua enables devMode when manifest.xml has branch="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

Key Development Rules

Spell Checking (cspell)

  • 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:words directives at the top of the file (e.g., -- cspell:words LÖVE cdef for Lua, # cspell:words LÖVE pacman for shell)
  • For upstream code with typos, use cspell:ignore on the line above to avoid modifying upstream lines
  • Do NOT skip the hook with --no-verify — fix the spelling issues with inline directives

Branch Strategy

  • This fork tracks upstream/master (stable releases only), not upstream/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

Pull Requests

  • Target master branch
  • If mod parsing logic changes, regenerate ModCache with Ctrl+F5 and commit src/Data/ModCache.lua
  • Changes to src/Export/ scripts must include the regenerated src/Data/ output files

LÖVE Release Workflow

  • CI (.github/workflows/love-build.yml) triggers on love-v* tags and builds Windows + Linux packages
  • At build time, CI: (1) injects the git tag into LOVE_VERSION_TAG via sed, (2) runs generate-manifest.sh to regenerate SHA1 hashes, (3) sets manifest branch to master
  • manifest.xml is 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

Auto-Generated Files

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.

Game Patch Update Pipeline

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.luasrc/Data/StatDescriptions/*.lua (~20 files) — must run first
  • mods.luaModItem.lua, ModJewel.lua, ModJewelAbyss.lua, ModJewelCluster.lua, ModMap.lua, ModVeiled.lua, ModGraft.lua, ModTincture.lua, ModNecropolis.lua, ModFoulborn.lua
  • bases.luasrc/Data/Bases/*.lua (one per item type)
  • skills.luasrc/Data/Skills/act_str.lua, act_dex.lua, act_int.lua, other.lua, sup_*.lua, glove.lua, minion.lua, spectre.lua
  • enchant.luaEnchantmentBoots.lua, EnchantmentGloves.lua, EnchantmentHelmet.lua, etc.
  • essence.luaEssence.lua | cluster.luaClusterJewels.lua | masters.luaModMaster.lua
  • minions.luaMinions.lua | pantheons.luaPantheons.lua | miscdata.luaMisc.lua
  • crucible.luaCrucible.lua | costs.luaCosts.lua | bossData.luaBosses.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 definitions
  • src/Data/SkillStatMap.lua — stat-to-mod mappings
  • src/Export/Skills/*.txt, src/Export/Bases/*.txt — template files for export scripts
  • src/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.

Debugging

  • 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

Key Reference Files

  • docs/rundown.md — Detailed codebase layout
  • docs/addingMods.md — How mods are parsed
  • docs/modSyntax.md — Mod syntax reference
  • docs/addingSkills.md — How skills work in PoB
  • CONTRIBUTING.md — Full contribution guide
  • src/Data/Global.lua — Color codes, mod flags, skill type enumerations
  • love/shim/init.lua — LÖVE shim orchestrator, version tag
  • love/shim/render.lua — LÖVE rendering pipeline