Skip to content

Conversation

@BUSTheid
Copy link
Contributor

@BUSTheid BUSTheid commented Nov 10, 2025

What did you fix?

fixes #602

Note: First ever OSS contribution, developed with AI assistance. Open to all feedback and criticism!

All relic refinement levels (Intact, Exceptional, Flawless, Radiant) were showing identical drop rates (e.g. 2% for rare items) instead of their refinement-specific rates.

The bug was in the addRelics function which was using reward data from @wfcd/relics package (which only contains Intact/base drop rates) instead of the drops API (which has accurate refinement-specific data).


Reproduction steps

  1. Clone master branch and run npm install && npm run build -- --force
  2. Open generated data/json/Relics.json
  3. Find "Axi A1 Intact" - rare item shows 2% chance
  4. Find "Axi A1 Radiant" - rare item also shows 2% chance (should be 10%)
  5. This affects all relics at all refinement levels

Evidence/screenshot/link to line

  • Code fix:
  • Test added: test/index.spec.mjs:368-403
  • Before: All* refinement levels had identical distribution patterns (all showing Intact rates: 25.33%, 11%, 2%)
  • After: Each refinement level has its correct distribution pattern:
    • Intact:
      • 3 items @ 25.33%,
      • 2 @ 11%,
      • 1 @ 2%
    • Exceptional:
      • 3 items @ 23.33%,
      • 2 @ 13%,
      • 1 @ 4%
    • Flawless:
      • 3 items @ 20%,
      • 2 @ 17%,
      • 1 @ 6%
    • Radiant:
      • 3 items @ 16.67%,
      • 2 @ 20%,
      • 1 @ 10%

*Note: The test validates drop rate distribution patterns across all refinement levels. However, 2 workarounds were necessary for existing data issues unrelated to this fix:

  1. Axi S19 Relic (test/index.spec.mjs:383-386): Has no rewards in the data, likely because this relic doesn't exist in the actual game. The test skips empty reward arrays.
  2. I fixed this bug, which I accidentally introduced! Meso D1 Relic (test/index.spec.mjs:388-391): Contains two "2X Forma Blueprint" entries that should have different drop chances (25.33% and 11% in upstream drops API), but both end up with the same chance due to what appears to be an item deduplication issue in the parser. This causes the distribution pattern to differ from expected. The test skips this relic to avoid false failures.

Considerations

  • Does this contain a new dependency? No
  • Does this introduce opinionated data formatting or manual data entry? No
  • Does this pr include updated data files in a separate commit that can be reverted for a clean code-only pr? Yes
  • Have I run the linter? Yes
  • Is is a bug fix, feature request, or enhancement? Bug Fix

Summary by CodeRabbit

  • New Features

    • Relic rewards are now enriched with drop-rate data, merging chance values from drop tables into displayed rewards.
  • Bug Fixes

    • Relic rewards now display more accurate drop chances based on refinement levels.
  • Tests

    • Added test coverage to validate relic drop rate distributions across refinement levels.

@BUSTheid BUSTheid requested a review from a team as a code owner November 10, 2025 08:43
@coderabbitai
Copy link

coderabbitai bot commented Nov 10, 2025

Walkthrough

The PR expands Parser.addRelics to accept drop-rate data and enrich relic rewards using drops: it derives a dropPlaceName from relic names, filters matching drops, merges drop-based chances into each reward (deduplicated, first-match), updates call sites, and adds a test validating relic drop distributions by refinement level.

Changes

Cohort / File(s) Summary
Parser relic-drops integration
build/parser.mjs
Signature changed to addRelics(item, relics, drops); call site updated to pass data.drops. Implementation now: compute baseRewards from relics, derive dropPlaceName from relic name, filter dropsForRelic, and merge drop chance data into each reward (preserving existing metadata, deduplicating by reward uniqueName, first-match wins). Market/vault info handling retained; rewards replaced in-place with drops-aware values.
Relic drop distribution test
test/index.spec.mjs
Added test that constructs relics, filters by refinement level, groups rewards by chance, and asserts exact chance distributions per relic (skips relics with no rewards; contains note about known bug).

Sequence Diagram(s)

sequenceDiagram
    participant Parser
    participant Relics as Relics Data
    participant Drops as Drops Data
    participant Rewards as Final Rewards

    Note over Parser,Relics: New flow: enrich relic rewards with drops
    Parser->>Relics: receive relics (with rewards metadata)
    Parser->>Drops: receive drops array
    Parser->>Parser: derive dropPlaceName from relic.name
    Parser->>Drops: filter dropsForRelic (place == dropPlaceName)
    Parser->>Parser: map baseRewards -> for each reward:
    alt matching drop found
        Parser->>Parser: merge drop.chance into reward (first-match, dedupe)
    else no match
        Parser->>Parser: keep original reward metadata
    end
    Parser->>Rewards: assign enriched rewards back to item
    Note right of Rewards: rewards now include drops-aware chances
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to: dropPlaceName derivation (pattern matching), correctness of drops filtering, deduplication/first-match merging behavior, and in-place replacement of rewards.
  • Review the new test for correct expectations and the skipped-case note (known bug).

Possibly related PRs

Suggested reviewers

  • TobiTenno
  • Soundofdarkness

Poem

🐰 In relic halls where small drops hide,
I hop and match each chance with pride.
Names aligned and chances sewn,
Rewards now richer, wisely grown.
Test the levels — the rabbit's noted guide.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing relic refinement drop rates by using drops API data instead of base Intact rates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
build/parser.mjs (2)

1096-1107: Consider adding observability for drops data merge outcomes.

The current implementation silently falls back to original reward data when no matching drop is found. This could mask issues with drops API data availability or formatting. Consider adding logging or metrics to track merge success/failure rates.

Example approach (add after line 1107):

        // Log merge statistics for observability
        const mergedCount = relicItem.rewards.filter(r => 
          dropsForRelic.some(d => d.item === r.item?.name)
        ).length;
        if (mergedCount === 0 && dropsForRelic.length > 0) {
          console.warn(`No rewards merged for ${name}: format mismatch between drops and relics data`);
        }

1096-1098: Document the expected relic name format and drops API key format.

The string manipulation logic assumes specific naming patterns for relics (ending with refinement level) and constructs the drops API lookup key accordingly. Consider adding a comment documenting the expected formats to aid future maintenance.

Example documentation:

        // Build the correct "place" name for drops API lookup
        // Expected relic name formats:
        //   - "Lith A1 Intact" -> drops key: "Lith A1 Relic"
        //   - "Lith A1 Exceptional" -> drops key: "Lith A1 Relic (Exceptional)"
        //   - "Lith A1 Radiant" -> drops key: "Lith A1 Relic (Radiant)"
        const dropPlaceName = name.endsWith('Intact')
          ? name.replace(/\sIntact$/, ' Relic')
          : name.replace(/\s(\w+)$/, ' Relic ($1)');
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e523192 and ddae90c.

📒 Files selected for processing (3)
  • build/parser.mjs (3 hunks)
  • data/warnings.json (1 hunks)
  • test/index.spec.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: SlayerOrnstein
Repo: WFCD/warframe-items PR: 663
File: config/masterableCategories.json:1-2
Timestamp: 2024-12-03T23:47:24.677Z
Learning: In the 'warframe-items' repository, when suggesting changes to regex patterns in 'config/masterableCategories.json', ensure that added patterns only include items relevant to the current PR context, and avoid adding items not present in the context.
📚 Learning: 2025-03-29T18:52:41.800Z
Learnt from: TobiTenno
Repo: WFCD/warframe-items PR: 714
File: build/parser.mjs:451-469
Timestamp: 2025-03-29T18:52:41.800Z
Learning: Wiki data in the warframe-items builder should not have null checks as it's critical for the build process - if wiki fetch fails, the build should fail to prevent propagating incorrect data downstream.

Applied to files:

  • data/warnings.json
🧬 Code graph analysis (1)
build/parser.mjs (1)
build/scraper.mjs (1)
  • data (94-94)
🔇 Additional comments (3)
data/warnings.json (1)

9-9: LGTM!

The expanded missingWikiThumb list provides more comprehensive tracking of items missing wiki thumbnails. This is consistent with the broader data completeness improvements in this PR.

build/parser.mjs (1)

1074-1074: Function signature update is correctly propagated across all call sites.

The search found one call site at line 202 that correctly passes all three arguments including the drops parameter: this.addRelics(result, data.relics, data.drops). The function definition at line 1074 matches the expected signature with all three parameters. No updates are needed.

test/index.spec.mjs (1)

368-410: Verify that known relic bugs are tracked in your issue tracker.

The test is well-structured with clear documentation of workarounds for known data issues. However, I was unable to complete automated verification of whether Axi S19 (empty rewards) and Meso D1 (duplicate item) bugs are tracked in your issue system. Please manually confirm these data quality issues are documented in your tracker.

@BUSTheid BUSTheid changed the title Fix/relic refinement drop rates fix: relic refinement drop rates Nov 10, 2025
@BUSTheid BUSTheid force-pushed the fix/relic-refinement-drop-rates branch from c6bd6d4 to 5649f24 Compare November 10, 2025 12:55
@BUSTheid
Copy link
Contributor Author

I've cleaned up the commit history with a force push. The PR now has 2 commits (code changes + rebuilt data), fixing the regression I accidentally created when trying to fetch Meso D1 Relic (which reported identical values for both 2x Forma Blueprint entries)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
build/parser.mjs (1)

1072-1074: Function signature update looks good.

The addition of the drops parameter with corresponding JSDoc enables refinement-specific drop rate processing.

Optionally, you could make the JSDoc more specific by adding the type annotation:

-   * @param {Array<DropRate>} drops drop rate data for refinement-specific chances
+   * @param {Array<DropRate>} drops drop rate data for refinement-specific chances

(Though the description is already clear enough.)

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6bd6d4 and 5649f24.

📒 Files selected for processing (3)
  • build/parser.mjs (3 hunks)
  • data/warnings.json (1 hunks)
  • test/index.spec.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/index.spec.mjs
  • data/warnings.json
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: SlayerOrnstein
Repo: WFCD/warframe-items PR: 663
File: config/masterableCategories.json:1-2
Timestamp: 2024-12-03T23:47:24.677Z
Learning: In the 'warframe-items' repository, when suggesting changes to regex patterns in 'config/masterableCategories.json', ensure that added patterns only include items relevant to the current PR context, and avoid adding items not present in the context.
🔇 Additional comments (2)
build/parser.mjs (2)

202-202: LGTM! Drops data correctly passed to addRelics.

The addition of data.drops as the third argument enables refinement-specific drop rate integration as intended.


1089-1118: Well-implemented drops integration with proper edge case handling.

The implementation correctly integrates refinement-specific drop rates from the Drops API while preserving reward metadata from the relics package. Key strengths:

  • dropPlaceName construction (lines 1093-1096) correctly maps relic names to Drops API format for all refinement levels
  • Null safety (line 1105) properly addresses the previous review concern about reward.item.name with a clean guard clause approach
  • Duplicate handling (lines 1102-1117) uses usedDropIndices Set to ensure each drop is matched only once when the same item appears multiple times
  • Graceful fallbacks handle missing drops data (line 1099) and unmatched rewards (line 1116)

@TobiTenno
Copy link
Member

@BUSTheid thanks! approving shortly, just waiting for the checks to pass!

@TobiTenno TobiTenno enabled auto-merge (squash) November 10, 2025 19:03
@TobiTenno TobiTenno added Type: Bug Scope: Data How data is represented or cleaned up Severity3: Minor The defect affects minor functionality or non-critical data. It has an easy workaround. labels Nov 10, 2025
@BUSTheid
Copy link
Contributor Author

Build got cloudflare-gated lol

@TobiTenno
Copy link
Member

Yeah, if you could drop your new data updates off of it, I'll merge once it doesn't have conflicts (new conflicts are coming from master branch generating new data) and I'll test it locally.

auto-merge was automatically disabled November 12, 2025 13:20

Head branch was pushed to by a user without write access

@BUSTheid BUSTheid force-pushed the fix/relic-refinement-drop-rates branch 2 times, most recently from c79fcde to e9aa5f8 Compare November 12, 2025 13:20
Previously, all relic refinement levels (Intact, Exceptional, Flawless, Radiant) were getting identical drop rates because the `addRelics` function only used data from `@wfcd/relics` package, which contains only base (Intact) variants.

Now fetches refinement-specific drop rates from the drops API and correctly matches them to rewards, including handling for duplicate item names in a single relic (e.g., Meso D1).

Adds test validating distribution pattern across all refinement levels.

Fixes WFCD#602
@BUSTheid BUSTheid force-pushed the fix/relic-refinement-drop-rates branch from e9aa5f8 to 26d58a4 Compare November 12, 2025 13:25
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
build/parser.mjs (2)

1089-1096: Consider the effectiveness of Set-based deduplication.

Line 1091 uses Array.from(new Set(...)) to deduplicate rewards. Since Set compares by object reference, not deep equality, and flat() creates new object instances from each relic's rewards array, the deduplication may not work as intended—identical reward objects from different relics would not be deduplicated.

If deduplication by value is required, consider using a helper like dedupe (imported at line 18) or a manual deduplication strategy. If the current behavior is intentional (keeping all reward instances), the Set wrapper adds no value and could be removed for clarity.

-        const baseRewards = Array.from(new Set(related.map((relic) => relic.rewards).flat()));
+        const baseRewards = related.map((relic) => relic.rewards).flat();

1104-1117: Good null safety and duplicate handling; consider adding verification for unmatched rewards.

The null safety check on line 1105 (!reward.item?.name) correctly addresses the past review concern. The usedDropIndices tracking provides a solid first-match strategy for handling duplicate item names across rewards.

However, rewards that don't match any drop silently fall back to their original data (line 1116). While preserving metadata is intentional, consider adding optional verification (e.g., logging or a warning) when rewards remain unmatched, especially during development, to detect potential data inconsistencies between the relics package and the drops API.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9aa5f8 and 26d58a4.

📒 Files selected for processing (2)
  • build/parser.mjs (3 hunks)
  • test/index.spec.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/index.spec.mjs
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: SlayerOrnstein
Repo: WFCD/warframe-items PR: 663
File: config/masterableCategories.json:1-2
Timestamp: 2024-12-03T23:47:24.677Z
Learning: In the 'warframe-items' repository, when suggesting changes to regex patterns in 'config/masterableCategories.json', ensure that added patterns only include items relevant to the current PR context, and avoid adding items not present in the context.
🔇 Additional comments (2)
build/parser.mjs (2)

202-202: LGTM!

The call site correctly passes the drops data to support refinement-specific drop rates.


1072-1074: LGTM!

The function signature and JSDoc are correctly updated to accept drops data.

@BUSTheid
Copy link
Contributor Author

Force-pushed without the data rebuilt commit and rebased on the latest master

@TobiTenno TobiTenno merged commit 28aae84 into WFCD:master Nov 12, 2025
7 of 8 checks passed
@BUSTheid BUSTheid deleted the fix/relic-refinement-drop-rates branch November 12, 2025 16:12
@wfcd-bot-boi
Copy link
Collaborator

🎉 This PR is included in version 1.1270.887 🎉

The release is available on:

Your semantic-release bot 📦🚀

@TobiTenno
Copy link
Member

@BUSTheid there we go, out it went

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released Scope: Data How data is represented or cleaned up Severity3: Minor The defect affects minor functionality or non-critical data. It has an easy workaround. Type: Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Relic reward chances

3 participants