Android build v1.1.35
This commit is contained in:
@@ -4,10 +4,30 @@ import { createServer } from 'vite'
|
||||
const DEFAULT_WORKERS = Math.max(1, Math.min(8, Number.parseInt(process.env.IWT2_SIM_WORKERS ?? '8', 10)))
|
||||
const DEFAULT_MAX_SECONDS = Math.max(30, Number.parseFloat(process.env.IWT2_SIM_SECONDS ?? '180'))
|
||||
const DEFAULT_DT = 1 / 30
|
||||
const DEFAULT_TICKS_PER_WORKER_SECOND = 45000
|
||||
const ESTIMATE_STARTUP_SECONDS = 0.8
|
||||
const PVP_BOSS_HEALTH_MULTIPLIER = 0.7
|
||||
const BOSS_HEALTH_PER_STAGE = 0.1
|
||||
const ARENA_BOUNDS = { width: 960, height: 540 }
|
||||
const HEALER_STYLES = ['dawnweaver', 'lifebinder', 'runesage']
|
||||
const BOSS_IDS = [
|
||||
'bulldrome',
|
||||
'yian-kut-ku',
|
||||
'great-jaggi',
|
||||
'khezu',
|
||||
'rathian',
|
||||
'barroth',
|
||||
'tobi-kadachi',
|
||||
'rimebastion',
|
||||
'ember-mantis-duelist',
|
||||
'cinderback-ricochet',
|
||||
'obsidian-ram-golem',
|
||||
'stormcoil-wyrm',
|
||||
'venom-orchid-hydra',
|
||||
'sandglass-scorpion',
|
||||
'crystal-bat-matriarch',
|
||||
'hollowcrown-revenant',
|
||||
]
|
||||
const activeChildren = new Set()
|
||||
|
||||
for (const signal of ['SIGINT', 'SIGTERM']) {
|
||||
@@ -32,6 +52,7 @@ const config = {
|
||||
bossFilter: parseList(args.get('--bosses') ?? 'all'),
|
||||
bossHpPercent: parsePositiveNumber(args.get('--boss-hp-percent') ?? '100', 100),
|
||||
classes: parseList(args.get('--classes') ?? args.get('--class') ?? 'all'),
|
||||
estimateOnly: args.has('--estimate-only'),
|
||||
gearLevel: parseNonNegativeInt(args.get('--gear-level') ?? args.get('--gear') ?? '5', 5),
|
||||
maxSeconds: Number.parseFloat(args.get('--seconds') ?? String(DEFAULT_MAX_SECONDS)),
|
||||
repeats: parsePositiveInt(args.get('--repeats') ?? '1', 1),
|
||||
@@ -66,6 +87,7 @@ async function runMain({
|
||||
bossFilter,
|
||||
bossHpPercent,
|
||||
classes,
|
||||
estimateOnly,
|
||||
gearLevel,
|
||||
maxSeconds,
|
||||
repeats,
|
||||
@@ -75,6 +97,33 @@ async function runMain({
|
||||
workers,
|
||||
}) {
|
||||
const safeWorkers = Math.max(1, Math.floor(workers))
|
||||
const estimate = estimateRun({
|
||||
bossCount,
|
||||
bossFilter,
|
||||
classes,
|
||||
maxSeconds,
|
||||
repeats,
|
||||
requiredBosses,
|
||||
stages,
|
||||
workers: safeWorkers,
|
||||
})
|
||||
if (estimateOnly) {
|
||||
console.log(JSON.stringify({
|
||||
config: {
|
||||
bossCount,
|
||||
bosses: bossFilter,
|
||||
classes,
|
||||
repeats,
|
||||
requiredBosses,
|
||||
seconds: maxSeconds,
|
||||
stages,
|
||||
workers: safeWorkers,
|
||||
},
|
||||
estimate,
|
||||
}, null, 2))
|
||||
return
|
||||
}
|
||||
const startedAt = Date.now()
|
||||
const childResults = await Promise.all(Array.from({ length: safeWorkers }, (_, shardIndex) => (
|
||||
runChild({
|
||||
bossCount,
|
||||
@@ -92,6 +141,7 @@ async function runMain({
|
||||
})
|
||||
)))
|
||||
const results = childResults.flat()
|
||||
const elapsedSeconds = round((Date.now() - startedAt) / 1000)
|
||||
const summary = summarizeResults(results)
|
||||
console.log(JSON.stringify({
|
||||
config: {
|
||||
@@ -101,6 +151,8 @@ async function runMain({
|
||||
bosses: bossFilter,
|
||||
classes,
|
||||
gearLevel,
|
||||
elapsedSeconds,
|
||||
estimate,
|
||||
orderedTrials: results.length,
|
||||
repeats,
|
||||
requiredBosses,
|
||||
@@ -549,6 +601,7 @@ Options:
|
||||
--bosses all|bulldrome,yian-kut-ku,...
|
||||
--required-bosses none|yian-kut-ku,...
|
||||
--repeats 1
|
||||
--estimate-only
|
||||
--boss-hp-percent 100
|
||||
--boss-damage-percent 100
|
||||
--stages 1,2
|
||||
@@ -562,9 +615,43 @@ Examples:
|
||||
node scripts/iwt2-pvp-roguelike-boss-sim.mjs --boss-hp-percent 125 --boss-damage-percent 110
|
||||
node scripts/iwt2-pvp-roguelike-boss-sim.mjs --bosses yian-kut-ku,rathian,rimebastion --boss-count 2
|
||||
node scripts/iwt2-pvp-roguelike-boss-sim.mjs --required-bosses yian-kut-ku --repeats 10
|
||||
node scripts/iwt2-pvp-roguelike-boss-sim.mjs --required-bosses yian-kut-ku --estimate-only
|
||||
`)
|
||||
}
|
||||
|
||||
function estimateRun({
|
||||
bossCount,
|
||||
bossFilter,
|
||||
classes,
|
||||
maxSeconds,
|
||||
repeats,
|
||||
requiredBosses,
|
||||
stages,
|
||||
workers,
|
||||
}) {
|
||||
const bossIds = filteredBossIds(BOSS_IDS, bossFilter)
|
||||
const requiredBossIds = filteredRequiredBossIds(bossIds, requiredBosses)
|
||||
const healerStyles = filteredClasses(classes)
|
||||
const orderedBossGroups = permutations(bossIds, bossCount)
|
||||
.filter((group) => requiredBossIds.every((bossId) => group.includes(bossId)))
|
||||
const trials = orderedBossGroups.length * healerStyles.length * stages.length * repeats
|
||||
const maxTicks = trials * maxSeconds * (1 / DEFAULT_DT)
|
||||
const estimatedWallSeconds = ESTIMATE_STARTUP_SECONDS + (maxTicks / (Math.max(1, workers) * DEFAULT_TICKS_PER_WORKER_SECOND))
|
||||
return {
|
||||
bossPoolSize: bossIds.length,
|
||||
classCount: healerStyles.length,
|
||||
orderedBossGroupCount: orderedBossGroups.length,
|
||||
requiredBosses: requiredBossIds,
|
||||
stageCount: stages.length,
|
||||
repeats,
|
||||
trials,
|
||||
maxSimulatedSeconds: round(trials * maxSeconds),
|
||||
maxTicks: Math.round(maxTicks),
|
||||
estimatedWallSeconds: round(estimatedWallSeconds),
|
||||
note: 'Rough wall-time estimate; victories or defeats can end trials early.',
|
||||
}
|
||||
}
|
||||
|
||||
function filteredBossIds(allBossIds, filter) {
|
||||
if (filter.length === 0 || filter.includes('all')) return allBossIds
|
||||
const known = new Set(allBossIds)
|
||||
|
||||
Reference in New Issue
Block a user