@modelstatus/cli 0.1.38 → 0.1.39

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelstatus/cli",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "Track which AI models you use, where, and never get surprised by a retirement. Free offline model-health for any repo (mm status), browser sign-in for cloud inventory + alerts.",
5
5
  "keywords": [
6
6
  "llm",
@@ -96,10 +96,6 @@ export function cooldownForLevel(level) {
96
96
  export function barrelSpeedForLevel(level) {
97
97
  return Math.min(170, BARREL_ROLL + (level - 1) * 12);
98
98
  }
99
- /** Probability a rolling barrel takes a ladder down per eligibility check. */
100
- export function ladderChanceForLevel(level) {
101
- return Math.min(0.6, 0.18 + (level - 1) * 0.1);
102
- }
103
99
  /** By construction the jump apex (~3 cells) clears a 1-cell barrel + player at
104
100
  * every level — exposed so a test can assert the invariant numerically. */
105
101
  export function jumpClearsBarrel(/* level */) {
@@ -340,7 +336,7 @@ function stepDying(s, _dt) {
340
336
  p.vy = Math.min(p.vy + GRAVITY, TERMINAL_VY);
341
337
  p.py = clampFx(p.py + p.vy, 0, toFx(s.BOARD_H - 1));
342
338
  syncCell(p);
343
- advanceBarrels(s, makeRnd(s)); // juice: hazards stay live during the death beat
339
+ advanceBarrels(s); // juice: hazards stay live during the death beat
344
340
  s.statusTimer -= 1;
345
341
  if (s.statusTimer <= 0) {
346
342
  if (s.lives > 0) {
@@ -542,7 +538,7 @@ function stepPlaying(s, input, dt) {
542
538
  }
543
539
 
544
540
  // 6/7. BARRELS -------------------------------------------------------------
545
- advanceBarrels(s, rnd);
541
+ advanceBarrels(s);
546
542
 
547
543
  // 8. COLLISIONS + SCORING --------------------------------------------------
548
544
  const pCol = cell(p.px), pRow = cell(p.py);
@@ -601,10 +597,11 @@ function stepPlaying(s, input, dt) {
601
597
  return finalize(s, s.rngSeed);
602
598
  }
603
599
 
604
- /** Advance every barrel one tick (roll / fall / descend ladders) in fx. */
605
- function advanceBarrels(s, rnd) {
606
- const { platforms, ladders, BOARD_W, BOARD_H } = s;
607
- const ladderChance = ladderChanceForLevel(s.level);
600
+ /** Advance every barrel one tick (roll along a girder / fall to the one below) in
601
+ * fx. Barrels NEVER take ladders — random mid-board drops were unreadable/unfair;
602
+ * a barrel rolls to the wall, bounces, and falls, a predictable zig-zag cascade. */
603
+ function advanceBarrels(s) {
604
+ const { platforms, BOARD_W, BOARD_H } = s;
608
605
  const maxPx = toFx(BOARD_W - 1);
609
606
  const surviving = [];
610
607
  for (const b of s.barrels) {
@@ -627,33 +624,25 @@ function advanceBarrels(s, rnd) {
627
624
  b.py = nextPy;
628
625
  }
629
626
  } else {
630
- // On a girder: maybe descend a ladder it's over.
631
- const lad = ladderAt(ladders, c, cell(b.py) + 1);
632
- if (lad && rnd() < ladderChance) {
627
+ // On a girder: roll along it (never down a ladder). Reaching a wall bounces
628
+ // the barrel and drops it to the girder below.
629
+ const nextPx = b.px + b.vx;
630
+ const nc = cell(nextPx);
631
+ if (nextPx < 0 || nextPx > maxPx) {
632
+ b.vx = -b.vx; // bounce off the wall and fall to the girder below
633
633
  b.falling = true;
634
- b.onLadder = true;
635
- b.px = toFx(lad.col);
636
634
  b.vy = GRAVITY;
637
635
  b.py = b.py + b.vy;
638
636
  } else {
639
- const nextPx = b.px + b.vx;
640
- const nc = cell(nextPx);
641
- if (nextPx < 0 || nextPx > maxPx) {
642
- b.vx = -b.vx; // bounce off the wall and fall to the girder below
637
+ const giHere = girderIndexAt(platforms, c, cell(b.py) + 1);
638
+ if (giHere >= 0 && nc >= 0 && nc < BOARD_W && platforms[giHere].slopeOffsets[nc] !== undefined) {
639
+ b.px = nextPx;
640
+ b.py = toFx(platforms[giHere].slopeOffsets[nc] - 1); // follow slope
641
+ } else {
642
+ b.px = nextPx; // rolled off the end → fall
643
643
  b.falling = true;
644
644
  b.vy = GRAVITY;
645
645
  b.py = b.py + b.vy;
646
- } else {
647
- const giHere = girderIndexAt(platforms, c, cell(b.py) + 1);
648
- if (giHere >= 0 && nc >= 0 && nc < BOARD_W && platforms[giHere].slopeOffsets[nc] !== undefined) {
649
- b.px = nextPx;
650
- b.py = toFx(platforms[giHere].slopeOffsets[nc] - 1); // follow slope
651
- } else {
652
- b.px = nextPx; // rolled off the end → fall
653
- b.falling = true;
654
- b.vy = GRAVITY;
655
- b.py = b.py + b.vy;
656
- }
657
646
  }
658
647
  }
659
648
  }