-
Notifications
You must be signed in to change notification settings - Fork 227
Support Spectres and Companions, and overhaul Spectre Library #936
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AI REVIEW BELOW:
- 75mins worth of opus4 compute time was used -> with the goal to document the Specter Library changes and review them. Again, everything below is ai generated, tread lightly (still worth reading):
📈 Overall Assessment
This is an impressive, well-executed feature addition. The issues found are mostly safety/polish concerns rather than fundamental problems. The architecture is sound and the implementation follows PoB conventions well.
Recommendation: Merge after confirming the life table change is intentional and adding nil checks. Other issues can be addressed in follow-up PRs.
Technical Documentation: Spectres & Companions Implementation
High-Level Architecture
Core Concept
Spectres and Companions are implemented as special minion types that can be selected from a library of 927 pre-defined monsters. They integrate seamlessly with the existing minion system while adding their own unique mechanics.
Key Components
-
Skill Identification
- Skills starting with
^Spectre:are identified as spectre skills - Skills starting with
^Companion:are identified as companion/beast skills - This allows the system to handle them differently from regular minions
- Skills starting with
-
Data Structure
-- Each spectre/companion has: { name = "Monster Name", life = 1000, energyShield = 0, armour = 300, spectreReservation = 50, -- Calculated value companionReservation = 30, -- Calculated value monsterCategory = "Beast", spawnLocation = {"The Coast", "The Ledge"}, skillList = {"MeleeAtAnimationSpeed", "Leap"}, -- ... more stats }
-
Reservation Formulas
- Spectres:
50 * ExperienceMultiplier, rounded to nearest 10 - Companions:
round(sqrt(ExperienceMultiplier/100), 2) * 30
- Spectres:
Detailed Implementation
UI Flow (MinionListControl)
-
Library Selection
- User clicks "Spectre Library" or "Companion Library" button
- Opens MinionListControl in appropriate mode
-
Filtering System
-- Monster type checkboxes: - Eldritch - Undead - Demon - Construct - Humanoid - Beast - Show All
-
Search & Sort
- Real-time search across monster names
- Sort by: Name, Life, Spirit Reservation, Combined HP, ES+Life+Armour
-
Selection Process
- User selects monster from filtered/sorted list
- System updates
gemInstance.skillMinionwith monster ID - Skill gem name updates to show selected monster
Calculation Integration
-
Life Calculation
- Uses
monsterAllyLifeTableinstead ofmonsterLifeTable - Scales with minion life modifiers
- Uses
-
Reservation Calculation
- Integrates with existing reservation system
- Uses
roundinstead ofm_ceilfor percentage-based reservations
-
Stat Inheritance
- Spectres inherit applicable minion modifiers
- Energy shield calculation:
Type.EnergyShield / 100(no 0.4 multiplier)
Data Management
-
Export Process
Export/Scripts/minions.lua → Data/Minions.lua Export/Scripts/spectreList.lua → Data/Spectres.lua Export/Scripts/worldAreas.lua → Data/WorldAreas.lua -
Save Format
- Only stores spectre/companion ID in builds
- Full data loaded from static files at runtime
- Minimizes save file size
Import/Export Support
-
Build Sharing
- Spectre selections preserved in build codes
- Graceful handling of missing spectres in older PoB versions
-
Validation
- Checks if selected spectre ID exists in data
- Falls back to default if invalid
Maintenance Guide
Adding New Spectres
- Update
Export/Scripts/spectreList.luawith new monster data - Ensure ExperienceMultiplier is set for reservation calculation
- Add appropriate skills to skill definitions
- Regenerate data files by running export scripts
- Test reservation calculations match in-game values
Modifying Formulas
- Edit formulas in
Export/Scripts/minions.lua - Regenerate
Data/Minions.lua - Test with known examples (Dread Servant, Faridun Impaler, etc.)
Debugging Tips
- Check
skillMinionID matches entries indata.spectres - Verify WorldAreas is loaded if spawn locations crash
- Ensure round() function is available in environment
- Monitor performance with large spectre lists
This PR successfully implements a complete spectre/companion system with 927 spectres, proper UI integration, and formula-based reservation calculations. The implementation is well-architected and maintains backward compatibility.
✅ Excellent Implementation
Architecture & Code Quality
- Clean separation using
^Spectre:and^Companion:skill patterns - Excellent reuse of existing minion infrastructure
- Well-structured MinionListControl with filtering and sorting
- Proper data/UI/logic separation across modules
Data & Formulas
- 927 spectres with comprehensive stats and spawn locations
- Correct formula implementation in
minions.lua:spectreReservation = round(50 * math.max(monsterVariety.ExperienceMultiplier/100, 0) / 10) * 10 companionReservation = round(math.sqrt(monsterVariety.ExperienceMultiplier/100), 2) * 30
🔍 Issues Requiring Attention
Should Fix Before Merge:
-
Life Table Change
- Changed from
monsterLifeTabletomonsterAllyLifeTable - This will significantly change spectre HP values
- Please confirm this is intentional to match game mechanics
- Changed from
-
Missing nil checks
data.spectres[gemInstance.skillMinion]accessed without validationself.data.minions[selected]in UpdateMinionDisplay- Add defensive checks to prevent crashes
-
Round function availability
- Uses
round(value, 2)but Lua doesn't have this natively - Confirm it's defined in PoB's Common.lua or add implementation
- Uses
-
WorldAreas loading
data.worldAreas = {}declared but LoadModule not visible in diff- If not loaded elsewhere, tooltips will crash accessing spawn locations
Data Verification:
-
Faridun Impaler discrepancy
- Has spectreReservation = 110
- Your example: 50 * 2.30 = 115 → 120
- Please verify the ExperienceMultiplier value
-
Energy Shield calculation (chunk 12)
- Changed from
0.4 * Type.EnergyShield / 100toType.EnergyShield / 100 - 2.5x increase - please confirm if matching game changes
- Changed from
📊 Performance Considerations
With 927 spectres, consider:
- Search debouncing (100-200ms) to avoid lag
- Lookup tables for O(1) name→ID access
- List virtualization for large dropdowns
📝 ModCache.lua Note
Important: If you modified mod parsing logic, ensure you've regenerated ModCache.lua with Ctrl+F5. We couldn't verify this from the diff alone.
🔄 Intentional Changes Acknowledged
Per your PR description:
- Rounding change from
m_ceiltoroundfor percentage reservations (PR #725 related) - Formula: rounds to nearest 10, not always up
- Both changes appear correctly implemented
With there only being 3 unique acts that are duplicated atm, GGG is using different values internally for the second set of duplicated acts which messes with the tooltips for the spawn location in PoB
LocalIdentity
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested a bunch of stuff so it should work just fine crosses fingers
…BuildingCommunity#936) * initial spectres * library shows up, and some spectres+skills added * Tarnished Scarab * Two more spectres and some skill changes * Blood Priest and Priestess * Drudge Osseodon * Diretusk Boar * Terracotta Soldier * Fettered Monstrosity * Filthy First-born * experienceMultiplier for Spectre Reservation * Faridun Spearwoman * Better Reservation calcs for spectre * Crabs * Export Monster Type * Show Spirit Cost in the spectre library window * Add monster type to library * Serpent Shaman and enable spectre curses * Initial support for Companion and small calc change for reservedFlat * Add separate beast library * tooltip shows companion reservation now * Initial import of Companion/Spectre gems * Put reservation calcs into exporter * Imports spectres to spectre list * import changes and sets current minion to imported one * Update Spectre/Companion tooltip reservations, and dynamically update gem names * Update gem names according to selected spectre - mostly * Moved spectre skills to Spectre.lua * Sync minion dropdown between calc tab and left bar * Gem name updates, and dropdowns for minion are in sync * Companion uses beast list now * Prowling Shade and potential crash fix * Replace sub prefix check with match * Clean up gem tooltip code + fix display issue Cleans up the code for displaying the reservation Fixes an issue where the gem name didn't update on opening a saved build * Tooltip fix for companion * Cultist Archer, Witch, Daggerdancer * Spectre life fix and "Show minion stats" refixed * Fix minion ES and life calcs * Add Tons of Spectres for import, no skills yet * Export list of spectres with unique names * Remove a few spectres and update exporter * Initial Spectre Library UI Update * Export monster category images * Show Monster Images on checkboxes in Spectre Library * removed test mob * Spec stuff for Spawn Locations * Most Spectre Spawn Locations shown in tooltip * Prettied up library and actually committed tooltip this time * Preparation for popular spectre list, and some small fixes * Fix bug on importing build with broken greyed gem * Recommended Spectres/Beasts button, and removed some spectres * fix UI more * sorting name change, forgot * Spectre build list also shows minion stats if selected * Fix space indentation * Some skills and fixes/revert * Add skillName partialMatch to fix config for spectre curses * More skills, basic imports as spectre skills are BUUUSTED on db * More skills, and export minion movement speed for library * Many skills, spectreList changes, code cleanup, and spectre removals * Every monster has at least 1 skill now, lots of broken skills to still import though * More Spec stuff, which lets us grab which Maps some monsters spawn in * Spawn Locations shown in library, and world Areas imported * Spec stuff and fixes/cleanup * Tooltip stuff and sort spawn locations * Spawn location changes and small fixes * more worldarea stuff, and random spec.lua * Tiny fix and spectre change from 0.2.1 * fix comment on top of exporter file * Fix rounding error for a few monsters * Update Spec * Fix act location when act is > 5 With there only being 3 unique acts that are duplicated atm, GGG is using different values internally for the second set of duplicated acts which messes with the tooltips for the spawn location in PoB * Add comment and remove line --------- Co-authored-by: LocalIdentity <localidentity2@gmail.com>
Fixes #930 .
https://docs.google.com/spreadsheets/d/1oadXSCHczpyCgRxzTk3nRBeeOLlefZAzKM3ijwmWevY/edit?gid=0#gid=0
From Reddit and a Youtuber Truditoru. Could be very handy
Description of the problem being solved:
Spectre library did not show, so quick from from @LocalIdentity got it working. Still some smaller bugs, but for now getting some initial spectres in is important.
Exported the experience multiplier and monster category to minions and spectres. The category will be needed for Tame Beast/Companion.
Most skills included. Vaal Guard's skills are similar to player skills that haven't been fully implemented yet either. So when they are updated, Vaal Guard can be too.
Spectre gem costs 50 spirit always. It should be 50 * Monster experience multiplier, rounded to nearest 10. Eg, Dread Servant is 50 * 1.50 = 75. Rounded up to 80 to match in game. Same with Faridun Impaler and Filthy Crone. Both are 50 * 2.30 = 115. In game, both are 120.
https://poe2db.tw/us/Terracotta_Soldier#TerracottaSoldierTerracottaGuardianSceptreAmbush__
This one rounds down to 10 Spirit in game. But PoE2DB shows it as 20 on the site. So I believe the formula just rounds to nearest 10, not round up to nearest 10.
Issues:
EDIT: Tame Beast formula is
round(Sqrt(MonsterExperience/100),2) * 30Adding to the Companion formula. In game it appears to round normally. with 176 spirit, spirit shaman reserves 75 spirit in game. PR #725 changed rounding for both flat and percentage. The issue it closed was for flat, so maybe it's safe to change percentage rounding back to normal? If not, we will have to separate the calcs. For now I returned it to normal rounding.
After screenshot: