BeamNG.Earth
A 1:1 scale streamed Earth for BeamNG.drive: real elevation and satellite imagery, floating origin, LOD streaming from a companion server
A Genshin Impact team damage simulator with a combat timeline, built on a generic engine where every character is a JSON file.
GamesTypeScript · JavaScriptGitHub @QuienxOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Genshin Impact DPS simulator: a generic engine where every character is a JSON file
Translation pending
Taken from the repository README
Loading the full README.
Read the full 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.