Skip to content

Stop a stalling bot deferring its own thinking forever - #263

Merged
saworbit merged 1 commit into
mainfrom
ai-tick-livelock
Sep 5, 2026
Merged

Stop a stalling bot deferring its own thinking forever#263
saworbit merged 1 commit into
mainfrom
ai-tick-livelock

Conversation

@saworbit

@saworbit saworbit commented Sep 5, 2026

Copy link
Copy Markdown
Owner

The other half of #257, and it is a livelock rather than the goal starvation the issue title claimed.

Stall recovery clears the goal and pushes ar_nextai out 1.5 s so the bot wanders before re-planning. It re-armed that deferral on every stall. A bot stalling more often than every 1.5 s therefore pushes its own AI tick permanently out of reach: it never re-picks a goal, never routes, and the wander meant to free it is the thing keeping it blind.

The edict dump named it

Romero on dm2, motionless at 2352.5 -103.1 56.0 for 65 s, sampled twice 28 seconds apart:

field t27 t55
ar_goalstart 13.9 13.9 PickGoal had not run since t13.9
ar_nextai 27.2 55.6 advancing, but from deferrals only
ar_stalls 15.0 53.0 38 stalls in 28 s, 1.4 a second
ar_wanderturn 26.9 55.8 the wander was running the whole time

ar_goal, ar_node, ar_mode, ar_enemy, ar_failstreak and ar_traptime all absent, so all default. Every branch that could have re-goaled him was reachable. None ran, because the tick they sit inside never fired.

The fix

One condition: only defer if we are not already waiting. One stall buys one 1.5 s pause; later stalls inside that window cannot extend it, so the tick always lands.

Ladder, dm2, three pairs

Goals is the metric the mechanism predicts, and every fix tape beats every control tape:

goals worst freeze cells stalls
control 78, 86, 89 22.3s 120, 124, 114 77, 57, 67
fix 100, 96, 91 8.2s 122, 124, 123 41, 69, 78

dm4: 66 cells, 6 stalls, 152 goals, no freezes. e1m2 co-op: 45 cells, no freezes, no water pin.

This is the shared stall path, not co-op gated, so it touches every bot on every map. Hence the wider net.

Method note

Two conclusions in this hunt were drawn from a field list that head -40 had silently truncated. ar_traptime and ar_failstreak were absent rather than unchecked, and only an explicit grep settled it. When the dump is the evidence, read all of it.

Refs #257

🤖 Generated with Claude Code

The other half of #257, and it is a livelock rather than the goal
starvation the issue title claimed.

Stall recovery clears the goal and pushes ar_nextai out 1.5 s so the
bot wanders before re-planning. It re-armed that deferral on EVERY
stall. A bot stalling more often than every 1.5 s therefore pushes its
own AI tick permanently out of reach: it never re-picks a goal, never
routes, and the wander meant to free it is the thing keeping it blind.

The edict dump named it. Romero on dm2, motionless at
'2352.5 -103.1 56.0' for 65 s, sampled twice 28 s apart:

  ar_goalstart   13.9  ->  13.9   PickGoal had not run since t13.9
  ar_nextai      27.2  ->  55.6   advancing, but from deferrals only
  ar_stalls      15.0  ->  53.0   38 stalls in 28 s, 1.4 a second
  ar_wanderturn  26.9  ->  55.8   the wander was running the whole time
  ar_goal, ar_node, ar_mode, ar_enemy, ar_failstreak, ar_traptime
                                  all absent, so all default

Every branch that could have re-goaled him was reachable. None ran,
because the tick they sit inside never fired.

One condition: only defer if we are not already waiting. One stall
buys one 1.5 s pause, later stalls inside that window cannot extend
it, so the tick always lands.

LADDER, dm2, three pairs. Goals is the metric the mechanism predicts,
and every fix tape beats every control tape:

  goals         78, 86, 89   ->  100, 96, 91
  worst freeze  22.3s        ->  8.2s
  cells         120,124,114  ->  122,124,123
  stalls        77, 57, 67   ->  41, 69, 78

dm4 66 cells, 6 stalls, 152 goals, no freezes. e1m2 co-op 45 cells,
no freezes, no water pin.

This is the shared stall path, not co-op gated, so it touches every
bot on every map. Hence the wider net.

METHOD NOTE. Two conclusions in this hunt were drawn from a field
list that head -40 had silently truncated; ar_traptime and
ar_failstreak were absent rather than unchecked, and only an explicit
grep settled it. When the dump is the evidence, read all of it.

Refs #257

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T06:54:42.246908Z 3770454 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3770454c6f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/argus.qc
Comment on lines +7133 to +7134
if (time > self.ar_nextai)
self.ar_nextai = time + 1.5;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the initial stall-recovery delay

Whenever a second consecutive stall reaches this branch, this condition can never be true: earlier in the same Argus_AI invocation, the periodic-maintenance block either observes time > self.ar_nextai and resets it to time + 0.2, or leaves an existing future deadline unchanged. Consequently, the new assignment is unreachable, so every cleared goal can be reconsidered within 0.2 seconds instead of receiving the intended one-time 1.5-second wander period, restoring the corner-wedging behavior described immediately above. Distinguishing a normal AI deadline from an already-active recovery pause requires separate state or a comparison that accounts for the normal 0.2-second deadline.

Useful? React with 👍 / 👎.

@saworbit
saworbit merged commit 8d752e4 into main Sep 5, 2026
3 checks passed
@saworbit
saworbit deleted the ai-tick-livelock branch September 5, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant