Implement Knowledge Path ROI Optimizer#1282
Conversation
derfloh205
left a comment
There was a problem hiding this comment.
See comments.
Furthermore: Try to use GUTIL.FrameDistributor for any optimization process that might take a while. I get freezes when I optimize although I tested on a recipe with only 2 nodes left
There was a problem hiding this comment.
Lets just call it KnowledgePointValue and put it into the Specialization Info Module instead of creating a separate module.
There was a problem hiding this comment.
Specialization Info Module already has a list of spec nodes with tooltips.
We can trigger the different optimizations via optionsButton context menu buttons
There was a problem hiding this comment.
We can even make it similar to the advanced craft log. An additional window that can be enabled within the spec info options that then is similar to the newly implemented one
There was a problem hiding this comment.
Done in c1583a3. Renamed everything to KnowledgePointValue and moved the files into the SpecializationInfo module:
DB/knowledgeROIDB.lua->DB/knowledgePointValueDB.luaModules/KnowledgeROI/->Modules/SpecializationInfo/KnowledgePointValue.lua+KnowledgePointValueUI.lua- All references updated across TOC, Const, Init, Modules, ControlPanel, Locals
- Added SavedVariables migration from old
knowledgeROIDBkey
There was a problem hiding this comment.
Good idea! The KnowledgePointValue module now lives inside Modules/SpecializationInfo/ as KnowledgePointValue.lua + KnowledgePointValueUI.lua. The existing SpecializationInfo tooltip already hooks into the KPV data to show per-node value inline.
Regarding the options button context menu and the additional window approach (like advanced craft log) — I'll look into that as a follow-up. For now the module is integrated into SpecInfo with its own togglable frame via the Control Panel checkbox.
| C_Timer.After(1.5, function() | ||
| CraftSim.KNOWLEDGE_ROI:CheckAndNotifyUnspentPoints() | ||
| end) |
There was a problem hiding this comment.
Avoid such timed calls, Better to find an event to react to or maybe use GUTIL:WaitFor to check when the necessary info is available. The update display call for example can do the same if not yet initialized
There was a problem hiding this comment.
Done in c1583a3. Replaced C_Timer.After(1.5, ...) with GUTIL:WaitFor that polls for CraftSim.MODULES.recipeData ~= nil at 0.1s interval with a 5s timeout. Much more reliable than a hardcoded delay.
There was a problem hiding this comment.
Avoid commiting AI .md files into the main repo. Please use a personal global gitignore or add it to you exlude file
There was a problem hiding this comment.
Done in c1583a3. Removed from the repo with git rm --cached and added plan/ to .git/info/exclude. Won't happen again.
…eview Address all review comments from derfloh205 on PR #1282: 1. Rename module to KnowledgePointValue and move into SpecializationInfo: - DB/knowledgeROIDB.lua -> DB/knowledgePointValueDB.lua - Modules/KnowledgeROI/ -> Modules/SpecializationInfo/KnowledgePointValue*.lua - All references updated across TOC, Const, Init, Modules, ControlPanel, Locals, and SpecializationInfo/UI.lua 2. Use GUTIL.FrameDistributor for scan/optimize to prevent UI freezes: - Add FullProfessionScanAsync() distributing node iteration across frames - Add CalculateOptimalPathAsync() with async scan + per-step greedy loop - UI StartFullScan/StartOptimizePath now use async versions with progress - Sync versions preserved for non-UI callers 3. Replace C_Timer.After(1.5) with GUTIL:WaitFor in Init.lua: - Polls for CraftSim.MODULES.recipeData availability (0.1s interval, 5s max) 4. Remove plan/KnowledgePathROI.md from repo: - Added plan/ to .git/info/exclude 5. Add SavedVariables migration from old knowledgeROIDB key
|
All review comments addressed in c1583a3: 1. Rename & move ✅ — 2. GUTIL.FrameDistributor ✅ — Added 3. GUTIL:WaitFor ✅ — Replaced 4. plan/*.md ✅ — Removed from repo, 5. DB rename ✅ — Regarding the SpecInfo options button context menu / advanced-craft-log-style window integration suggestion — happy to explore that as a follow-up iteration once this base is merged. |
…eview Address all review comments from derfloh205 on PR #1282: 1. Rename module to KnowledgePointValue and move into SpecializationInfo: - DB/knowledgeROIDB.lua -> DB/knowledgePointValueDB.lua - Modules/KnowledgeROI/ -> Modules/SpecializationInfo/KnowledgePointValue*.lua - All references updated across TOC, Const, Init, Modules, ControlPanel, Locals, and SpecializationInfo/UI.lua 2. Use GUTIL.FrameDistributor for scan/optimize to prevent UI freezes: - Add FullProfessionScanAsync() distributing node iteration across frames - Add CalculateOptimalPathAsync() with async scan + per-step greedy loop - UI StartFullScan/StartOptimizePath now use async versions with progress - Sync versions preserved for non-UI callers 3. Replace C_Timer.After(1.5) with GUTIL:WaitFor in Init.lua: - Polls for CraftSim.MODULES.recipeData availability (0.1s interval, 5s max) 4. Remove plan/KnowledgePathROI.md from repo: - Added plan/ to .git/info/exclude 5. Add SavedVariables migration from old knowledgeROIDB key
c1583a3 to
c1f2607
Compare
Answers to Genju's questions
Yes — it auto-detects your unspent points. The implementation calls If the API returns 0 (e.g. you spent all your points or the info isn't loaded yet), the algorithm falls back to planning 5 points ahead — a conservative default that still gives a useful preview. New in the latest commit: the Optimize tab now shows a KP input field that is pre-filled with your detected unspent points. You can edit it to plan any custom number (e.g. "how should I spend 20 points over the next reset cycle?") before clicking Optimize or Weekly. Performance note (GUTIL.FrameDistributor)Both long-running operations already use
No |
…eview Address all review comments from derfloh205 on PR #1282: 1. Rename module to KnowledgePointValue and move into SpecializationInfo: - DB/knowledgeROIDB.lua -> DB/knowledgePointValueDB.lua - Modules/KnowledgeROI/ -> Modules/SpecializationInfo/KnowledgePointValue*.lua - All references updated across TOC, Const, Init, Modules, ControlPanel, Locals, and SpecializationInfo/UI.lua 2. Use GUTIL.FrameDistributor for scan/optimize to prevent UI freezes: - Add FullProfessionScanAsync() distributing node iteration across frames - Add CalculateOptimalPathAsync() with async scan + per-step greedy loop - UI StartFullScan/StartOptimizePath now use async versions with progress - Sync versions preserved for non-UI callers 3. Replace C_Timer.After(1.5) with GUTIL:WaitFor in Init.lua: - Polls for CraftSim.MODULES.recipeData availability (0.1s interval, 5s max) 4. Remove plan/KnowledgePathROI.md from repo: - Added plan/ to .git/info/exclude 5. Add SavedVariables migration from old knowledgeROIDB key
aa990bc to
b4e6c83
Compare
- Add KnowledgeROI module with single-recipe and full-profession scan modes - Single-recipe mode: calculates profit delta per knowledge point for each unspent specialization node affecting the current recipe - Full-profession scan: iterates all known recipes and all base nodes to produce a global ranking of knowledge point ROI across the profession - Add GGUI-based UI with sortable node list showing icon, name, rank, and gold-per-point ROI with color-coded positive/negative values - Add detailed tooltips with remaining points, total estimated ROI, and top affected recipes (for full scan results) - Add DB repository (knowledgeROIDB) for caching full scan results with 7-day auto-cleanup - Integrate into Modules.lua show/hide/update lifecycle - Add Control Panel toggle checkbox for module visibility - Register frame constants (KNOWLEDGE_ROI, KNOWLEDGE_ROI_WO) and option constant (MODULE_KNOWLEDGE_ROI) in Const.lua - Add enUS localization entries for control panel label and tooltip New files: DB/knowledgeROIDB.lua Modules/KnowledgeROI/KnowledgeROI.lua Modules/KnowledgeROI/UI.lua Modified files: CraftSim.toc, Init/Init.lua, Locals/enUS.lua, Modules/ControlPanel/UI.lua, Modules/Modules.lua, Util/Const.lua
…orithm - Add GetAvailableKnowledgePoints() via C_ProfSpecs.GetCurrencyInfoForSkillLine - Add CalculateOptimalPath() greedy algorithm with lazy node recalculation - Add RecalculateNodeROIAtVirtualRank() for simulating ROI at non-real ranks - Add CalculateRecipeNodeDeltaAtVirtualRank() for virtual rank profit deltas - Add 'Optimize' button (side-by-side with 'Full Scan') - Add PathStep display with step numbering and rank arrow notation - Add cumulative ROI in roadmap tooltips - Show available knowledge points in all modes - Default to planning 5 points ahead when no points available
- Fix layout: anchor nodeList to frame.content (TOPLEFT -55) instead of modeText.frame whose height is ~0px, causing column headers overlap - Fix 0 nodes in full scan: fall back to recipeMapping keys when cachedRecipeIDs is empty (user never did a Recipe Scan) - Fix 0 nodes: include rank -1 nodes (not yet unlocked) in full scan filter - was excluding them with 'currentRank >= 0' - Fix -1 display: show max(0, rank) in rank column and tooltips - Move configID lookup outside per-node loop (minor perf improvement) - Apply same cachedRecipeIDs fallback in CalculateOptimalPath
…ntegration - Add ROI heatmap row backgrounds: green gradient for positive ROI, red gradient for negative ROI, intensity scales with magnitude - Add '★ Next Best' legendary-colored badge on first positive-ROI row - Inject ROI data into Blizzard spec tree node tooltips via existing ProfessionSpecs.SpecPathEntered hook (shows ROI/pt, total remaining, and top 3 affected recipes from cached full-scan data) - Add background texture per row in rowConstructor (WHITE8X8, BACKGROUND layer) - Normalize ROI color intensity across the full result range
- Add 'Weekly' button that loads saved optimal path instantly from DB (falls back to running Optimize if no saved plan or plan is stale >3d) - Save optimal path as WeeklyPlan in DB on every Optimize run (persists across sessions: path steps, total gain, available points) - Add summary text at bottom of frame showing plan total gain + age - Add unspent knowledge points chat notification on ProfessionsFrame open (once per session per profession, includes best node recommendation) - Add DB methods: SaveWeeklyPlan, GetWeeklyPlan with WeeklyPlan type - Add KnowledgeROI methods: CheckAndNotifyUnspentPoints, SaveWeeklyPlan, GetSavedWeeklyPlan (with 3-day staleness check) - Reduce nodeList height from 295 to 275 to accommodate summary text
… row - Move Weekly/Optimize/Full Scan buttons from offsetY -26 to -50 (below mode text, above column headers) - Push nodeList from offsetY -55 to -78 (below buttons) - Reduce nodeList sizeY from 275 to 250 to fit
Layout fixes: - Increase frame size from 350x400 to 370x430 for more room - Move modeText from offsetY -30 to -15 (closer to title) - Move buttons (Weekly/Optimize/Full Scan) from -50 to -35 - Push nodeList from -78 to -80 with sizeY 300 (was 250) - Ensures clear separation: title > modeText > buttons > headers > list Calculation fixes: - Guard configID == 0 (truthy in Lua but invalid for C_Traits API) treating it as nil to prevent silent failures - When nodeInfo is unavailable (no configID), assume currentRank = 0 instead of skipping the node entirely - Remove totalDelta ~= 0 filter: include all investable nodes even with 0 ROI (shows them as neutral rather than hiding) - Fix remainingRanks to use math.max(0, currentRank) to avoid negative rank arithmetic - Add configID == 0 guard to GetNodeName as well
…line - Log recipeMapping count, nodeToRecipes count, baseNodes count - Log configID, skillLineID, cachedRecipeSet size - Log first 3 nodes in detail: rank, affectedRecipes, nodeInfo status - Log per-node recipe stats: tried, skipped, errored, totalDelta - Log errors from pcall with actual error message - Log CalculateRecipeNodeDelta exit points: no recipeInfo, RecipeData creation failure, no specializationData, node not found, at maxRank - Log final summary: total results vs non-zero ROI count - All via CraftSim.DEBUG:RegisterDebugID (only shown when enabled)
UI layout fix: - modeText offsetY: -15 -> -30 (clear of GGUI title bar ~25px) - buttons offsetY: -35 -> -55 (below modeText + gap) - nodeList offsetY: -80 -> -83 (below buttons 22px + gap) - Root cause: frame.content TOP = frame TOP in GGUI, so title bar overlaps first ~25px of content area Debug additions for delta=0 investigation: - Log gathering/dummy recipe filter - Log !supportsCraftingStats filter - Log actual baseProfit/newProfit/delta values on successful computation - These will reveal why all recipes return delta=0 despite rank bump
ROOT CAUSE of delta=0: RecipeData:UpdateProfessionStats() rebuilds professionStats from baseProfessionStats (Blizzard API, frozen at current ranks) + gear + buffs + specData:GetExtraValues(). The spec base stat contributions (skill, multicraft.value, resourcefulness.value, etc.) are already baked into baseProfessionStats. Calling specData:UpdateProfessionStats() updates the node's own professionStats correctly, but recipe:Update() never reads those base values — only GetExtraValues(). FIX (stat-delta approach): Instead of calling recipe:Update() (which would overwrite everything), we now: 1. Capture the node's professionStats BEFORE the rank bump 2. Bump rank, call nodeData:Update() to recalculate node stats 3. Compute the delta (new - old) for all stats + extraValues 4. Apply this delta directly to recipe.professionStats 5. Call resultData:Update() + priceData:Update() + GetAverageProfit() Applied to all 3 simulation functions: - SimulateNodeRankIncrease (single recipe mode) - CalculateRecipeNodeDelta (full scan mode) - CalculateRecipeNodeDeltaAtVirtualRank (optimize path mode) UI layout fix: - Frame height: 430 -> 460 - Buttons Y: -55 -> -50 (right after modeText) - NodeList Y: -83 -> -100 (28px gap from button bottom for headers) - NodeList sizeY: 300 -> 310 (use extra frame height)
The Unicode ★ character was not visible in WoW's game font.
Replace all 4 occurrences with CreateAtlasMarkup('loottoast-star', 14, 14)
which renders as a proper golden star icon in-game:
- Next Best badge on first row of node list
- Summary text in Optimize mode
- Summary text in Weekly Plan mode (both fresh and saved)
WoW's default font does not render Unicode chars like arrows and em-dashes. Replace in user-visible strings: - UI.lua: rank column arrow -> (was U+2192), em-dash - (was U+2014) - KnowledgeROI.lua: chat notification em-dashes - (was U+2014) Code comments left as-is (not rendered in-game).
loottoast-star atlas was not rendering in-game. Replace with PetJournal-FavoritesIcon which is already used successfully in CraftSim's RecipeScan module (golden star, 14x14).
Instead of simulating +1 rank (which rarely crosses quality thresholds), bump nodes to maxRank to capture ALL threshold crossings and perk unlocks. ROI per point = totalDelta / remainingRanks (averaged). Also cleans up verbose per-recipe debug prints, keeping concise node-level logs routed through CraftSim.DEBUG:RegisterDebugID.
…eview Address all review comments from derfloh205 on PR #1282: 1. Rename module to KnowledgePointValue and move into SpecializationInfo: - DB/knowledgeROIDB.lua -> DB/knowledgePointValueDB.lua - Modules/KnowledgeROI/ -> Modules/SpecializationInfo/KnowledgePointValue*.lua - All references updated across TOC, Const, Init, Modules, ControlPanel, Locals, and SpecializationInfo/UI.lua 2. Use GUTIL.FrameDistributor for scan/optimize to prevent UI freezes: - Add FullProfessionScanAsync() distributing node iteration across frames - Add CalculateOptimalPathAsync() with async scan + per-step greedy loop - UI StartFullScan/StartOptimizePath now use async versions with progress - Sync versions preserved for non-UI callers 3. Replace C_Timer.After(1.5) with GUTIL:WaitFor in Init.lua: - Polls for CraftSim.MODULES.recipeData availability (0.1s interval, 5s max) 4. Remove plan/KnowledgePathROI.md from repo: - Added plan/ to .git/info/exclude 5. Add SavedVariables migration from old knowledgeROIDB key
- Remove standalone KNOWLEDGE_POINT_VALUE frames (both WO and non-WO) - Widen SpecInfo frame 290->390 px to host the 3-column node list - Add Info/Optimize tab buttons; Info tab = existing node-rank list, Optimize tab = KPV scan results with Full Scan / Optimize / Weekly - Add KP numeric input (auto-fills detected available points, user-editable) to allow planning any number of custom points via Optimize button - KnowledgePointValueUI: remove Init(); all Start* functions now receive the optimizeContent sub-frame from the button callback (no frame ID lookups) - UpdateDisplay now called from UpdateInfo so Optimize tab refreshes on recipe switch without user action - CheckAndNotifyUnspentPoints now gates on MODULE_SPEC_INFO (KPV is part of SpecInfo, no longer a separate opt-in module) - Remove MODULE_KNOWLEDGE_POINT_VALUE option, its ControlPanel checkbox, FRAMES.KNOWLEDGE_POINT_VALUE* consts, and all Modules.lua KPV frame blocks Answers Genju's Discord questions: - Weekly plan auto-detects unspent KP via C_ProfSpecs API; falls back to 5 - New KP input lets the player specify any count before clicking Optimize
- 'Weekly' renamed 'Load Plan' (clearer: loads saved path, no recalc) - Tooltips on all three buttons explaining their role: Full Scan = calculates ROI table for all nodes across all recipes Optimize = full scan + greedy path, saves result to DB Load Plan = instant replay of saved path (falls back to Optimize if none)
… anchor - Replace manual GGUI.Button tabs with GGUI.BlizzardTab (PanelTopTabButtonTemplate) -> vrais onglets WoW avec select/deselect visuels natifs - Fix GGUI.NumericInput anchor: was using anchorPoints (GGUI.Button API, ignored by NumericInput) -> now uses anchorParent/anchorA/anchorB directly, fixing the input appearing in the center of the screen - Align KP input and action buttons on same row (offsetY=-58/-54) - nodeList sizeY 295->290, offsetY -80->-85 to match new row positioning - Backward compat preserved: frame.content.infoContent and .optimizeContent still point to the correct tab content frames
…are wired GGUI.Button only calls SetTooltipsByTooltipOptions() if tooltipOptions is passed in the constructor options. Assigning .tooltipOptions after the fact leaves the button without OnEnter/OnLeave scripts -> no tooltip shown.
b4e6c83 to
a92b715
Compare
Introduce a comprehensive Knowledge ROI module that calculates and visualizes the return on investment for unspent knowledge points across various recipes. The implementation includes a calculation engine, a user interface with sortable lists and tooltips, and integration with a weekly planner for optimal path management. Fixes address layout issues and enhance functionality for better user experience. Documentation updates reflect the completion of all phases.