Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Genshin Impact DPS simulator: a generic engine where every character is a JSON file
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗A Genshin Impact damage simulator built on a generic engine. Every character is data: one JSON file that describes the kit (talents, passives, constellations, weapon, artifact set, rotation). The engine knows nothing about any particular character; it only runs blocks. Shared game mechanics such as Energy, Bond of Life or Nightsoul are pluggable system modules that a character turns on in its JSON.
Frames, hitmarks and kit rules are taken from gcsim, so results can be checked against a known reference.
The site is the simulator: / opens a team combat timeline with an editable rotation (the old /genshin-dps-simulator redirects there). The team or character picked is kept in the URL (/?team=solo:mavuika).
Current roster: Arlecchino, Mualani, Varesa, Iansan, Chevreuse, Nicole, Escoffier, Mavuika, Citlali, Bennett, Xilonen, Sucrose.
Preset teams: Varesa with Iansan, Chevreuse and Nicole; Mavuika's Melt teams (with Citlali, Escoffier and Bennett; Citlali, Xilonen and Bennett; Citlali, Xilonen and Iansan, after KQM's guide). The Team button picks any party of up to four.
swap_delay), team buffs (stats and infusions), shared particles, elemental resonance, and Pyro/Electro/Cryo auras with Overloaded and Melt.NaN damage._data/characters/<name>.json
│ registered in CHARACTER_FILES (_lib/characterData.ts)
▼
zod schemas ──────────── characterSchema.ts, actionSchema.ts, engine/schema.ts
│
▼
reference check ──────── engine/validateReferences.ts
│
▼
systems expansion ────── engine/modules/* (energy, bondOfLife, nightsoul → plain blocks)
│
▼
runtime + kit adapter ── engine/runtime.ts state, bonuses, triggers, hits
│ engine/kitAdapter.ts when each action starts, which form it takes
│ engine/queue.ts frame-based event queue
▼
simulateKit.ts (solo) / simulateTeam.ts (team) → results → UI (_components/)
Path (under src/app/genshin-dps-simulator/) | Role |
|---|---|
_data/characters/*.json | One file per character |
_data/weapons/*.json, _data/sets/*.json | The weapon and artifact set catalog (_lib/catalog.ts) |
_data/reactions.json | Reaction formulas (Vaporize, Melt, Overloaded) |
_lib/characterData.ts | CHARACTER_FILES registry, loadCharacterFile() |
_lib/characterSchema.ts, _lib/actionSchema.ts | Character and talent schemas; getCharacterActions() compiles actions |
_lib/engine/schema.ts | Block, condition, trigger and operation schemas |
_lib/engine/runtime.ts | Simulation state, bonuses, triggers and hits |
_lib/engine/kitAdapter.ts | Action timing, cancels, forms |
_lib/engine/modules/ | Shared system modules (MODULES in index.ts) |
_lib/engine/simulateKit.ts | Solo runs, simulateLoadedCharacter() |
_lib/engine/simulateTeam.ts | Team runs, simulateTeam() |
_lib/team.ts | Team presets and screen state |
_components/timeline/ | The timeline UI (CombatTimelinePage.tsx is the entry point) |
__tests__/ | Vitest suite (engine features, invariants, golden cases, teams) |
CLAUDE.md | Full engine and JSON reference |
A character file is mostly talents plus a list of blocks. There are four block types:
| Block | What it is |
|---|---|
bonus | A conditional stat, infusion, reaction or multiplier change |
resource | A number with min and max (Energy, Bond of Life, Nightsoul points, stacks) |
status | A temporary state or mode, with duration, ticks, stacks or drain |
trigger | when something happens (hit, use, resource change, status end…), do operations |
rows with gcsim timing (hitmarks, end, cancels), extra actions (hold E, plunges), and forms: alternate versions of an action that apply while a status holds (for example, Varesa's Fiery Passion attacks).resource, status, flag, field, ready, previous, all / any / not) gate bonuses, triggers, operations and rotation entries.addResource, applyStatus, addStack, reduceCooldown, hit, reactionHit, particles, heal and count.Real examples from the character files. Arlecchino's Blood-Debt Directive is a status with ticks, and her Normal Attack infusion is a bonus gated on a resource:
{
"id": "directive",
"type": "status",
"source": "talent",
"label": "Blood-Debt Directive",
"target": "enemy",
"durationFrames": 1800,
"ticks": {
"everyFrames": 300,
"count": 2,
"row": "elementalSkill/blood-debt-directive",
"element": "Pyro",
"category": "Directive"
}
}
{
"id": "masque-infusion",
"type": "bonus",
"source": "talent",
"label": "Masque of the Red Death",
"infuse": "Pyro",
"match": { "actions": ["normal", "charged"] },
"while": { "bondOfLife": { "gte": 30 } }
}
Mualani turns on the Energy and Nightsoul systems. Her surfing state is Nightsoul's Blessing:
"systems": {
"energy": { "initialField": "startingEnergy" },
"nightsoul": {
"maxPoints": 60,
"blessing": { "drain": { "everyFrames": 6, "firstAfterFrames": 8 } },
"nightsoulBurst": {
"do": [{ "addStack": "wavechaserStacks", "ifFlag": "wavechaserPassive" }]
}
}
}
The full field reference (every key, trigger, operation, details template and gotcha) is in src/app/genshin-dps-simulator/CLAUDE.md.
| Module | Creates |
|---|---|
energy | Resource energy (max = Q cost), particles × ER, flat Energy on Normal/Charged hits by weapon type |
bondOfLife | Resource bondOfLife (%); the kit decides how it is gained and consumed |
nightsoul | Resource nightsoul, status nightsoulBlessing (drain or fixed duration), optional Nightsoul Burst |
These keep the engine generic. Read them before proposing a change.
status block. There is no separate "state" type. Natlan modes use Nightsoul's Blessing.form with "while": { "status": "<id>" }.bonus or trigger blocks, never states.systems module. One that belongs to a single character stays in its JSON.hook is the last resort, for rules no block can express.__tests__/engineFeatures.test.ts, and the golden results must stay the same unless the change is meant to move them.partial or not-simulated instead of guessing.scripts/scaffolds/, not loaded by the app):
npx tsx scripts/scaffold/character.ts <gcsim key> --weapon "<name>" --set "<name>": stats, ascension stat, every talent table, icons, official texts, and gcsim's frames.npx tsx scripts/scaffold/weapon.ts "<name>" and scripts/scaffold/set.ts "<name>" for catalog entries it needs.automatic, defaults) and save it as _data/characters/<name>.json. Check it unregistered with npx tsx scripts/scaffold/check.ts <file> [--team id,id]; scripts/scaffold/build.ts gives a standard build's screen totals.CHARACTER_FILES in _lib/characterData.ts. The invariants in __tests__/invariants.test.ts then cover it automatically.__tests__/goldenCases.ts, then regenerate the golden file with npx tsx scripts/sim-golden.ts.CLAUDE.md.If the kit needs something no block can express, that is an engine feature (see below), not a reason for character-specific code.
For mechanics like Bond of Life or Nightsoul that several characters share:
_lib/engine/modules/<name>.ts. It validates its own params and returns plain Block[].MODULES in _lib/engine/modules/index.ts.__tests__/engineFeatures.test.ts using the helpers in __tests__/fixtures.ts.CLAUDE.md.npx tsx scripts/sim-golden.ts --compare must pass (0.1% tolerance) unless the change is meant to move results. In that case, regenerate the golden file and explain why in the PR.pnpm test
pnpm typecheck
pnpm lint
npx tsx scripts/sim-golden.ts --compare
Commits follow Conventional Commits, and commitlint enforces it.
src/app/genshin-dps-simulator/CLAUDE.md before touching the simulator. It is the authoritative reference.if (character === …) logic to the engine.Gaps in the engine, roughly in order of impact. The details are in CLAUDE.md.
Planned characters include Flins, Navia and Zhongli.
Use pnpm so the Husky hooks work.
git clone [email protected]:Quienx/genshin-dps-simulator.git
cd genshin-dps-simulator
pnpm install
pnpm dev
Then open http://localhost:3000.
Import the GitHub repository in Vercel; it detects Next.js and pnpm. Set the environment variable ENABLE_EXPERIMENTAL_COREPACK=1 (so it uses the packageManager pnpm version) and Node.js 20 or later. Every push to main deploys. The site URL (metadata, sitemap) comes from the production domain; elsewhere, set SITE_URL (for example https://example.com, no trailing /).
| Command | What it does |
|---|---|
pnpm dev | Start the dev server |
pnpm build | Production build (also generates sitemap) |
pnpm test | Run the Vitest suite once |
pnpm test:watch | Run Vitest in watch mode |
pnpm typecheck | Type-check with tsc |
pnpm lint | Lint with ESLint |
pnpm format | Format with Prettier |
Stack: Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS 4, shadcn/ui on Radix, zod, @dnd-kit, Vitest.