@vibemancer/core 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-E7R4JFAN.js → chunk-US4MEDKT.js} +85 -20
- package/dist/chunk-US4MEDKT.js.map +1 -0
- package/dist/index-browser-CYoJrb2d.d.ts +3065 -0
- package/dist/index-browser.d.ts +1 -2878
- package/dist/index-browser.js +3 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +35 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/bots/index.ts +5 -0
- package/src/engine/bot-compute-budget.ts +173 -0
- package/src/engine/bundle-fight.ts +9 -3
- package/src/engine/sandbox-browser.ts +7 -1
- package/src/engine/sandbox-harness.ts +15 -4
- package/src/engine/sandbox.ts +11 -2
- package/src/engine/simulation.ts +113 -17
- package/src/engine-version.ts +1 -1
- package/src/index.ts +2 -0
- package/dist/chunk-E7R4JFAN.js.map +0 -1
|
@@ -208,7 +208,7 @@ function currentRuleset() {
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
// src/engine-version.ts
|
|
211
|
-
var ENGINE_VERSION =
|
|
211
|
+
var ENGINE_VERSION = 1709865010946010;
|
|
212
212
|
|
|
213
213
|
// src/engine/hooks-runtime.ts
|
|
214
214
|
var _g = globalThis;
|
|
@@ -659,6 +659,26 @@ function angleInRange(angle, target, range) {
|
|
|
659
659
|
return Math.abs(angleDiff(angle, target)) <= range;
|
|
660
660
|
}
|
|
661
661
|
|
|
662
|
+
// src/engine/bot-compute-budget.ts
|
|
663
|
+
var DEFAULT_BUDGET = {
|
|
664
|
+
totalMs: 45e3
|
|
665
|
+
};
|
|
666
|
+
var DEFAULT_FIGHT_BACKSTOP_MS = 11e4;
|
|
667
|
+
function createBudgetState() {
|
|
668
|
+
return { spentMs: 0, exhausted: false };
|
|
669
|
+
}
|
|
670
|
+
function createFightBudget(limits = DEFAULT_BUDGET) {
|
|
671
|
+
return { states: [createBudgetState(), createBudgetState()], limits };
|
|
672
|
+
}
|
|
673
|
+
function mayAct(state) {
|
|
674
|
+
return !state.exhausted;
|
|
675
|
+
}
|
|
676
|
+
function recordSpend(state, limits, elapsedMs) {
|
|
677
|
+
if (!Number.isFinite(elapsedMs) || elapsedMs <= 0) return state;
|
|
678
|
+
const spentMs = state.spentMs + elapsedMs;
|
|
679
|
+
return { spentMs, exhausted: state.exhausted || spentMs > limits.totalMs };
|
|
680
|
+
}
|
|
681
|
+
|
|
662
682
|
// src/utils/random.ts
|
|
663
683
|
var MAX_INT = 2147483647;
|
|
664
684
|
function hashCombine(a, b) {
|
|
@@ -769,28 +789,40 @@ function buildWizardContext(state, config, random) {
|
|
|
769
789
|
lastHitTick: state.lastHitTick
|
|
770
790
|
};
|
|
771
791
|
}
|
|
772
|
-
function tick(currentTick, wizard1AI, wizard2AI, config, wizards, projectiles, missileAIs, matchSeed) {
|
|
792
|
+
function tick(currentTick, wizard1AI, wizard2AI, config, wizards, projectiles, missileAIs, matchSeed, budgets) {
|
|
773
793
|
const nextTick = currentTick + 1;
|
|
774
794
|
const errors = [];
|
|
775
795
|
const events = [];
|
|
776
796
|
const random1 = createRandom(createEntitySeed(matchSeed, wizards[0].id, nextTick));
|
|
777
797
|
const random2 = createRandom(createEntitySeed(matchSeed, wizards[1].id, nextTick));
|
|
778
|
-
|
|
779
|
-
|
|
798
|
+
const IDLE_ACTION = () => ({ move: { x: 0, y: 0 } });
|
|
799
|
+
const nextBudgets = budgets ? [budgets.states[0], budgets.states[1]] : void 0;
|
|
800
|
+
const runBot = (index, entityId, invoke) => {
|
|
801
|
+
const state = nextBudgets?.[index];
|
|
802
|
+
if (state && !mayAct(state)) return IDLE_ACTION();
|
|
803
|
+
const startedAt = state ? Date.now() : 0;
|
|
804
|
+
let action;
|
|
805
|
+
try {
|
|
806
|
+
action = invoke();
|
|
807
|
+
} catch (e) {
|
|
808
|
+
errors.push({ tick: nextTick, entityId, message: e instanceof Error ? e.message : String(e) });
|
|
809
|
+
action = IDLE_ACTION();
|
|
810
|
+
}
|
|
811
|
+
if (state && budgets) {
|
|
812
|
+
nextBudgets[index] = recordSpend(state, budgets.limits, Date.now() - startedAt);
|
|
813
|
+
}
|
|
814
|
+
return action;
|
|
815
|
+
};
|
|
816
|
+
const actions1 = runBot(0, "wizard-1", () => {
|
|
780
817
|
const stateView1 = getPlayerStateView(0, wizards, projectiles, nextTick);
|
|
781
818
|
const ctx1 = buildWizardContext(stateView1, config, random1);
|
|
782
|
-
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
}
|
|
786
|
-
let actions2 = { move: { x: 0, y: 0 } };
|
|
787
|
-
try {
|
|
819
|
+
return runWithHooks(wizards[0].id, () => extractAction(withWizardContext(ctx1, wizard1AI))) ?? IDLE_ACTION();
|
|
820
|
+
});
|
|
821
|
+
const actions2 = runBot(1, "wizard-2", () => {
|
|
788
822
|
const stateView2 = getPlayerStateView(1, wizards, projectiles, nextTick);
|
|
789
823
|
const ctx2 = buildWizardContext(stateView2, config, random2);
|
|
790
|
-
|
|
791
|
-
}
|
|
792
|
-
errors.push({ tick: nextTick, entityId: "wizard-2", message: e instanceof Error ? e.message : String(e) });
|
|
793
|
-
}
|
|
824
|
+
return runWithHooks(wizards[1].id, () => extractAction(withWizardContext(ctx2, wizard2AI))) ?? IDLE_ACTION();
|
|
825
|
+
});
|
|
794
826
|
const actions = [actions1, actions2];
|
|
795
827
|
const guideOverrides = /* @__PURE__ */ new Map();
|
|
796
828
|
const guideInvincibleApplied = [];
|
|
@@ -1049,7 +1081,8 @@ function tick(currentTick, wizard1AI, wizard2AI, config, wizards, projectiles, m
|
|
|
1049
1081
|
wizards,
|
|
1050
1082
|
projectiles: remainingProjectiles,
|
|
1051
1083
|
events,
|
|
1052
|
-
errors
|
|
1084
|
+
errors,
|
|
1085
|
+
budgets: nextBudgets
|
|
1053
1086
|
};
|
|
1054
1087
|
}
|
|
1055
1088
|
function cloneWizard(wizard) {
|
|
@@ -1183,11 +1216,13 @@ function fight(wizard1AI, wizard2AI, options = {}) {
|
|
|
1183
1216
|
let wizard1Wins = 0;
|
|
1184
1217
|
let wizard2Wins = 0;
|
|
1185
1218
|
let draws = 0;
|
|
1219
|
+
const budget = options.budgetLimits ? createFightBudget(options.budgetLimits) : void 0;
|
|
1186
1220
|
for (const spawnDistance of FIGHT_SPAWN_DISTANCES) {
|
|
1187
1221
|
const result = simulate(wizard1AI, wizard2AI, {
|
|
1188
1222
|
seed: options.seed,
|
|
1189
1223
|
maxTicks: options.maxTicks,
|
|
1190
|
-
spawnDistance
|
|
1224
|
+
spawnDistance,
|
|
1225
|
+
budget
|
|
1191
1226
|
});
|
|
1192
1227
|
matches.push(result);
|
|
1193
1228
|
if (result.winner === "wizard-1") {
|
|
@@ -1197,12 +1232,17 @@ function fight(wizard1AI, wizard2AI, options = {}) {
|
|
|
1197
1232
|
} else {
|
|
1198
1233
|
draws++;
|
|
1199
1234
|
}
|
|
1235
|
+
const swappedBudget = budget ? { states: [budget.states[1], budget.states[0]], limits: budget.limits } : void 0;
|
|
1200
1236
|
const swapped = simulate(wizard2AI, wizard1AI, {
|
|
1201
1237
|
seed: options.seed,
|
|
1202
1238
|
maxTicks: options.maxTicks,
|
|
1203
1239
|
spawnDistance,
|
|
1204
|
-
skipHistory: true
|
|
1240
|
+
skipHistory: true,
|
|
1241
|
+
budget: swappedBudget
|
|
1205
1242
|
});
|
|
1243
|
+
if (budget && swappedBudget) {
|
|
1244
|
+
budget.states = [swappedBudget.states[1], swappedBudget.states[0]];
|
|
1245
|
+
}
|
|
1206
1246
|
if (swapped.winner === "wizard-1") {
|
|
1207
1247
|
wizard2Wins++;
|
|
1208
1248
|
} else if (swapped.winner === "wizard-2") {
|
|
@@ -1266,8 +1306,25 @@ function simulate(wizard1AI, wizard2AI, options = {}) {
|
|
|
1266
1306
|
const missileAIs = /* @__PURE__ */ new Map();
|
|
1267
1307
|
const allErrors = [];
|
|
1268
1308
|
let deathTick = null;
|
|
1309
|
+
const sharedBudget = options.budget;
|
|
1310
|
+
const budgetLimits = sharedBudget?.limits ?? options.budgetLimits;
|
|
1311
|
+
let budgets = sharedBudget ? sharedBudget.states : budgetLimits ? [createBudgetState(), createBudgetState()] : void 0;
|
|
1269
1312
|
while (currentTick < maxTicks) {
|
|
1270
|
-
const result = tick(
|
|
1313
|
+
const result = tick(
|
|
1314
|
+
currentTick,
|
|
1315
|
+
wizard1AI,
|
|
1316
|
+
wizard2AI,
|
|
1317
|
+
config,
|
|
1318
|
+
wizards,
|
|
1319
|
+
projectiles,
|
|
1320
|
+
missileAIs,
|
|
1321
|
+
seed,
|
|
1322
|
+
budgetLimits && budgets ? { states: budgets, limits: budgetLimits } : void 0
|
|
1323
|
+
);
|
|
1324
|
+
if (result.budgets) {
|
|
1325
|
+
budgets = result.budgets;
|
|
1326
|
+
if (sharedBudget) sharedBudget.states = result.budgets;
|
|
1327
|
+
}
|
|
1271
1328
|
currentTick = result.nextTick;
|
|
1272
1329
|
wizards = result.wizards;
|
|
1273
1330
|
projectiles = result.projectiles;
|
|
@@ -9420,6 +9477,7 @@ __export(bots_exports, {
|
|
|
9420
9477
|
Doombringer: () => Doombringer,
|
|
9421
9478
|
Flamecaller: () => Flamecaller,
|
|
9422
9479
|
Golem: () => Golem,
|
|
9480
|
+
Hero: () => Hero,
|
|
9423
9481
|
Hogger: () => Hogger,
|
|
9424
9482
|
Infernalist: () => Infernalist,
|
|
9425
9483
|
Lich: () => Lich,
|
|
@@ -9610,7 +9668,7 @@ var BrowserMatchSandbox = class _BrowserMatchSandbox {
|
|
|
9610
9668
|
* that sets globalThis.__fight and globalThis.__simulate).
|
|
9611
9669
|
*/
|
|
9612
9670
|
static async fromBundle(bundle, options) {
|
|
9613
|
-
const timeout = options?.timeoutMs ??
|
|
9671
|
+
const timeout = options?.timeoutMs ?? DEFAULT_FIGHT_BACKSTOP_MS;
|
|
9614
9672
|
const code = createWorkerScript(bundle);
|
|
9615
9673
|
let worker;
|
|
9616
9674
|
let cleanup;
|
|
@@ -10500,6 +10558,12 @@ export {
|
|
|
10500
10558
|
normalizeAngle,
|
|
10501
10559
|
angleDiff,
|
|
10502
10560
|
angleInRange,
|
|
10561
|
+
DEFAULT_BUDGET,
|
|
10562
|
+
DEFAULT_FIGHT_BACKSTOP_MS,
|
|
10563
|
+
createBudgetState,
|
|
10564
|
+
createFightBudget,
|
|
10565
|
+
mayAct,
|
|
10566
|
+
recordSpend,
|
|
10503
10567
|
hashCombine,
|
|
10504
10568
|
nextRandom,
|
|
10505
10569
|
createRandom,
|
|
@@ -10592,6 +10656,7 @@ export {
|
|
|
10592
10656
|
Spellspinner,
|
|
10593
10657
|
Spellweaver,
|
|
10594
10658
|
Spellbinder,
|
|
10659
|
+
Hero,
|
|
10595
10660
|
BOT_GROUPS,
|
|
10596
10661
|
ALL_BOTS,
|
|
10597
10662
|
getEffectiveRange,
|
|
@@ -10617,4 +10682,4 @@ export {
|
|
|
10617
10682
|
diagnoseTrace,
|
|
10618
10683
|
formatDiagnosis
|
|
10619
10684
|
};
|
|
10620
|
-
//# sourceMappingURL=chunk-
|
|
10685
|
+
//# sourceMappingURL=chunk-US4MEDKT.js.map
|