@vibemancer/core 1.0.2 → 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.
@@ -208,7 +208,7 @@ function currentRuleset() {
208
208
  }
209
209
 
210
210
  // src/engine-version.ts
211
- var ENGINE_VERSION = 1203306608058186;
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
- let actions1 = { move: { x: 0, y: 0 } };
779
- try {
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
- actions1 = runWithHooks(wizards[0].id, () => extractAction(withWizardContext(ctx1, wizard1AI))) ?? { move: { x: 0, y: 0 } };
783
- } catch (e) {
784
- errors.push({ tick: nextTick, entityId: "wizard-1", message: e instanceof Error ? e.message : String(e) });
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
- actions2 = runWithHooks(wizards[1].id, () => extractAction(withWizardContext(ctx2, wizard2AI))) ?? { move: { x: 0, y: 0 } };
791
- } catch (e) {
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(currentTick, wizard1AI, wizard2AI, config, wizards, projectiles, missileAIs, seed);
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 ?? 3e4;
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-XYEK7THS.js.map
10685
+ //# sourceMappingURL=chunk-US4MEDKT.js.map