@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.
- package/dist/{chunk-KGRG7TZS.js → chunk-2AVERV6J.js} +44 -18
- package/dist/chunk-2AVERV6J.js.map +1 -0
- package/dist/{index-browser-Dc-Vl1HI.d.ts → index-browser-oQNgZFLr.d.ts} +5 -2
- package/dist/index-browser.d.ts +1 -1
- package/dist/index-browser.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/engine/bot-error-capture.ts +51 -1
- package/src/engine/simulation.ts +15 -3
- package/src/engine-version.ts +2 -2
- package/src/hooks/state-hooks.ts +13 -4
- package/src/hooks/threat-analysis.ts +22 -8
- package/dist/chunk-KGRG7TZS.js.map +0 -1
|
@@ -213,8 +213,8 @@ function currentRuleset() {
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
// src/engine-version.ts
|
|
216
|
-
var ENGINE_VERSION =
|
|
217
|
-
var EQUIVALENT_ENGINE_VERSIONS = [
|
|
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
|
|
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 =
|
|
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
|
|
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 *
|
|
2243
|
-
const newY = targetPos.y + dodgeDir.y *
|
|
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
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
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-
|
|
10973
|
+
//# sourceMappingURL=chunk-2AVERV6J.js.map
|