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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ Known limits: boss mechanics, movement, deaths and crowd control are not simulat

Protection Warrior, Protection Paladin, Blood Death Knight, Guardian Druid, Brewmaster Monk and Vengeance Demon Hunter are detected on import. Every mode (Quick Sim, Enchant Lab, Gear Compare, Upgrade Finder, Crest Planner, Great Vault and Talent Search) then ranks results on DPS and survival.

**Tank Sim** has its own place in the menu: the imported tank against a boss and its adds, one simulation per fight you tick (the boss alone, the boss with 2 adds, the boss with 4 adds), with the numbers a tank cares about: damage taken per second and as a share of your health, healing and absorbs, how much of the fight you survive, how often you die, and your DPS. It needs a tank specialization.

SimC's built-in tank dummy uses level-70 damage values and never threatens a Midnight tank, and SimC gives players infinite health by default. SimC Lab replaces it with a calibrated boss, tuned once per job against the imported gear and then shared by every variant and scenario:

- Sustained damage: melee swings plus a magic damage-over-time effect, scaled until the imported gear takes the chosen share of its maximum health per second after its own mitigation.
Expand Down
4 changes: 2 additions & 2 deletions desktop/package-lock.json

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

2 changes: 1 addition & 1 deletion desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "simc-lab",
"productName": "SimC Lab",
"desktopName": "simc-lab.desktop",
"version": "1.41.0",
"version": "1.42.0",
"description": "Local SimulationCraft workbench with upgrade finder and tank simulation.",
"author": "Roburmaster",
"private": true,
Expand Down
5 changes: 5 additions & 0 deletions lib/engine.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ export async function prepare(request,catalog,talentData,season) {
if(!Number.isFinite(settings.targetError)||settings.targetError<0||settings.targetError>5) throw new Error('Target error must be between 0 and 5%.');
settings.environment=normalizeEnvironment(request.environment,catalog);
settings.tank=weapons?null:normalizeTank(request.tank,profile.info);
// Tank Sim runs one imported tank against a boss and adds that all hit it.
if(request.mode==='tank'){
if(!settings.tank)throw new Error('Tank Sim needs a tank specialization: Protection Warrior or Paladin, Blood Death Knight, Guardian Druid, Brewmaster Monk or Vengeance Demon Hunter.');
settings.tank.adds=true;
}
// Trinket Lab can name its scenarios instead: raid and Mythic+ fights of their own length (see scenarioPresets).
const presets=request.mode==='trinkets'&&request.trinkets?.scenarioSet?.length;
// Bloodmallet parity fixes the fight and the precision to Bloodmallet's own (see parity in trinkets.mjs).
Expand Down
2 changes: 1 addition & 1 deletion lib/profile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export function createVariants(profile, request, catalog) {
if (!patch.text) throw new Error(`Variant «${v.name}» is empty.`);
variants.push({name:v.name,text:applyOverrides(profile.text,patch.text)});
}
} else if (mode !== 'quick') throw new Error('Unknown simulation mode.');
} else if (mode !== 'quick' && mode !== 'tank') throw new Error('Unknown simulation mode.');
if (variants.length > 129) throw new Error('Too many variants.');
return variants;
}
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "simc-lab",
"version": "1.41.0",
"version": "1.42.0",
"private": true,
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion public/activity.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// What the engine is doing right now: a bar in the header on every page, and the shared wording for a job's
// progress. Jobs run one at a time; everything else waits in the queue.
const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
const names={quick:'Quick Sim',enchants:'Enchant Lab',compare:'Gear Compare',upgrades:'Upgrade Finder',weapons:'Weapon Lab',trinkets:'Trinket Lab',talents:'Talent Search'};
const names={quick:'Quick Sim',enchants:'Enchant Lab',compare:'Gear Compare',upgrades:'Upgrade Finder',tank:'Tank Sim',weapons:'Weapon Lab',trinkets:'Trinket Lab',talents:'Talent Search'};

export function duration(seconds){
if(!Number.isFinite(seconds)||seconds<0)return '';
Expand Down
17 changes: 10 additions & 7 deletions public/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="color-scheme" content="dark"><title>SimC Lab · mpcombat</title><link rel="stylesheet" href="/style.css"><script src="/wowhead.js"></script><script async src="https://wow.zamimg.com/js/tooltips.js"></script></head>
<body>
<aside class="sidebar"><a class="brand" href="/"><span class="brand-mark">S<span>≋</span></span><span>SIMC <b>LAB</b><small>by mpcombat</small></span></a><div class="nav-label">SIMULATION</div><nav aria-label="Simulation mode"><button class="nav active" data-mode="quick"><span>◈</span> Quick Sim</button><button class="nav" data-mode="enchants"><span>✧</span> Enchant Lab</button><button class="nav" data-mode="compare"><span>⇄</span> Gear Compare</button><button class="nav" data-mode="upgrades"><span>⇪</span> Upgrade Finder</button><button class="nav" data-mode="crests"><span>⬆</span> Crest Planner</button><button class="nav" data-mode="vault"><span>▣</span> Great Vault</button><button class="nav" data-mode="weapons"><span>⚖</span> Weapon Lab</button><button class="nav" data-mode="trinkets"><span>◆</span> Trinket Lab</button><button class="nav" data-mode="talents"><span>⌘</span> Talent Search</button><button class="nav" data-mode="logs"><span>⌕</span> Log Analysis</button><button class="nav" data-mode="history"><span>◷</span> History</button><button class="nav" data-mode="wow"><span>⚔</span> WoW addon</button></nav><div class="sidebar-bottom"><div class="local-label">LOCAL ENGINE</div><strong id="side-version">Checking …</strong><p>SimulationCraft, official build or built from source.<br>Simulations run on your PC.</p><a href="https://github.com/simulationcraft/simc" target="_blank" rel="noreferrer">SimulationCraft on GitHub ↗</a></div></aside>
<aside class="sidebar"><a class="brand" href="/"><span class="brand-mark">S<span>≋</span></span><span>SIMC <b>LAB</b><small>by mpcombat</small></span></a><div class="nav-label">SIMULATION</div><nav aria-label="Simulation mode"><button class="nav active" data-mode="quick"><span>◈</span> Quick Sim</button><button class="nav" data-mode="enchants"><span>✧</span> Enchant Lab</button><button class="nav" data-mode="compare"><span>⇄</span> Gear Compare</button><button class="nav" data-mode="upgrades"><span>⇪</span> Upgrade Finder</button><button class="nav" data-mode="tank"><span>⛨</span> Tank Sim</button><button class="nav" data-mode="crests"><span>⬆</span> Crest Planner</button><button class="nav" data-mode="vault"><span>▣</span> Great Vault</button><button class="nav" data-mode="weapons"><span>⚖</span> Weapon Lab</button><button class="nav" data-mode="trinkets"><span>◆</span> Trinket Lab</button><button class="nav" data-mode="talents"><span>⌘</span> Talent Search</button><button class="nav" data-mode="logs"><span>⌕</span> Log Analysis</button><button class="nav" data-mode="history"><span>◷</span> History</button><button class="nav" data-mode="wow"><span>⚔</span> WoW addon</button></nav><div class="sidebar-bottom"><div class="local-label">LOCAL ENGINE</div><strong id="side-version">Checking …</strong><p>SimulationCraft, official build or built from source.<br>Simulations run on your PC.</p><a href="https://github.com/simulationcraft/simc" target="_blank" rel="noreferrer">SimulationCraft on GitHub ↗</a></div></aside>
<div class="shell"><header><div><span class="muted">Workspace</span><span class="slash">/</span><span id="breadcrumb">Quick Sim</span></div><span class="badge" id="engine-badge">Checking engine</span></header>
<main><div class="page-heading"><div><div class="eyebrow">SIMULATIONCRAFT WORKBENCH</div><h1 id="page-title">Quick Sim<span class="accent">.</span></h1><p id="page-description">Import your character. Find out what your gear can do.</p></div><div class="engine-mini"><span>WOW LIVE</span><strong id="wow-version">—</strong></div></div>
<div id="notice" class="notice" role="alert" hidden></div>
Expand Down
36 changes: 36 additions & 0 deletions public/tanksim.js

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

2 changes: 1 addition & 1 deletion server.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ const server=http.createServer(async(req,res)=>{
// Reports are generated by SimC. Serve downloads so their scripts never share this app's origin.
res.writeHead(200,{'Content-Type':ext==='.json'?'application/json':'application/octet-stream','Content-Disposition':`attachment; filename="${report[2]}"`});return res.end(data);
}
const assets={'/':'index.html','/app.js':'app.js','/mplus.js':'mplus.js','/items.js':'items.js','/wowhead.js':'wowhead.js','/features.js':'features.js','/upgrades.js':'upgrades.js','/crests.js':'crests.js','/crestplan.js':'crestplan.js','/vault.js':'vault.js','/weapons.js':'weapons.js','/trinkets.js':'trinkets.js','/tank.js':'tank.js','/engine.js':'engine.js','/activity.js':'activity.js','/environment.js':'environment.js','/wow.js':'wow.js','/logs.js':'logs.js','/armory.js':'armory.js','/style.css':'style.css'};
const assets={'/':'index.html','/app.js':'app.js','/mplus.js':'mplus.js','/items.js':'items.js','/wowhead.js':'wowhead.js','/features.js':'features.js','/upgrades.js':'upgrades.js','/tanksim.js':'tanksim.js','/crests.js':'crests.js','/crestplan.js':'crestplan.js','/vault.js':'vault.js','/weapons.js':'weapons.js','/trinkets.js':'trinkets.js','/tank.js':'tank.js','/engine.js':'engine.js','/activity.js':'activity.js','/environment.js':'environment.js','/wow.js':'wow.js','/logs.js':'logs.js','/armory.js':'armory.js','/style.css':'style.css'};
if(req.method==='GET'&&assets[route]){const file=assets[route];res.writeHead(200,{'Content-Type':file.endsWith('.js')?'text/javascript; charset=utf-8':file.endsWith('.css')?'text/css; charset=utf-8':'text/html; charset=utf-8'});return res.end(await fs.readFile(path.join(root,'public',file)));}
json(res,404,{error:'Not found.'});
}catch(e){json(res,e.code==='ENOENT'?404:400,{error:e.message});}
Expand Down
Loading