Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ Data is fetched from [tarkov.dev](https://tarkov.dev/) GraphQL API in a single c

API responses are cached in localStorage for 30 minutes.

## Build Modes

`build:dev` intentionally runs `vite build --mode preview`, and `deploy:dev`
uses that script. `src/instrument.ts` reads the Vite mode for Sentry environment
and trace sampling (`development=1.0`, `preview=0.2`, default `0.1`), so the
preview mode name is not a typo.

## Data Overlay System

The tracker uses a community-maintained data overlay to correct and extend tarkov.dev API data. This handles cases where game updates outpace API updates.
Expand Down
76 changes: 76 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

111 changes: 111 additions & 0 deletions docs/PVP_PVE_TASK_OBJECTIVE_API_CHECK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# PvP/PvE Task Objective API Check

Checked against `https://api.tarkov.dev/graphql` on 2026-04-23.

Freshness note: this was a one-off live snapshot against the same endpoint used
by `src/services/tarkovApi.ts` and the service tests. Recheck this document
after Tarkov wipes, major API/schema changes, or mode-specific objective
regressions. The LanguageTool "loose punctuation" hint on the Markdown lists is
a false positive.

Query shape:

```graphql
query CheckTaskObjectives {
regular: tasks(lang: en, gameMode: regular) {
id
name
objectives {
description
maps { name }
... on TaskObjectiveItem {
items { id name }
count
foundInRaid
}
... on TaskObjectiveShoot {
count
}
... on TaskObjectivePlayerLevel {
playerLevel
}
}
}
pve: tasks(lang: en, gameMode: pve) {
id
name
objectives {
description
maps { name }
... on TaskObjectiveItem {
items { id name }
count
foundInRaid
}
... on TaskObjectiveShoot {
count
}
... on TaskObjectivePlayerLevel {
playerLevel
}
}
}
}
```

Compared objective fields used by the app:

- `description`
- `maps { name }`
- `TaskObjectiveItem`: `items`, `count`, `foundInRaid`
- `TaskObjectiveShoot`: `count`
- `TaskObjectivePlayerLevel`: `playerLevel`

Implementation references:

- `src/services/tarkovApi.ts` owns the API query and cache normalization.
- `src/utils/taskProgressView.ts` maps equivalent task/objective progress across
mode variants.

Summary:

- `regular` returned 494 tasks.
- `pve` returned 490 tasks.
- 22 task IDs were regular-only.
- 18 task IDs were PvE-only.
- For tasks with the same task ID in both modes, there were 0 objective differences in the app-consumed objective fields.

Most visible PvP/PvE differences are separate PvP/PvE zone task variants with different IDs, not same-ID objective changes.

Examples:

- `Easy Money - Part 1 [PVP ZONE]`
- PvP ID: `66058cb22cee99303f1ba067`
- PvE equivalent: `Easy Money - Part 1 [PVE ZONE]`
- PvE ID: `6834145ebc1f443d7603c8a7`
- Objective is effectively the same: plant the Arena advertisement poster in the living quarters at the Scav base on Customs.

- `Balancing - Part 2 [PVP ZONE]`
- PvP ID: `66058cb9e8e4f17985230805`
- PvE equivalent: `Balancing - Part 2 [PVE ZONE]`
- PvE ID: `68341a0b2f0e2a7eb90b62d4`
- Same objective: eliminate 2 PMC operatives while wearing PACA Soft Armor.

- `To Great Heights! - Part 4 [PVP ZONE]`
- PvP ID: `66058cc72cee99303f1ba069`
- PvE equivalent: `To Great Heights! - Part 4 [PVE ZONE]`
- PvE ID: `683421515619c8e2a9031511`
- Same objectives: hand over 1,000,000 roubles, win three out of six Arena matches, and fail if losing 4 matches.

- `New Beginning`
- Regular mode returned multiple regular-only `New Beginning` task IDs.
- No matching PvE-only `New Beginning` variants were returned in this check.
- Regular-only objective sets differed materially, including variants with:
- `Eliminate Scavs` x50
- `Eliminate PMC operatives` x15
- `Eliminate Raiders` x50
- `Eliminate Rogues` x100

Conclusion:

If the app needs to distinguish PvP/PvE task objective behavior, compare by mode-aware task set first. Do not assume same-name tasks share IDs, and do not expect many same-ID objective payload differences based on this API check.
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
"scripts": {
"dev": "vite",
"build": "vite build",
"build:prod": "vite build --mode production",
"build:dev": "vite build --mode preview",
"lint": "eslint .",
"preview": "vite preview",
"test": "vitest",
"test:run": "vitest run",
"test:coverage": "vitest run --coverage",
"deploy:prod": "bun run build && wrangler pages deploy dist --project-name=kappas --branch=master --commit-dirty=true",
"deploy:dev": "bun run build && wrangler pages deploy dist --project-name=kappas --branch=dev --commit-dirty=true",
"deploy:prod": "bun run build:prod && wrangler pages deploy dist --project-name=kappas --branch=master --commit-dirty=true",
"deploy:dev": "bun run build:dev && wrangler pages deploy dist --project-name=kappas --branch=dev --commit-dirty=true",
"task": "npx tsx scripts/task-cli.ts"
},
"dependencies": {
Expand Down Expand Up @@ -44,6 +46,8 @@
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"@react-spring/web": "^10.0.3",
"@sentry/react": "^10.50.0",
"@sentry/vite-plugin": "^5.2.0",
"@xyflow/react": "^12.10.0",
"baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001769",
Expand Down
Loading