Skip to content

Add PD2 damage calculator#26

Merged
coleestrin merged 1 commit into
coleestrin:mainfrom
ChaseBianchi:feature/damage-calculator
Jun 19, 2026
Merged

Add PD2 damage calculator#26
coleestrin merged 1 commit into
coleestrin:mainfrom
ChaseBianchi:feature/damage-calculator

Conversation

@ChaseBianchi

@ChaseBianchi ChaseBianchi commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds the Project Diablo 2 damage calculator feature with full-page and condensed character-page calculator experiences.
  • Sources damage mechanics from explicit PD2 extracted game tables instead of hidden local/generated comparison data.
  • Adds selectable weapons, skills, transformations, multiple auras with self/party handling, and calculator cache/type support.
  • Adds feature-focused tests and documentation for the PD2 game-file source-of-truth workflow.
  • Adds docs/runbooks/ with runbooks for all source scripts, including repeatable commands for api/src/scripts/damage-stress-test.ts.
  • Add AGENTS.md, with a pointer to relevant docs.

Verification

  • npm run lint (api)
  • npm run build (api)
  • npm test -- damage-calculator.test.ts --runInBand (api)
  • npm test -- routes.test.ts --runInBand (api)
  • npm run lint (web)
  • npm run build (web)
  • docker compose up -d --build
  • Local smoke checks for ChaseWoof and Sinfection calculator data

Notes

  • Full host-side API test suite still requires a reachable local PostgreSQL instance on localhost:5432 for existing DB-backed tests.
  • Local Docker use requires current-season PD2 text tables via PD2_EXTRACT_HOST_DIR or api/.pd2-live-extract.

Testing

  • in addition to the test files, I ran several stress tests by manually running src/scripts/damage-stress-test.ts
Metric Value
Live characters requested/fetched/processed 600 / 600 / 600
Failed 0
Unsupported 0
Profiles generated 644,003
Damage components generated 2,510,139
Profiles with no components 0
Components missing source refs 0
Avg / p95 / p99 per character 346.94ms / 766ms / 1,210ms
Max per character 4,011ms

Screenshots

Desktop
image

Mobile
image

Mini-calc on character page
image

Risks

In my local environment the auto-generated ads were pretty experience breaking. It would often run a full page video ad below the character selection of the damage-calculator page. It will also sometimes put an add in the middle of the Damage Calculator section beneath the skills/aura selection. Not sure how ads are being handled though, so I didn't address it.

@ChaseBianchi ChaseBianchi marked this pull request as ready for review May 26, 2026 19:22
Comment thread api/src/config/index.ts

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

is there a reason for these changes? this and to adding the multiple cors origins to the env? did you run into issues?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was added to make local dev across Vite/preview ports easier, not important so ill remove it.

Comment thread .env.example

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

id rather just have the .txt files committed rather than doing all this with the script to extract them, they can just be manually extracted w/ the mpq extractor that comes with pd2 and then just changed once per season

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

as it assumes wherever its run has pd2 installed which is not the case in production

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed to having the game files in the repo and a brief doc on how to update those files

Comment thread .gitignore

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

don't believe this is needed given my other requested changes

Comment thread AGENTS.md Outdated

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

this can be removed from the pr

Comment thread docker-compose.yml

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

see my comment about cors and the other comment about txt files

Comment thread api/package.json

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

not needed in pr

Comment thread api/eslint.config.js

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

not needed in pr as per my requeseted changes

Comment thread api/.dockerignore

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

not needed in pr

Comment thread api/src/utils/skill-calculator.test.ts Outdated
});

describe("Complex Scenarios", () => {
it("should apply ChaseWoof-style Druid skill bonuses from equipped items and inventory charms", () => {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

remove "chasewoof-style"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

is this and the other scripts in this folder still meaningful or were they just for your initial testing and research?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It can live locally

@ChaseBianchi ChaseBianchi requested a review from coleestrin June 2, 2026 03:26
@ChaseBianchi ChaseBianchi force-pushed the feature/damage-calculator branch from 76eaf23 to 6a0c69e Compare June 2, 2026 12:47

@coleestrin coleestrin left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

re: discord comments, I think i'd prefer to have the stress test script and docs/runbooks folder kept locally on your end, you can just remove them the pr and keep them locally for your future development

Comment thread web/src/theme.ts Outdated
violet: "var(--mantine-color-violet-5)",
gray: "var(--mantine-color-gray-5)",
white: "var(--mantine-color-white)",
physical: "var(--mantine-color-pd2Physical-5)",

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

physical, combinedDamage, and bugReport shouldn't have their own theme colors here, it should be just the core theme colors e.g. red, why do those 3 specific attributes need their own tuple of colors?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Just to distinguish damage types on the calculator with their own color.

The bug report button was a design choice to have a secondary button color.

@coleestrin coleestrin Jun 6, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

id rather place the physical and combineddamage in stat-colors.ts just with the hex there and i think the bug button color if you're not using red or a different standard color i think it'd be better to just put the color inline in the button styles rather than having it here.

Comment thread web/src/types/constants.ts Outdated
}));
export const SEASON_STORAGE_KEY_SUFFIX = `s${CURRENT_SEASON}`;
export const LEVEL_RANGE_COOKIE_KEY = `levelRange_${CURRENT_SEASON}`;
export const DAMAGE_CALCULATOR_PAYLOAD_VERSION = "damage-model-v10";

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

purpose of tracking this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Cache busting for updates

Comment thread api/src/types/index.ts Outdated
export * from "./damage";

// Extended character types
export * from "./extended-character";

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

why do we need this? if we are adding the damage prop to every character response i don't think we'd need this special type since every character would have this so we can just add the damage prop to whatever the current character type is.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think the original idea was separation of concerns, but yeah agree it's simplified by integrating into existing response.

Comment thread api/src/jobs/character-scraper.ts Outdated
@ChaseBianchi ChaseBianchi requested a review from coleestrin June 5, 2026 14:07
Comment thread api/src/jobs/character-scraper.ts Outdated
Comment thread api/src/utils/pd2-game-data.ts Outdated
@@ -0,0 +1,40 @@
import fs from "fs";

@coleestrin coleestrin Jun 6, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

is this file not needed anymore since we aren't doing the extraction in the repo anymore?

Comment thread web/src/components/character/StatsSection.tsx
@coleestrin

coleestrin commented Jun 6, 2026

Copy link
Copy Markdown
Owner

The damage model notes dropdown is not very readable to the average user, maybe handwrite some of those (at least the 2nd line to make it more clear?) to make it more readable or understandable to the average user who will be using it? Also we can include a disclaimer there stating it may not be 100% exact and that if you notice significant deviations from the damage you expect, to file a bug report (with a link to the discord)

@coleestrin

Copy link
Copy Markdown
Owner
  • On the character page the damage calculator button should open in new tab. Similarly on the damage calculator page, clicking to open the character should open in a new tab as well.

  • Season dropdown has "Latest" but also includes "season 13" in the list (duplicate)

@coleestrin

Copy link
Copy Markdown
Owner

Does it support bows? The "Weapon" dropdown shows as unarmed for characters with bows.

@coleestrin

Copy link
Copy Markdown
Owner

And thank you again for all your work, this is excellent.

@ChaseBianchi ChaseBianchi requested a review from coleestrin June 9, 2026 13:37
@ChaseBianchi ChaseBianchi force-pushed the feature/damage-calculator branch 2 times, most recently from ad11ec3 to e882b0b Compare June 18, 2026 00:47
@ChaseBianchi ChaseBianchi force-pushed the feature/damage-calculator branch from e882b0b to 6e45be6 Compare June 18, 2026 13:58
@coleestrin coleestrin merged commit 6a8a580 into coleestrin:main Jun 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants