@vibemancer/core 1.0.9 → 1.0.11
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-OLGKLCCB.js → chunk-EO7JO2RZ.js} +199 -24
- package/dist/chunk-EO7JO2RZ.js.map +1 -0
- package/dist/{index-browser-BTHlrB_s.d.ts → index-browser-CM0uuzWp.d.ts} +156 -18
- package/dist/index-browser.d.ts +1 -1
- package/dist/index-browser.js +5 -1
- package/dist/index.d.ts +10 -4
- package/dist/index.js +51 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/bot-compute-budget.ts +10 -0
- package/src/engine/bot-error-capture.ts +179 -0
- package/src/engine/manual-match.ts +2 -0
- package/src/engine/physics.ts +76 -0
- package/src/engine/sandbox-harness.ts +46 -0
- package/src/engine/sandbox.ts +347 -341
- package/src/engine/simulation.ts +120 -10
- package/src/engine-version.ts +1 -1
- package/src/hooks/action-builders.ts +112 -5
- package/src/hooks/state-hooks.ts +409 -407
- package/src/hooks/threat-analysis.ts +57 -18
- package/src/hooks/types.ts +16 -4
- package/src/rules.ts +8 -0
- package/src/types.ts +10 -6
- package/src/utils/combat.ts +379 -371
- package/dist/chunk-OLGKLCCB.js.map +0 -1
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
* damage history — only what's visible on the battlefield.
|
|
20
20
|
*/
|
|
21
21
|
interface EnemyState {
|
|
22
|
-
/** Enemy position in world coordinates
|
|
22
|
+
/** Enemy position in world coordinates. The arena is 0-860; the survivable playfield is
|
|
23
|
+
* [30, 830], and outside that band is lava. */
|
|
23
24
|
position: Position;
|
|
24
25
|
/** Enemy velocity in units/tick. */
|
|
25
26
|
velocity: Velocity;
|
|
@@ -95,9 +96,20 @@ interface ActionBuilder extends FinalAction {
|
|
|
95
96
|
* to `missile()` is overwritten before the shot leaves. That makes the enemy impossible
|
|
96
97
|
* to LEAD: you always fire where they are, never where they will be.
|
|
97
98
|
*
|
|
98
|
-
* `lockAim()` holds your angle for the whole cast
|
|
99
|
-
* and
|
|
100
|
-
*
|
|
99
|
+
* `lockAim()` holds your angle for the whole cast — but it is USUALLY THE WRONG TOOL for
|
|
100
|
+
* leading, and this comment used to claim the opposite. Measured over 1,140 matches
|
|
101
|
+
* against the built-ins: auto-aim wins 80.5%, lockAim with a computed lead wins 29.3%,
|
|
102
|
+
* and it degrades monotonically the more shots you lock.
|
|
103
|
+
*
|
|
104
|
+
* The reason is cast time. A cast runs 88-240 ticks — up to 2.4 SECONDS — and lockAim
|
|
105
|
+
* freezes the angle at cast START, so it is stale long before the missile leaves. No bot
|
|
106
|
+
* holds a heading that long.
|
|
107
|
+
*
|
|
108
|
+
* TO LEAD A TARGET, call `aim(degrees)` on every tick of the cast and recompute the lead
|
|
109
|
+
* each time: same harness, 85.4%. That is what makes `getLeadPosition` worth calling.
|
|
110
|
+
*
|
|
111
|
+
* lockAim is for aiming at a PLACE rather than a bot — a lava edge, an escape lane, an
|
|
112
|
+
* area you want denied — where a fixed angle is the point.
|
|
101
113
|
*
|
|
102
114
|
* Chainable — `missile(cfg, ai, angle).lockAim().move(0, 1)` aims, fires and kites.
|
|
103
115
|
*/
|
|
@@ -288,16 +300,20 @@ interface GameState {
|
|
|
288
300
|
* Actions returned by wizard each tick.
|
|
289
301
|
*
|
|
290
302
|
* Movement uses world-space coordinates:
|
|
291
|
-
* - x:
|
|
292
|
-
* - y:
|
|
293
|
-
* -
|
|
303
|
+
* - x: positive = right, negative = left
|
|
304
|
+
* - y: positive = down, negative = up
|
|
305
|
+
* - Only the DIRECTION matters: the vector is normalised, and magnitude is capped at 1.
|
|
306
|
+
* move(1, 0), move(5, 0) and move(100, 0) are identical; move(0.5, 0) is half speed.
|
|
294
307
|
* - No rotation tracking - just output (x, y) direction
|
|
308
|
+
*
|
|
309
|
+
* The old wording here described a [-100, 100] scale, which has not been true for a long
|
|
310
|
+
* time and is 100x off.
|
|
295
311
|
*/
|
|
296
312
|
interface WizardActions {
|
|
297
313
|
/**
|
|
298
|
-
* Movement direction in world-space.
|
|
299
|
-
*
|
|
300
|
-
*
|
|
314
|
+
* Movement direction in world-space. Only the direction matters — the vector is
|
|
315
|
+
* normalised and its magnitude is capped at 1, so move(100, 0) and move(1, 0) are the
|
|
316
|
+
* same full-speed step. A magnitude below 1 moves proportionally slower.
|
|
301
317
|
*/
|
|
302
318
|
move: {
|
|
303
319
|
x: number;
|
|
@@ -561,6 +577,14 @@ declare function validateMissileConfig(config: MissileConfig): MissileConfig;
|
|
|
561
577
|
* If lastMissileConfig is a MissileConfig, applies warmup multiplier:
|
|
562
578
|
* - Similar to previous: up to 20% faster
|
|
563
579
|
* - Very different: up to 20% slower (switching penalty)
|
|
580
|
+
*
|
|
581
|
+
* @returns cast time in SECONDS — multiply by TICKS_PER_SECOND for ticks.
|
|
582
|
+
*
|
|
583
|
+
* Bot authors almost always want `getMissileCastTime` from utils/combat.ts instead, which
|
|
584
|
+
* has the identical signature and returns TICKS, the unit the guide and every other number in
|
|
585
|
+
* the API use. Both are exported and both appear in vibemancer_api as `(config, last?) =>
|
|
586
|
+
* number`, so the unit was impossible to tell apart: 2.747 read as three ticks rather than
|
|
587
|
+
* 275.
|
|
564
588
|
*/
|
|
565
589
|
declare function calculateMissileCastTime(config: MissileConfig, lastMissileConfig?: MissileConfig | undefined | null): number;
|
|
566
590
|
declare const WARMUP_MAX_BONUS: number;
|
|
@@ -630,7 +654,7 @@ declare function currentRuleset(): Record<string, number>;
|
|
|
630
654
|
* Used to gate spectator replays: a recorded match can only be re-simulated when
|
|
631
655
|
* the runtime engine version matches the version that produced the match.
|
|
632
656
|
*/
|
|
633
|
-
declare const ENGINE_VERSION =
|
|
657
|
+
declare const ENGINE_VERSION = 2983169471988242;
|
|
634
658
|
/**
|
|
635
659
|
* Historical versions that denote the SAME engine as `ENGINE_VERSION`.
|
|
636
660
|
*
|
|
@@ -738,6 +762,16 @@ interface BudgetLimits {
|
|
|
738
762
|
interface BotBudgetState {
|
|
739
763
|
spentMs: number;
|
|
740
764
|
exhausted: boolean;
|
|
765
|
+
/**
|
|
766
|
+
* Whether the engine has already reported this bot being cut off.
|
|
767
|
+
*
|
|
768
|
+
* An exhausted bot is refused on every remaining tick — thousands of them — and one record
|
|
769
|
+
* is a report while thousands is a denial of service against the reader. Lives on the
|
|
770
|
+
* state rather than in the caller because the state object is what survives the early
|
|
771
|
+
* return: once exhausted, `recordSpend` is never reached again, so this same object
|
|
772
|
+
* persists for the rest of the match.
|
|
773
|
+
*/
|
|
774
|
+
reported?: boolean;
|
|
741
775
|
}
|
|
742
776
|
/**
|
|
743
777
|
* Default, sized from measurement (2026-08-30) — and resized once, after the first
|
|
@@ -851,6 +885,7 @@ declare function tick(currentTick: number, wizard1AI: WizardFunction, wizard2AI:
|
|
|
851
885
|
projectiles: ProjectileState[];
|
|
852
886
|
events: SimEvent[];
|
|
853
887
|
errors: BotError[];
|
|
888
|
+
budgetExhausted: BudgetExhaustion[];
|
|
854
889
|
budgets?: [BotBudgetState, BotBudgetState];
|
|
855
890
|
};
|
|
856
891
|
/**
|
|
@@ -867,10 +902,41 @@ type FightWinner = 'wizard-1' | 'wizard-2' | 'draw';
|
|
|
867
902
|
* Result of a simulation.
|
|
868
903
|
*/
|
|
869
904
|
/** A runtime error captured from a bot or missile AI function. */
|
|
905
|
+
/**
|
|
906
|
+
* A bot that ran out of its compute budget and stopped being called.
|
|
907
|
+
*
|
|
908
|
+
* Deliberately NOT a BotError. Errors feed `consecutiveCrashes` on the ladder and
|
|
909
|
+
* auto-deactivate a wizard at three; being slow on a loaded server must never cost someone
|
|
910
|
+
* their bot. But it was recorded NOWHERE, so a bot that burned its allowance stood still for
|
|
911
|
+
* the rest of the fight and reported a clean scoreline — measured, a certain 10-0 became 1
|
|
912
|
+
* win and 9 draws with nothing saying why.
|
|
913
|
+
*/
|
|
914
|
+
interface BudgetExhaustion {
|
|
915
|
+
entityId: string;
|
|
916
|
+
/** The tick the bot was first refused. */
|
|
917
|
+
tick: number;
|
|
918
|
+
/** How much it had spent when it was cut off, in milliseconds. */
|
|
919
|
+
spentMs: number;
|
|
920
|
+
/** 1-based match index within a fight; set by `fight()`, absent from a lone simulate(). */
|
|
921
|
+
match?: number;
|
|
922
|
+
}
|
|
870
923
|
interface BotError {
|
|
871
924
|
tick: number;
|
|
872
925
|
entityId: string;
|
|
873
926
|
message: string;
|
|
927
|
+
/**
|
|
928
|
+
* True when the wizard was ALREADY DEAD on the tick this was thrown.
|
|
929
|
+
*
|
|
930
|
+
* The engine keeps calling a bot after its health reaches zero and discards the action, so
|
|
931
|
+
* these errors change nothing. Unmarked they are actively misleading in two ways: a player
|
|
932
|
+
* sees a fault spanning hundreds of ticks with no hint the wizard was dead for all of
|
|
933
|
+
* them, and the ladder counts them toward consecutiveCrashes — so a bot can be
|
|
934
|
+
* auto-deactivated for errors the guide itself calls harmless.
|
|
935
|
+
*
|
|
936
|
+
* The engine is the only place that knows, so it is recorded here rather than guessed
|
|
937
|
+
* downstream from a reconstructed death tick.
|
|
938
|
+
*/
|
|
939
|
+
afterDeath?: boolean;
|
|
874
940
|
/**
|
|
875
941
|
* 1-based index within the fight's TEN matches, present only on `FightResult.allErrors`.
|
|
876
942
|
*
|
|
@@ -889,6 +955,15 @@ interface SimulateResult {
|
|
|
889
955
|
history: GameState[];
|
|
890
956
|
/** Runtime errors thrown by bot or missile AI functions (empty if no errors). */
|
|
891
957
|
errors: BotError[];
|
|
958
|
+
/**
|
|
959
|
+
* Bots that ran out of compute and stopped being called (empty if nobody did).
|
|
960
|
+
*
|
|
961
|
+
* Separate from `errors` on purpose: errors feed consecutiveCrashes and deactivate a
|
|
962
|
+
* wizard at three, and being slow must never do that. But it has to be reported SOMEWHERE
|
|
963
|
+
* — a bot cut off in match 1 stands still for the rest of the fight, and without this the
|
|
964
|
+
* player sees a clean scoreline and rewrites a strategy that was never the problem.
|
|
965
|
+
*/
|
|
966
|
+
budgetExhausted: BudgetExhaustion[];
|
|
892
967
|
}
|
|
893
968
|
/**
|
|
894
969
|
* Result of a fight (best-of-5 at different spawn distances).
|
|
@@ -917,6 +992,14 @@ interface FightResult {
|
|
|
917
992
|
* raw would blame each side's faults on the other.
|
|
918
993
|
*/
|
|
919
994
|
allErrors: BotError[];
|
|
995
|
+
/**
|
|
996
|
+
* Bots cut off by the compute budget, across all ten matches.
|
|
997
|
+
*
|
|
998
|
+
* The budget is FIGHT-scoped, so this is where it belongs: exhausting it in match 1
|
|
999
|
+
* freezes the bot for the other nine. Ids are in the caller's frame, mirrored out of the
|
|
1000
|
+
* swapped matches like allErrors.
|
|
1001
|
+
*/
|
|
1002
|
+
budgetExhausted: BudgetExhaustion[];
|
|
920
1003
|
}
|
|
921
1004
|
/** Spawn distances for the 5 matches in a fight (creates butterfly effect variation) */
|
|
922
1005
|
declare const FIGHT_SPAWN_DISTANCES: number[];
|
|
@@ -1086,6 +1169,48 @@ declare function moveProjectile(projectile: ProjectileState, deltaTicks: number)
|
|
|
1086
1169
|
* Clamp a position to the full arena bounds (0-860).
|
|
1087
1170
|
* No playfield clamping — wizards CAN walk/blink into lava.
|
|
1088
1171
|
*/
|
|
1172
|
+
/**
|
|
1173
|
+
* Clamp a position into the band where a wizard SURVIVES.
|
|
1174
|
+
*
|
|
1175
|
+
* `clampToArena` clamps to the full 0-860 arena, lava border included, which is what its own
|
|
1176
|
+
* JSDoc says and is almost never what a bot wants. The MCP guide nonetheless named it as the
|
|
1177
|
+
* remedy for lava, and an agent following that advice verbatim blinked into the lava at tick
|
|
1178
|
+
* 11 and lost 0-10 to a bot that does nothing. There was no exported helper that did the
|
|
1179
|
+
* survivable thing, so the guide reached for the closest-sounding name.
|
|
1180
|
+
*
|
|
1181
|
+
* The band is inset by the wizard's RADIUS, not merely to the playfield edge, because death
|
|
1182
|
+
* is decided by whether the wizard's EDGE touches lava: the safe range for a centre is
|
|
1183
|
+
* [ARENA_MIN + radius, ARENA_MAX - radius].
|
|
1184
|
+
*
|
|
1185
|
+
* A non-finite input returns the arena centre rather than propagating NaN — a helper whose
|
|
1186
|
+
* entire job is safety must not be the thing that poisons the simulation.
|
|
1187
|
+
*/
|
|
1188
|
+
declare function clampToSafeZone(position: Position, radius: number): Position;
|
|
1189
|
+
/**
|
|
1190
|
+
* A move vector that walks TOWARD a target without overshooting it.
|
|
1191
|
+
*
|
|
1192
|
+
* `move()` takes a DIRECTION, and `moveWizard` normalises only when the vector's magnitude
|
|
1193
|
+
* exceeds 1 — so a shorter vector is a fraction of full speed, not a distance. That makes the
|
|
1194
|
+
* obvious composition of the two things the guide recommends quietly fatal:
|
|
1195
|
+
*
|
|
1196
|
+
* const goal = clampToSafeZone({x: pos.x + dx, y: pos.y + dy}, WIZARD_RADIUS);
|
|
1197
|
+
* return move(goal.x - pos.x, goal.y - pos.y); // overshoots the clamp
|
|
1198
|
+
*
|
|
1199
|
+
* Asking to move 0.09 units moves you 0.14, which at the boundary is 0.03 units into the
|
|
1200
|
+
* lava, at full health. An agent died to exactly this at T1040 on 60/60 HP. It is the same
|
|
1201
|
+
* shape as the clampToArena defect: the helper was right and the composition was deadly.
|
|
1202
|
+
*
|
|
1203
|
+
* This scales the step so that ARRIVING is the worst case. It prevents OVERSHOOT, not bad
|
|
1204
|
+
* aim — clamp the target first, then walk to it:
|
|
1205
|
+
*
|
|
1206
|
+
* const goal = clampToSafeZone({x: pos.x + dx, y: pos.y + dy}, WIZARD_RADIUS);
|
|
1207
|
+
* return move(...moveTowardSafely(pos, goal)); // safe
|
|
1208
|
+
*
|
|
1209
|
+
* Aim it at an unclamped point 90 units away and it will take a full-speed step straight into
|
|
1210
|
+
* the lava, correctly. I made that exact mistake writing the test for this function, which is
|
|
1211
|
+
* the same composition confusion the helper exists to fix — hence spelling it out here.
|
|
1212
|
+
*/
|
|
1213
|
+
declare function moveTowardSafely(from: Position, target: Position): Position;
|
|
1089
1214
|
declare function clampToArena(position: Position, radius: number): Position;
|
|
1090
1215
|
/**
|
|
1091
1216
|
* Check if a position is in the lava zone (outside the playfield).
|
|
@@ -1413,6 +1538,14 @@ declare function magnitude(vector: Position): number;
|
|
|
1413
1538
|
*
|
|
1414
1539
|
* If lastMissileConfig is provided, includes warmup multiplier.
|
|
1415
1540
|
* Pass undefined for first cast (full warmup) or null for base time only.
|
|
1541
|
+
*
|
|
1542
|
+
* @returns cast time in TICKS.
|
|
1543
|
+
*
|
|
1544
|
+
* Note the unit, because there are two of these: `calculateMissileCastTime` in rules.ts has
|
|
1545
|
+
* the identical signature and returns SECONDS. vibemancer_api lists both as
|
|
1546
|
+
* `(config, last?) => number`, and the whole guide speaks in ticks — so a player budgeting
|
|
1547
|
+
* ticks from the seconds one reads 2.747 as "about three ticks" when it is 275.
|
|
1548
|
+
* This one is the one a bot wants.
|
|
1416
1549
|
*/
|
|
1417
1550
|
declare function getMissileCastTime(config: MissileConfig, lastMissileConfig?: MissileConfig | null): number;
|
|
1418
1551
|
/**
|
|
@@ -1535,7 +1668,7 @@ declare function useVelocity(): Velocity;
|
|
|
1535
1668
|
/**
|
|
1536
1669
|
* Get your current status:
|
|
1537
1670
|
* - 'idle': free to act
|
|
1538
|
-
* - 'casting': casting a spell (missile
|
|
1671
|
+
* - 'casting': casting a spell (missile, blink OR shield). Can move at 33% speed.
|
|
1539
1672
|
* - 'channeling': channeling shield. Cannot move. Cancel anytime with cancel().
|
|
1540
1673
|
* - 'gcd_locked': global cooldown after spell. Can move at full speed, but cannot cast.
|
|
1541
1674
|
*/
|
|
@@ -1572,7 +1705,9 @@ declare function useLastMissileConfig(): MissileConfig | undefined;
|
|
|
1572
1705
|
* Get blink cooldown remaining in ticks. Returns 0 if ready to blink.
|
|
1573
1706
|
*
|
|
1574
1707
|
* Cooldown scales with distance used:
|
|
1575
|
-
* -
|
|
1708
|
+
* - 10 units → 100 ticks (1s); 100 units → 667 ticks; 300 → 2000 (20s)
|
|
1709
|
+
* - The cooldown scales with DISTANCE, so a micro-blink is cheap and a full-range one is
|
|
1710
|
+
* not. This said 100 units → ~100 ticks, which understated it by 6.7x.
|
|
1576
1711
|
* - 300 units (max range) → 2000 ticks (20s)
|
|
1577
1712
|
*
|
|
1578
1713
|
* Note: 100 ticks = 1 second.
|
|
@@ -1713,7 +1848,7 @@ declare function shield(): ActionBuilder;
|
|
|
1713
1848
|
* Cast a missile spell.
|
|
1714
1849
|
*
|
|
1715
1850
|
* Cast time scales with damage, speed, duration, and turn rate — bigger missiles
|
|
1716
|
-
* take longer to cast. While casting you move at
|
|
1851
|
+
* take longer to cast. While casting you move at 33% speed. After firing, 100-tick
|
|
1717
1852
|
* (1s) GCD before next spell.
|
|
1718
1853
|
*
|
|
1719
1854
|
* Repeated similar missiles cast 20% faster (warmup bonus). Switching styles
|
|
@@ -1766,13 +1901,16 @@ declare function aim(degrees: number): ActionBuilder;
|
|
|
1766
1901
|
*
|
|
1767
1902
|
* Max range: 300 units from current position (clamped by engine if further).
|
|
1768
1903
|
* Cast time: 10 ticks (0.1s). Cooldown scales with distance:
|
|
1769
|
-
* -
|
|
1904
|
+
* - 10 units → 100 ticks (1s); 100 units → 667 ticks; 150 → 1000 (10s); 300 → 2000 (20s).
|
|
1905
|
+
* The cooldown scales with DISTANCE — a micro-blink costs a second, a full-range one
|
|
1906
|
+
* costs twenty. This line used to claim 100 units → 100 ticks, understating it 6.7x.
|
|
1770
1907
|
* - 300 units → 2000 ticks (20s)
|
|
1771
1908
|
*
|
|
1772
1909
|
* Cannot chain .move() — blink IS the movement.
|
|
1773
1910
|
*
|
|
1774
|
-
* @param x - Target X position (0-
|
|
1775
|
-
*
|
|
1911
|
+
* @param x - Target X position (absolute world coordinate; arena is 0-860, and the
|
|
1912
|
+
* survivable playfield is [30, 830] — outside that band is lava)
|
|
1913
|
+
* @param y - Target Y position (absolute world coordinate; see x)
|
|
1776
1914
|
*
|
|
1777
1915
|
* @example
|
|
1778
1916
|
* return blink(400, 400); // blink to center
|
|
@@ -3204,4 +3342,4 @@ declare function diagnoseTrace(events: TraceEvent[], summary: TraceSummary): str
|
|
|
3204
3342
|
/** Format diagnostic tips as a human-readable string. */
|
|
3205
3343
|
declare function formatDiagnosis(tips: string[]): string;
|
|
3206
3344
|
|
|
3207
|
-
export {
|
|
3345
|
+
export { type HookState as $, ALL_BOTS as A, BLINK_CAST_TIME as B, CASTING_MOVEMENT_MULT as C, type CastStartEvent as D, Critter as E, type FightResult as F, DEFAULT_BUDGET as G, DEFAULT_FIGHT_BACKSTOP_MS as H, DEFAULT_SEED as I, Doombringer as J, ENGINE_VERSION as K, EQUIVALENT_ENGINE_VERSIONS as L, type EnemyState as M, FIGHT_SPAWN_DISTANCES as N, type FightBudget as O, type FightStats as P, type FightWinner as Q, type FinalAction as R, type SimulateResult as S, Flamecaller as T, GCD_DURATION as U, type GameConfig as V, type GameState as W, Golem as X, Hero as Y, Hogger as Z, type HomingParams as _, ARENA_MAX as a, type SimEvent as a$, Infernalist as a0, type InternalWizardState as a1, KNOCKBACK_DAMAGE_THRESHOLD as a2, KNOCKBACK_DECAY as a3, KNOCKBACK_DELAY as a4, KNOCKBACK_SPEED_PER_DAMAGE as a5, LAVA_BORDER_WIDTH as a6, Lich as a7, MATCH_DURATION as a8, MAX_HEALTH as a9, type MissileFunction$1 as aA, type MissileHitEvent as aB, type MissileLaunchEvent as aC, type MissileOobEvent as aD, type MissileTemplate as aE, Nightblade as aF, type ParamDeclaration as aG, type Position as aH, type ProjectileState as aI, Pyromancer as aJ, RULES as aK, RULESET_RANGES as aL, type RefObject as aM, Rookie as aN, SHIELD_CAST_TIME as aO, SHIELD_DECAY_PER_SECOND as aP, SHIELD_DECAY_RATE as aQ, SHIELD_MAX_BLOCK as aR, SHIELD_MAX_STRENGTH as aS, SHIELD_MIN_BLOCK as aT, SHIELD_MIN_STRENGTH as aU, SPAWN_DISTANCE as aV, type SeekerParams as aW, Sentinel as aX, Shadowblade as aY, type ShieldBlockEvent as aZ, type ShieldStartEvent as a_, MISSILE_BASE_CAST as aa, MISSILE_BASE_RADIUS as ab, MISSILE_DAMAGE_POWER as ac, MISSILE_DAMAGE_RADIUS_SCALE as ad, MISSILE_DAMAGE_SCALE as ae, MISSILE_HOMING_COEFF as af, MISSILE_MIN_CAST_TIME as ag, MISSILE_MIN_DAMAGE as ah, MISSILE_MIN_DURATION as ai, MISSILE_MIN_SPEED as aj, MISSILE_RADIUS_PER_DAMAGE as ak, MISSILE_SPEED_DURATION_BASELINE as al, MISSILE_SPEED_DURATION_COEFF as am, MISSILE_TURN_DURATION_COEFF as an, MOVEMENT_SPEED as ao, MOVE_SPEED as ap, ManualMatch as aq, type ManualMatchInitOptions as ar, type ManualMatchOptions as as, type ManualMatchStepRequest as at, type MatchWinner as au, type MissileAction as av, type MissileActions as aw, type MissileConfig as ax, type MissileContext as ay, type MissileExpiredEvent as az, ARENA_MIN as b, clampToArena as b$, Spellbinder as b0, Spellseeker as b1, Spellshot as b2, Spellspinner as b3, Spelltracer as b4, Spellweaver as b5, type SpiralParams as b6, type StepResult as b7, Stormcaller as b8, Stormchaser as b9, type WizardEntry as bA, type WizardFunction as bB, type WizardGroup as bC, type WizardLavaDeathEvent as bD, type WizardState as bE, type WorkerFactory as bF, type WorkerLike as bG, aim as bH, analyzeThreats as bI, angleDiff as bJ, angleInRange as bK, angleTo as bL, applyDamage as bM, applyRulesetOverrides as bN, blink as bO, browserSandboxFight as bP, browserSandboxSimulate as bQ, calculateBlinkCooldown as bR, calculateMissileCastTime as bS, calculateMissileRadius as bT, calculateMissileSimilarity as bU, calculateShieldBlock as bV, calculateWarmupMultiplier as bW, canReplayMatch as bX, cancel as bY, cancelCast as bZ, clampPositionToArena as b_, Stormforger as ba, type StraightParams as bb, TICKS_PER_SECOND as bc, TICK_DURATION_MS as bd, TargetDummy as be, type TestBotBuilder as bf, type TestFightResult as bg, type TestSimulateResult as bh, type TraceBotSummary as bi, type TraceEvent as bj, type TraceEventType as bk, type TraceSummary as bl, Turtle as bm, type Velocity as bn, Voidblade as bo, WARMUP_DURATION_TOLERANCE as bp, WARMUP_MAX_BONUS as bq, WARMUP_MAX_PENALTY as br, WARMUP_SPEED_TOLERANCE as bs, WARMUP_TURN_TOLERANCE as bt, WIZARD_HEALTH as bu, WIZARD_RADIUS as bv, Warmage as bw, type WizardActions as bx, type WizardContext as by, type WizardDeathEvent as bz, ARENA_SIZE as c, resolveWizardCollision as c$, clampToSafeZone as c0, clearHooks as c1, clearParamValues as c2, completeCast as c3, createBudgetState as c4, createEntitySeed as c5, createFightBudget as c6, createInitialState as c7, createRandom as c8, createWorkerScript as c9, getMissileContext as cA, getPlayerState as cB, getWizardContext as cC, hashCombine as cD, homingMissile as cE, idle as cF, inRange as cG, interceptAngle as cH, isBannedBotName as cI, isInLava as cJ, magnitude as cK, matchesAnyBanRule as cL, mayAct as cM, missile as cN, move as cO, moveInDirection as cP, moveProjectile as cQ, moveTowardSafely as cR, moveWizard as cS, narrowRange as cT, nextRandom as cU, normalize as cV, normalizeAngle as cW, predictPosition as cX, recordSpend as cY, resetAllHooks as cZ, resetRuleset as c_, currentRuleset as ca, diagnoseTrace as cb, directionAway as cc, directionTo as cd, distanceTo as ce, effectiveTurnRateCost as cf, extractAction as cg, extractMissileAction as ch, extractStats as ci, extractTraceEvents as cj, fight as ck, findInRange as cl, findNearest as cm, fitMissileForEscapingTarget as cn, fitMissileToBudget as co, flyStraight as cp, formatDiagnosis as cq, formatStats as cr, formatTraceEvents as cs, formatTraceSummary as ct, generateCandidates as cu, generateCombos as cv, getAdaptiveMissileConfig as cw, getEffectiveRange as cx, getLeadPosition as cy, getMissileCastTime as cz, ARENA_WATER_BUFFER as d, runWithHooks as d0, runWizardWithContext as d1, scoreFight as d2, scoreFightAsWizard2 as d3, seekerMissile as d4, setParamValues as d5, shield as d6, simulate as d7, simulateMinDuration as d8, sortByDistance as d9, useMyProjectiles as dA, useMyThreatsToEnemy as dB, useParam as dC, usePosition as dD, useProjectiles as dE, useRandom as dF, useRef as dG, useShieldStrength as dH, useState as dI, useStatus as dJ, useThreats as dK, useTick as dL, useTicksUntilReady as dM, useVelocity as dN, validateHookCall as dO, validateMissileConfig as dP, withMissileContext as dQ, withWizardContext as dR, wrapWithParams as dS, spiralMissile as da, startCast as db, startDiscovery as dc, stopDiscovery as dd, straightMissile as de, summarizeTrace as df, sweptCircleCollision as dg, testBot as dh, tick as di, turnToAngle as dj, turnToward as dk, updateShield as dl, useArenaSize as dm, useBlinkCooldown as dn, useCastProgress as dp, useCastingSpell as dq, useClosestThreat as dr, useDamageDealt as ds, useDamageTaken as dt, useEffect as du, useEnemy as dv, useHealth as dw, useLastHitTick as dx, useLastMissileConfig as dy, useMemo as dz, type ActionBuilder as e, type AnalyzedThreat as f, Archlich as g, Archmage as h, BLINK_COOLDOWN as i, BLINK_MAX_COOLDOWN as j, BLINK_MAX_RANGE as k, BLINK_MIN_COOLDOWN as l, BLINK_RANGE as m, BOT_GROUPS as n, Battlemage as o, type BlinkEvent as p, Bonemancer as q, type BotBudgetState as r, type BotError as s, BrowserManualMatchSandbox as t, BrowserMatchSandbox as u, type BrowserSandboxOptions as v, type BudgetExhaustion as w, type BudgetLimits as x, COLLISION_RADIUS as y, type CastCancelEvent as z };
|
package/dist/index-browser.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { A as ALL_BOTS, a as ARENA_MAX, b as ARENA_MIN, c as ARENA_SIZE, d as ARENA_WATER_BUFFER, e as ActionBuilder, f as AnalyzedThreat, g as Archlich, h as Archmage, B as BLINK_CAST_TIME, i as BLINK_COOLDOWN, j as BLINK_MAX_COOLDOWN, k as BLINK_MAX_RANGE, l as BLINK_MIN_COOLDOWN, m as BLINK_RANGE, n as BOT_GROUPS, o as Battlemage, p as BlinkEvent, q as Bonemancer, s as BotError, t as BrowserManualMatchSandbox, u as BrowserMatchSandbox, v as BrowserSandboxOptions, C as CASTING_MOVEMENT_MULT,
|
|
1
|
+
export { A as ALL_BOTS, a as ARENA_MAX, b as ARENA_MIN, c as ARENA_SIZE, d as ARENA_WATER_BUFFER, e as ActionBuilder, f as AnalyzedThreat, g as Archlich, h as Archmage, B as BLINK_CAST_TIME, i as BLINK_COOLDOWN, j as BLINK_MAX_COOLDOWN, k as BLINK_MAX_RANGE, l as BLINK_MIN_COOLDOWN, m as BLINK_RANGE, n as BOT_GROUPS, o as Battlemage, p as BlinkEvent, q as Bonemancer, s as BotError, t as BrowserManualMatchSandbox, u as BrowserMatchSandbox, v as BrowserSandboxOptions, w as BudgetExhaustion, C as CASTING_MOVEMENT_MULT, y as COLLISION_RADIUS, z as CastCancelEvent, D as CastStartEvent, E as Critter, I as DEFAULT_SEED, J as Doombringer, K as ENGINE_VERSION, L as EQUIVALENT_ENGINE_VERSIONS, M as EnemyState, N as FIGHT_SPAWN_DISTANCES, F as FightResult, P as FightStats, Q as FightWinner, R as FinalAction, T as Flamecaller, U as GCD_DURATION, V as GameConfig, W as GameState, X as Golem, Y as Hero, Z as Hogger, _ as HomingParams, $ as HookState, a0 as Infernalist, a1 as InternalWizardState, a2 as KNOCKBACK_DAMAGE_THRESHOLD, a3 as KNOCKBACK_DECAY, a4 as KNOCKBACK_DELAY, a5 as KNOCKBACK_SPEED_PER_DAMAGE, a6 as LAVA_BORDER_WIDTH, a7 as Lich, a8 as MATCH_DURATION, a9 as MAX_HEALTH, aa as MISSILE_BASE_CAST, ab as MISSILE_BASE_RADIUS, ac as MISSILE_DAMAGE_POWER, ad as MISSILE_DAMAGE_RADIUS_SCALE, ae as MISSILE_DAMAGE_SCALE, af as MISSILE_HOMING_COEFF, ag as MISSILE_MIN_CAST_TIME, ah as MISSILE_MIN_DAMAGE, ai as MISSILE_MIN_DURATION, aj as MISSILE_MIN_SPEED, ak as MISSILE_RADIUS_PER_DAMAGE, al as MISSILE_SPEED_DURATION_BASELINE, am as MISSILE_SPEED_DURATION_COEFF, an as MISSILE_TURN_DURATION_COEFF, ao as MOVEMENT_SPEED, ap as MOVE_SPEED, aq as ManualMatch, ar as ManualMatchInitOptions, as as ManualMatchOptions, at as ManualMatchStepRequest, au as MatchWinner, av as MissileAction, aw as MissileActions, ax as MissileConfig, ay as MissileContext, az as MissileExpiredEvent, aA as MissileFunction, aB as MissileHitEvent, aC as MissileLaunchEvent, aD as MissileOobEvent, aE as MissileTemplate, aF as Nightblade, aG as ParamDeclaration, aH as Position, aI as ProjectileState, aJ as Pyromancer, aK as RULES, aL as RULESET_RANGES, aM as RefObject, aN as Rookie, aO as SHIELD_CAST_TIME, aP as SHIELD_DECAY_PER_SECOND, aQ as SHIELD_DECAY_RATE, aR as SHIELD_MAX_BLOCK, aS as SHIELD_MAX_STRENGTH, aT as SHIELD_MIN_BLOCK, aU as SHIELD_MIN_STRENGTH, aV as SPAWN_DISTANCE, aW as SeekerParams, aX as Sentinel, aY as Shadowblade, aZ as ShieldBlockEvent, a_ as ShieldStartEvent, a$ as SimEvent, S as SimulateResult, b0 as Spellbinder, b1 as Spellseeker, b2 as Spellshot, b3 as Spellspinner, b4 as Spelltracer, b5 as Spellweaver, b6 as SpiralParams, b7 as StepResult, b8 as Stormcaller, b9 as Stormchaser, ba as Stormforger, bb as StraightParams, bc as TICKS_PER_SECOND, bd as TICK_DURATION_MS, be as TargetDummy, bf as TestBotBuilder, bg as TestFightResult, bh as TestSimulateResult, bi as TraceBotSummary, bj as TraceEvent, bk as TraceEventType, bl as TraceSummary, bm as Turtle, bn as Velocity, bo as Voidblade, bp as WARMUP_DURATION_TOLERANCE, bq as WARMUP_MAX_BONUS, br as WARMUP_MAX_PENALTY, bs as WARMUP_SPEED_TOLERANCE, bt as WARMUP_TURN_TOLERANCE, bu as WIZARD_HEALTH, bv as WIZARD_RADIUS, bw as Warmage, bx as WizardActions, by as WizardContext, bz as WizardDeathEvent, bA as WizardEntry, bB as WizardFunction, bC as WizardGroup, bD as WizardLavaDeathEvent, bE as WizardState, bF as WorkerFactory, bG as WorkerLike, bH as aim, bI as analyzeThreats, bJ as angleDiff, bK as angleInRange, bL as angleTo, bM as applyDamage, bN as applyRulesetOverrides, bO as blink, bP as browserSandboxFight, bQ as browserSandboxSimulate, bR as calculateBlinkCooldown, bS as calculateMissileCastTime, bT as calculateMissileRadius, bU as calculateMissileSimilarity, bV as calculateShieldBlock, bW as calculateWarmupMultiplier, bX as canReplayMatch, bY as cancel, bZ as cancelCast, b_ as clampPositionToArena, b$ as clampToArena, c0 as clampToSafeZone, c1 as clearHooks, c2 as clearParamValues, c3 as completeCast, c5 as createEntitySeed, c7 as createInitialState, c8 as createRandom, c9 as createWorkerScript, ca as currentRuleset, cb as diagnoseTrace, cc as directionAway, cd as directionTo, ce as distanceTo, cf as effectiveTurnRateCost, cg as extractAction, ch as extractMissileAction, ci as extractStats, cj as extractTraceEvents, ck as fight, cl as findInRange, cm as findNearest, cn as fitMissileForEscapingTarget, co as fitMissileToBudget, cp as flyStraight, cq as formatDiagnosis, cr as formatStats, cs as formatTraceEvents, ct as formatTraceSummary, cu as generateCandidates, cv as generateCombos, cw as getAdaptiveMissileConfig, cx as getEffectiveRange, cy as getLeadPosition, cz as getMissileCastTime, cA as getMissileContext, cB as getPlayerState, cC as getWizardContext, cD as hashCombine, cE as homingMissile, cF as idle, cG as inRange, cH as interceptAngle, cI as isBannedBotName, cJ as isInLava, cK as magnitude, cL as matchesAnyBanRule, cN as missile, cO as move, cP as moveInDirection, cQ as moveProjectile, cR as moveTowardSafely, cS as moveWizard, cT as narrowRange, cU as nextRandom, cV as normalize, cW as normalizeAngle, cX as predictPosition, cZ as resetAllHooks, c_ as resetRuleset, c$ as resolveWizardCollision, d0 as runWithHooks, d1 as runWizardWithContext, d2 as scoreFight, d3 as scoreFightAsWizard2, d4 as seekerMissile, d5 as setParamValues, d6 as shield, d7 as simulate, d8 as simulateMinDuration, d9 as sortByDistance, da as spiralMissile, db as startCast, dc as startDiscovery, dd as stopDiscovery, de as straightMissile, df as summarizeTrace, dg as sweptCircleCollision, dh as testBot, di as tick, dj as turnToAngle, dk as turnToward, dl as updateShield, dm as useArenaSize, dn as useBlinkCooldown, dp as useCastProgress, dq as useCastingSpell, dr as useClosestThreat, ds as useDamageDealt, dt as useDamageTaken, du as useEffect, dv as useEnemy, dw as useHealth, dx as useLastHitTick, dy as useLastMissileConfig, dz as useMemo, dA as useMyProjectiles, dB as useMyThreatsToEnemy, dC as useParam, dD as usePosition, dE as useProjectiles, dF as useRandom, dG as useRef, dH as useShieldStrength, dI as useState, dJ as useStatus, dK as useThreats, dL as useTick, dM as useTicksUntilReady, dN as useVelocity, dO as validateHookCall, dP as validateMissileConfig, dQ as withMissileContext, dR as withWizardContext, dS as wrapWithParams } from './index-browser-CM0uuzWp.js';
|
package/dist/index-browser.js
CHANGED
|
@@ -114,6 +114,7 @@ import {
|
|
|
114
114
|
cancelCast,
|
|
115
115
|
clampPositionToArena,
|
|
116
116
|
clampToArena,
|
|
117
|
+
clampToSafeZone,
|
|
117
118
|
clearHooks,
|
|
118
119
|
clearParamValues,
|
|
119
120
|
completeCast,
|
|
@@ -163,6 +164,7 @@ import {
|
|
|
163
164
|
move,
|
|
164
165
|
moveInDirection,
|
|
165
166
|
moveProjectile,
|
|
167
|
+
moveTowardSafely,
|
|
166
168
|
moveWizard,
|
|
167
169
|
narrowRange,
|
|
168
170
|
nextRandom,
|
|
@@ -226,7 +228,7 @@ import {
|
|
|
226
228
|
withMissileContext,
|
|
227
229
|
withWizardContext,
|
|
228
230
|
wrapWithParams
|
|
229
|
-
} from "./chunk-
|
|
231
|
+
} from "./chunk-EO7JO2RZ.js";
|
|
230
232
|
export {
|
|
231
233
|
ALL_BOTS,
|
|
232
234
|
ARENA_MAX,
|
|
@@ -343,6 +345,7 @@ export {
|
|
|
343
345
|
cancelCast,
|
|
344
346
|
clampPositionToArena,
|
|
345
347
|
clampToArena,
|
|
348
|
+
clampToSafeZone,
|
|
346
349
|
clearHooks,
|
|
347
350
|
clearParamValues,
|
|
348
351
|
completeCast,
|
|
@@ -392,6 +395,7 @@ export {
|
|
|
392
395
|
move,
|
|
393
396
|
moveInDirection,
|
|
394
397
|
moveProjectile,
|
|
398
|
+
moveTowardSafely,
|
|
395
399
|
moveWizard,
|
|
396
400
|
narrowRange,
|
|
397
401
|
nextRandom,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FightResult, S as SimulateResult } from './index-browser-
|
|
2
|
-
export { A as ALL_BOTS, a as ARENA_MAX, b as ARENA_MIN, c as ARENA_SIZE, d as ARENA_WATER_BUFFER, e as ActionBuilder, f as AnalyzedThreat, g as Archlich, h as Archmage, B as BLINK_CAST_TIME, i as BLINK_COOLDOWN, j as BLINK_MAX_COOLDOWN, k as BLINK_MAX_RANGE, l as BLINK_MIN_COOLDOWN, m as BLINK_RANGE, n as BOT_GROUPS, o as Battlemage, p as BlinkEvent, q as Bonemancer, r as BotBudgetState, s as BotError, t as BrowserManualMatchSandbox, u as BrowserMatchSandbox, v as BrowserSandboxOptions, w as
|
|
1
|
+
import { F as FightResult, S as SimulateResult } from './index-browser-CM0uuzWp.js';
|
|
2
|
+
export { A as ALL_BOTS, a as ARENA_MAX, b as ARENA_MIN, c as ARENA_SIZE, d as ARENA_WATER_BUFFER, e as ActionBuilder, f as AnalyzedThreat, g as Archlich, h as Archmage, B as BLINK_CAST_TIME, i as BLINK_COOLDOWN, j as BLINK_MAX_COOLDOWN, k as BLINK_MAX_RANGE, l as BLINK_MIN_COOLDOWN, m as BLINK_RANGE, n as BOT_GROUPS, o as Battlemage, p as BlinkEvent, q as Bonemancer, r as BotBudgetState, s as BotError, t as BrowserManualMatchSandbox, u as BrowserMatchSandbox, v as BrowserSandboxOptions, w as BudgetExhaustion, x as BudgetLimits, C as CASTING_MOVEMENT_MULT, y as COLLISION_RADIUS, z as CastCancelEvent, D as CastStartEvent, E as Critter, G as DEFAULT_BUDGET, H as DEFAULT_FIGHT_BACKSTOP_MS, I as DEFAULT_SEED, J as Doombringer, K as ENGINE_VERSION, L as EQUIVALENT_ENGINE_VERSIONS, M as EnemyState, N as FIGHT_SPAWN_DISTANCES, O as FightBudget, P as FightStats, Q as FightWinner, R as FinalAction, T as Flamecaller, U as GCD_DURATION, V as GameConfig, W as GameState, X as Golem, Y as Hero, Z as Hogger, _ as HomingParams, $ as HookState, a0 as Infernalist, a1 as InternalWizardState, a2 as KNOCKBACK_DAMAGE_THRESHOLD, a3 as KNOCKBACK_DECAY, a4 as KNOCKBACK_DELAY, a5 as KNOCKBACK_SPEED_PER_DAMAGE, a6 as LAVA_BORDER_WIDTH, a7 as Lich, a8 as MATCH_DURATION, a9 as MAX_HEALTH, aa as MISSILE_BASE_CAST, ab as MISSILE_BASE_RADIUS, ac as MISSILE_DAMAGE_POWER, ad as MISSILE_DAMAGE_RADIUS_SCALE, ae as MISSILE_DAMAGE_SCALE, af as MISSILE_HOMING_COEFF, ag as MISSILE_MIN_CAST_TIME, ah as MISSILE_MIN_DAMAGE, ai as MISSILE_MIN_DURATION, aj as MISSILE_MIN_SPEED, ak as MISSILE_RADIUS_PER_DAMAGE, al as MISSILE_SPEED_DURATION_BASELINE, am as MISSILE_SPEED_DURATION_COEFF, an as MISSILE_TURN_DURATION_COEFF, ao as MOVEMENT_SPEED, ap as MOVE_SPEED, aq as ManualMatch, ar as ManualMatchInitOptions, as as ManualMatchOptions, at as ManualMatchStepRequest, au as MatchWinner, av as MissileAction, aw as MissileActions, ax as MissileConfig, ay as MissileContext, az as MissileExpiredEvent, aA as MissileFunction, aB as MissileHitEvent, aC as MissileLaunchEvent, aD as MissileOobEvent, aE as MissileTemplate, aF as Nightblade, aG as ParamDeclaration, aH as Position, aI as ProjectileState, aJ as Pyromancer, aK as RULES, aL as RULESET_RANGES, aM as RefObject, aN as Rookie, aO as SHIELD_CAST_TIME, aP as SHIELD_DECAY_PER_SECOND, aQ as SHIELD_DECAY_RATE, aR as SHIELD_MAX_BLOCK, aS as SHIELD_MAX_STRENGTH, aT as SHIELD_MIN_BLOCK, aU as SHIELD_MIN_STRENGTH, aV as SPAWN_DISTANCE, aW as SeekerParams, aX as Sentinel, aY as Shadowblade, aZ as ShieldBlockEvent, a_ as ShieldStartEvent, a$ as SimEvent, b0 as Spellbinder, b1 as Spellseeker, b2 as Spellshot, b3 as Spellspinner, b4 as Spelltracer, b5 as Spellweaver, b6 as SpiralParams, b7 as StepResult, b8 as Stormcaller, b9 as Stormchaser, ba as Stormforger, bb as StraightParams, bc as TICKS_PER_SECOND, bd as TICK_DURATION_MS, be as TargetDummy, bf as TestBotBuilder, bg as TestFightResult, bh as TestSimulateResult, bi as TraceBotSummary, bj as TraceEvent, bk as TraceEventType, bl as TraceSummary, bm as Turtle, bn as Velocity, bo as Voidblade, bp as WARMUP_DURATION_TOLERANCE, bq as WARMUP_MAX_BONUS, br as WARMUP_MAX_PENALTY, bs as WARMUP_SPEED_TOLERANCE, bt as WARMUP_TURN_TOLERANCE, bu as WIZARD_HEALTH, bv as WIZARD_RADIUS, bw as Warmage, bx as WizardActions, by as WizardContext, bz as WizardDeathEvent, bA as WizardEntry, bB as WizardFunction, bC as WizardGroup, bD as WizardLavaDeathEvent, bE as WizardState, bF as WorkerFactory, bG as WorkerLike, bH as aim, bI as analyzeThreats, bJ as angleDiff, bK as angleInRange, bL as angleTo, bM as applyDamage, bN as applyRulesetOverrides, bO as blink, bP as browserSandboxFight, bQ as browserSandboxSimulate, bR as calculateBlinkCooldown, bS as calculateMissileCastTime, bT as calculateMissileRadius, bU as calculateMissileSimilarity, bV as calculateShieldBlock, bW as calculateWarmupMultiplier, bX as canReplayMatch, bY as cancel, bZ as cancelCast, b_ as clampPositionToArena, b$ as clampToArena, c0 as clampToSafeZone, c1 as clearHooks, c2 as clearParamValues, c3 as completeCast, c4 as createBudgetState, c5 as createEntitySeed, c6 as createFightBudget, c7 as createInitialState, c8 as createRandom, c9 as createWorkerScript, ca as currentRuleset, cb as diagnoseTrace, cc as directionAway, cd as directionTo, ce as distanceTo, cf as effectiveTurnRateCost, cg as extractAction, ch as extractMissileAction, ci as extractStats, cj as extractTraceEvents, ck as fight, cl as findInRange, cm as findNearest, cn as fitMissileForEscapingTarget, co as fitMissileToBudget, cp as flyStraight, cq as formatDiagnosis, cr as formatStats, cs as formatTraceEvents, ct as formatTraceSummary, cu as generateCandidates, cv as generateCombos, cw as getAdaptiveMissileConfig, cx as getEffectiveRange, cy as getLeadPosition, cz as getMissileCastTime, cA as getMissileContext, cB as getPlayerState, cC as getWizardContext, cD as hashCombine, cE as homingMissile, cF as idle, cG as inRange, cH as interceptAngle, cI as isBannedBotName, cJ as isInLava, cK as magnitude, cL as matchesAnyBanRule, cM as mayAct, cN as missile, cO as move, cP as moveInDirection, cQ as moveProjectile, cR as moveTowardSafely, cS as moveWizard, cT as narrowRange, cU as nextRandom, cV as normalize, cW as normalizeAngle, cX as predictPosition, cY as recordSpend, cZ as resetAllHooks, c_ as resetRuleset, c$ as resolveWizardCollision, d0 as runWithHooks, d1 as runWizardWithContext, d2 as scoreFight, d3 as scoreFightAsWizard2, d4 as seekerMissile, d5 as setParamValues, d6 as shield, d7 as simulate, d8 as simulateMinDuration, d9 as sortByDistance, da as spiralMissile, db as startCast, dc as startDiscovery, dd as stopDiscovery, de as straightMissile, df as summarizeTrace, dg as sweptCircleCollision, dh as testBot, di as tick, dj as turnToAngle, dk as turnToward, dl as updateShield, dm as useArenaSize, dn as useBlinkCooldown, dp as useCastProgress, dq as useCastingSpell, dr as useClosestThreat, ds as useDamageDealt, dt as useDamageTaken, du as useEffect, dv as useEnemy, dw as useHealth, dx as useLastHitTick, dy as useLastMissileConfig, dz as useMemo, dA as useMyProjectiles, dB as useMyThreatsToEnemy, dC as useParam, dD as usePosition, dE as useProjectiles, dF as useRandom, dG as useRef, dH as useShieldStrength, dI as useState, dJ as useStatus, dK as useThreats, dL as useTick, dM as useTicksUntilReady, dN as useVelocity, dO as validateHookCall, dP as validateMissileConfig, dQ as withMissileContext, dR as withWizardContext, dS as wrapWithParams } from './index-browser-CM0uuzWp.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A compiled bot ready for sandboxed execution.
|
|
@@ -43,7 +43,7 @@ declare function compileMatchBundle(bot1: BotBundle, bot2: BotBundle, options?:
|
|
|
43
43
|
*
|
|
44
44
|
* Safety:
|
|
45
45
|
* - Memory limit (default 512 MB) catches memory bombs
|
|
46
|
-
* - Timeout (default
|
|
46
|
+
* - Timeout (default DEFAULT_FIGHT_BACKSTOP_MS) catches infinite loops
|
|
47
47
|
* - Prototype freeze prevents cross-bot sabotage
|
|
48
48
|
* - platform: 'neutral' strips Node.js APIs (no fs/net/process)
|
|
49
49
|
*/
|
|
@@ -54,7 +54,13 @@ declare function compileMatchBundle(bot1: BotBundle, bot2: BotBundle, options?:
|
|
|
54
54
|
interface SandboxOptions {
|
|
55
55
|
/** Memory limit in MB for the isolate (default: 512). */
|
|
56
56
|
memoryLimitMB?: number;
|
|
57
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Timeout in ms for fight/simulate calls. Defaults to DEFAULT_FIGHT_BACKSTOP_MS.
|
|
59
|
+
*
|
|
60
|
+
* Named rather than written out, because this file previously gave THREE different
|
|
61
|
+
* numbers for one default — "30s" in the header, "60000" here, and the actual value used
|
|
62
|
+
* below — and a reader had no way to tell which was true.
|
|
63
|
+
*/
|
|
58
64
|
timeoutMs?: number;
|
|
59
65
|
/** Options passed to esbuild compilation (aliases, externals). */
|
|
60
66
|
compileOptions?: CompileOptions;
|
package/dist/index.js
CHANGED
|
@@ -116,6 +116,7 @@ import {
|
|
|
116
116
|
cancelCast,
|
|
117
117
|
clampPositionToArena,
|
|
118
118
|
clampToArena,
|
|
119
|
+
clampToSafeZone,
|
|
119
120
|
clearHooks,
|
|
120
121
|
clearParamValues,
|
|
121
122
|
completeCast,
|
|
@@ -168,6 +169,7 @@ import {
|
|
|
168
169
|
move,
|
|
169
170
|
moveInDirection,
|
|
170
171
|
moveProjectile,
|
|
172
|
+
moveTowardSafely,
|
|
171
173
|
moveWizard,
|
|
172
174
|
narrowRange,
|
|
173
175
|
nextRandom,
|
|
@@ -232,7 +234,7 @@ import {
|
|
|
232
234
|
withMissileContext,
|
|
233
235
|
withWizardContext,
|
|
234
236
|
wrapWithParams
|
|
235
|
-
} from "./chunk-
|
|
237
|
+
} from "./chunk-EO7JO2RZ.js";
|
|
236
238
|
|
|
237
239
|
// src/engine/sandbox.ts
|
|
238
240
|
import ivm from "isolated-vm";
|
|
@@ -256,8 +258,54 @@ Object.freeze(Date.prototype);
|
|
|
256
258
|
Object.freeze(Error.prototype);
|
|
257
259
|
Object.freeze(Map.prototype);
|
|
258
260
|
Object.freeze(Set.prototype);
|
|
261
|
+
// Math.random is made DETERMINISTIC before Math is frozen.
|
|
262
|
+
//
|
|
263
|
+
// It was live and unseeded, and calling it is a completely natural thing for a bot to write.
|
|
264
|
+
// Rated matches persist only (seed, engineVersion) and spectate RE-SIMULATES, so any bot
|
|
265
|
+
// touching Math.random made the spectator watch a different fight from the one that moved the
|
|
266
|
+
// ratings \u2014 with nothing to fall back on and no warning anywhere. The replay feature only
|
|
267
|
+
// means something if the replay is the same fight.
|
|
268
|
+
//
|
|
269
|
+
// Seeded from a fixed constant rather than the match seed, because this banner runs before
|
|
270
|
+
// any bot code and therefore before the seed exists. That is sufficient: re-simulating the
|
|
271
|
+
// same bundle reproduces the same sequence, which is exactly what replay needs. Bots wanting
|
|
272
|
+
// randomness that VARIES per match still have useRandom(), which is seeded per entity and
|
|
273
|
+
// per tick.
|
|
274
|
+
//
|
|
275
|
+
// Installed with defineProperty and then frozen, so a bot cannot swap it back out \u2014 the same
|
|
276
|
+
// lesson as Date.now, which was writable and let a bot charge its opponent 50 seconds.
|
|
277
|
+
(function() {
|
|
278
|
+
var state = 0x2F6E2B1 >>> 0;
|
|
279
|
+
Object.defineProperty(Math, 'random', {
|
|
280
|
+
value: function() {
|
|
281
|
+
// xorshift32: small, fast, and good enough for gameplay jitter.
|
|
282
|
+
state ^= state << 13; state >>>= 0;
|
|
283
|
+
state ^= state >>> 17;
|
|
284
|
+
state ^= state << 5; state >>>= 0;
|
|
285
|
+
return state / 4294967296;
|
|
286
|
+
},
|
|
287
|
+
writable: false,
|
|
288
|
+
configurable: false,
|
|
289
|
+
});
|
|
290
|
+
})();
|
|
259
291
|
Object.freeze(Math);
|
|
260
292
|
Object.freeze(JSON);
|
|
293
|
+
// The CONSTRUCTORS, not just their prototypes.
|
|
294
|
+
//
|
|
295
|
+
// Freezing Date.prototype left Date.now writable, and an agent used that to charge its
|
|
296
|
+
// OPPONENT 50,000ms of compute: the engine reads Date.now() around each bot call, so a bot
|
|
297
|
+
// that returns 0 for its own pair and a huge number for its victim's drains a budget that is
|
|
298
|
+
// not its own. The victim froze for the rest of the fight and the report stated as fact that
|
|
299
|
+
// it had burned the time.
|
|
300
|
+
//
|
|
301
|
+
// Freezing Number.prototype left Number.isFinite writable, which defeats every input guard in
|
|
302
|
+
// the engine in one line \u2014 move, blink, aim and validateMissileConfig all rely on it.
|
|
303
|
+
Object.freeze(Date);
|
|
304
|
+
Object.freeze(Number);
|
|
305
|
+
Object.freeze(Boolean);
|
|
306
|
+
Object.freeze(String);
|
|
307
|
+
Object.freeze(Array);
|
|
308
|
+
Object.freeze(Object);
|
|
261
309
|
(function() {
|
|
262
310
|
var g = typeof globalThis !== 'undefined' ? globalThis : typeof self !== 'undefined' ? self : {};
|
|
263
311
|
var blocked = [
|
|
@@ -816,6 +864,7 @@ export {
|
|
|
816
864
|
cancelCast,
|
|
817
865
|
clampPositionToArena,
|
|
818
866
|
clampToArena,
|
|
867
|
+
clampToSafeZone,
|
|
819
868
|
clearHooks,
|
|
820
869
|
clearParamValues,
|
|
821
870
|
compileMatchBundle,
|
|
@@ -869,6 +918,7 @@ export {
|
|
|
869
918
|
move,
|
|
870
919
|
moveInDirection,
|
|
871
920
|
moveProjectile,
|
|
921
|
+
moveTowardSafely,
|
|
872
922
|
moveWizard,
|
|
873
923
|
narrowRange,
|
|
874
924
|
nextRandom,
|