@vibemancer/core 1.0.12 → 1.0.14

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.
@@ -213,8 +213,8 @@ function currentRuleset() {
213
213
  }
214
214
 
215
215
  // src/engine-version.ts
216
- var ENGINE_VERSION = 4256327861353618;
217
- var EQUIVALENT_ENGINE_VERSIONS = [1688330189011034];
216
+ var ENGINE_VERSION = 3372706385669861;
217
+ var EQUIVALENT_ENGINE_VERSIONS = [];
218
218
 
219
219
  // src/replay-compat.ts
220
220
  function canReplayMatch(matchEngineVersion) {
@@ -801,6 +801,21 @@ function createEntitySeed(matchSeed, entityId, tick2) {
801
801
  }
802
802
 
803
803
  // src/engine/bot-error-capture.ts
804
+ var NATIVE_STACK_GETTER = Object.getOwnPropertyDescriptor(new Error("probe"), "stack")?.get;
805
+ function safeStack(error) {
806
+ try {
807
+ const descriptor = Object.getOwnPropertyDescriptor(error, "stack");
808
+ if (!descriptor) return typeof error.stack === "string" ? error.stack : null;
809
+ if (typeof descriptor.value === "string") return descriptor.value;
810
+ if (descriptor.get && descriptor.get === NATIVE_STACK_GETTER) {
811
+ const stack = descriptor.get.call(error);
812
+ return typeof stack === "string" ? stack : null;
813
+ }
814
+ return null;
815
+ } catch {
816
+ return null;
817
+ }
818
+ }
804
819
  var MAX_MESSAGE_LENGTH = 1e3;
805
820
  var MAX_ERRORS_PER_MATCH = 500;
806
821
  function describeThrown(thrown) {
@@ -813,7 +828,8 @@ function rawDescription(thrown) {
813
828
  if (message.length > MAX_MESSAGE_LENGTH) {
814
829
  return { text: truncate(message) + " [stack omitted: message too large]", alreadyBounded: true };
815
830
  }
816
- const stack = typeof thrown.stack === "string" ? stripBundleCoordinates(thrown.stack.trim()) : "";
831
+ const raw = safeStack(thrown);
832
+ const stack = raw === null ? "" : stripBundleCoordinates(raw.trim());
817
833
  if (stack) return { text: stack, alreadyBounded: false };
818
834
  return { text: message || `${thrown.name || "Error"} (thrown with no message)`, alreadyBounded: false };
819
835
  }
@@ -1049,7 +1065,7 @@ function tick(currentTick, wizard1AI, wizard2AI, config, wizards, projectiles, m
1049
1065
  if (wizard.castProgress >= wizard.castDuration) {
1050
1066
  const spell = wizard.castingSpell;
1051
1067
  if (spell === "missile" && wizard.missileConfig && wizard.missileAI) {
1052
- const validConfig = validateMissileConfig(wizard.missileConfig);
1068
+ const validConfig = wizard.missileConfig;
1053
1069
  const id = `missile-${wizard.id}-${nextTick}`;
1054
1070
  const projectile = {
1055
1071
  id,
@@ -1168,7 +1184,7 @@ function tick(currentTick, wizard1AI, wizard2AI, config, wizards, projectiles, m
1168
1184
  message: `This missile takes ${wizard.castDuration} ticks to cast, but a match is only ${MATCH_DURATION} ticks long, so the cast can never finish and this wizard will stand still for the rest of the match. The cost is dominated by turnRate (${config2?.turnRate ?? "?"}) \u2014 it is the most expensive field by far, and unlike the others it is not clamped to a sane maximum. Try a turnRate in the single digits, then use missile-calc or getMissileCastTime() to check the cast time before committing to a config.`
1169
1185
  });
1170
1186
  }
1171
- wizard.missileConfig = action.startCast.config;
1187
+ wizard.missileConfig = Object.freeze(validateMissileConfig(action.startCast.config));
1172
1188
  wizard.missileAI = action.startCast.missileAI;
1173
1189
  if (action.startCast.direction !== void 0) {
1174
1190
  wizard.rotation = action.startCast.direction;
@@ -2141,7 +2157,9 @@ function analyzeThreats(myPos, projectiles, myProjectiles, ticksUntilReady, opti
2141
2157
  const enemyProjectiles = projectiles.filter((p) => !myProjectileIds.has(p.id));
2142
2158
  const threats = [];
2143
2159
  for (const projectile of enemyProjectiles) {
2144
- const analysis = analyzeOneThreat(myPos, projectile, ticksUntilReady, options?.canCancelCurrentCast ?? false);
2160
+ const rawMultiplier = options?.movementMultiplier;
2161
+ const multiplier = Number.isFinite(rawMultiplier) ? Math.min(1, Math.max(0, rawMultiplier)) : 1;
2162
+ const analysis = analyzeOneThreat(myPos, projectile, ticksUntilReady, options?.canCancelCurrentCast ?? false, multiplier);
2145
2163
  const missileDistance = Math.sqrt(
2146
2164
  (projectile.position.x - myPos.x) ** 2 + (projectile.position.y - myPos.y) ** 2
2147
2165
  );
@@ -2152,7 +2170,7 @@ function analyzeThreats(myPos, projectiles, myProjectiles, ticksUntilReady, opti
2152
2170
  threats.sort((a, b) => a.ticksToImpact - b.ticksToImpact);
2153
2171
  return threats;
2154
2172
  }
2155
- function analyzeOneThreat(targetPos, projectile, ticksUntilReady, canCancelCurrentCast) {
2173
+ function analyzeOneThreat(targetPos, projectile, ticksUntilReady, canCancelCurrentCast, movementMultiplier) {
2156
2174
  const missileRadius = calculateMissileRadius(projectile.damage);
2157
2175
  const collisionDist = COLLISION_RADIUS + missileRadius;
2158
2176
  const dodgeCollisionDist = collisionDist + projectile.speed * 0.5;
@@ -2166,9 +2184,9 @@ function analyzeOneThreat(targetPos, projectile, ticksUntilReady, canCancelCurre
2166
2184
  let canOutrun = true;
2167
2185
  let bestDodgeDirection = null;
2168
2186
  if (willHit) {
2169
- canDodgeLeft = simulateDodge(projectile, targetPos, "left", dodgeCollisionDist);
2170
- canDodgeRight = simulateDodge(projectile, targetPos, "right", dodgeCollisionDist);
2171
- canOutrun = simulateDodge(projectile, targetPos, "away", dodgeCollisionDist);
2187
+ canDodgeLeft = simulateDodge(projectile, targetPos, "left", dodgeCollisionDist, movementMultiplier);
2188
+ canDodgeRight = simulateDodge(projectile, targetPos, "right", dodgeCollisionDist, movementMultiplier);
2189
+ canOutrun = simulateDodge(projectile, targetPos, "away", dodgeCollisionDist, movementMultiplier);
2172
2190
  bestDodgeDirection = calculateBestDodgeDirection(
2173
2191
  projectile,
2174
2192
  targetPos,
@@ -2227,7 +2245,8 @@ function simulateMissileToTarget(projectile, targetPos, collisionDist) {
2227
2245
  }
2228
2246
  return { willHit: false, ticksToImpact: Infinity };
2229
2247
  }
2230
- function simulateDodge(projectile, startPos, direction, collisionDist) {
2248
+ function simulateDodge(projectile, startPos, direction, collisionDist, movementMultiplier) {
2249
+ const stepDistance = RULES.MOVEMENT_SPEED * movementMultiplier;
2231
2250
  const dodgeDir = getDodgeDirection(projectile, startPos, direction);
2232
2251
  if (dodgeDir.x === 0 && dodgeDir.y === 0) {
2233
2252
  return false;
@@ -2239,8 +2258,8 @@ function simulateDodge(projectile, startPos, direction, collisionDist) {
2239
2258
  const speed = projectile.speed;
2240
2259
  const turnRate = projectile.turnRate;
2241
2260
  for (let tick2 = 1; tick2 <= maxTicks; tick2++) {
2242
- const newX = targetPos.x + dodgeDir.x * RULES.MOVEMENT_SPEED;
2243
- const newY = targetPos.y + dodgeDir.y * RULES.MOVEMENT_SPEED;
2261
+ const newX = targetPos.x + dodgeDir.x * stepDistance;
2262
+ const newY = targetPos.y + dodgeDir.y * stepDistance;
2244
2263
  targetPos = {
2245
2264
  x: Math.max(ARENA_MIN + COLLISION_RADIUS, Math.min(ARENA_MAX - COLLISION_RADIUS, newX)),
2246
2265
  y: Math.max(ARENA_MIN + COLLISION_RADIUS, Math.min(ARENA_MAX - COLLISION_RADIUS, newY))
@@ -2457,10 +2476,17 @@ function useThreats() {
2457
2476
  ctx.projectiles,
2458
2477
  ctx.myProjectiles,
2459
2478
  ticksUntilReady,
2460
- // Mid-CAST you are one cancel() away from being able to shield, so the analysis
2461
- // must not charge you the whole remainder of the cast. A GCD cannot be cancelled,
2462
- // so it keeps the pessimistic reading.
2463
- { canCancelCurrentCast: ctx.state === "casting" }
2479
+ {
2480
+ // Mid-CAST you are one cancel() away from being able to shield, so the analysis
2481
+ // must not charge you the whole remainder of the cast. A GCD cannot be
2482
+ // cancelled, so it keeps the pessimistic reading.
2483
+ canCancelCurrentCast: ctx.state === "casting",
2484
+ // And the dodge half must use the speed you ACTUALLY have. The engine slows a
2485
+ // casting wizard to 33% and pins a channeling one to zero (physics.ts), while
2486
+ // the analysis stepped at full speed regardless — so it promised dodges that
2487
+ // could not be made, for the ~78% of a match a bot spends casting.
2488
+ movementMultiplier: ctx.state === "casting" ? RULES.CASTING_MOVEMENT_MULT : ctx.state === "channeling" ? 0 : 1
2489
+ }
2464
2490
  );
2465
2491
  }, [ctx.projectiles, ctx.myProjectiles, ctx.position.x, ctx.position.y, ticksUntilReady, ctx.state]);
2466
2492
  }
@@ -10944,4 +10970,4 @@ export {
10944
10970
  diagnoseTrace,
10945
10971
  formatDiagnosis
10946
10972
  };
10947
- //# sourceMappingURL=chunk-KGRG7TZS.js.map
10973
+ //# sourceMappingURL=chunk-2AVERV6J.js.map