Skip to content

fix(fp): the chat answers in an empty city; mayors argue, and say they are busy when no reply comes - #20

Merged
KunalSiyag merged 1 commit into
mainfrom
fp/chat-mayors
Oct 22, 2026
Merged

KunalSiyag merged 1 commit into
mainfrom
fp/chat-mayors

Conversation

@KunalSiyag

Copy link
Copy Markdown
Owner

Summary

Fixes "chat with AI not working". In a city nobody lives in yet the chat stayed silent: chatter rounds only ran with residents, and a player line had nobody to answer it. Now the rival mayors answer and argue there, and when no reply can come the chat says so instead of going quiet.

What changes in the game

  • Empty city, live replies working: the rival mayors answer each player line (the mayor the line names first, else the player's district's mayor, then a rival, up to 3 lines) and argue among themselves once a minute (3-5 lines from 2-3 mayors). Their lines skip the per-author limit, so a mayor can answer back within a round.
  • No reply possible (offline, or the live call failed): a status card says "The mayors are busy fighting right now. Chat later."
  • Live replies down with nobody living there: the card says "Live replies are slow right now." without promising neighbours who do not exist.
  • Face to face: a reply still out after 8 s of feed time gets the resident's busy line ("can't think straight with the mayors fighting") instead of a made-up offline answer, and the late reply still shows when it arrives. Busy lines are not turns, quotes or mood changes. Up to two talk calls may be out at once, and the free-text box keeps what was typed while a reply is pending.

Implementation

  • scripts/ai/chatter_minds.gd: run_mayors_round, _mayors_answer (used by reply_to_player when no residents can answer), mayor_panel, _mayors_live; validate_lines accepts extra mayors; talk() caps parallel calls at 2 and falls back to the LRU, then talk_busy (source busy).
  • scripts/ai/gmi_client.gd: TEMPERATURE and a public request_body(). A model that refuses 0.7 with an HTTP 400 naming the temperature (Kimi-K3 takes only 1) is retried once at 1 and keeps 1 for the session (temperature_of). Every failed live call prints one scrubbed GMI_FAIL role/agent on model: error line (never the prompt; a repeat of the last line is skipped), so an editor run shows why replies fell back.
  • scripts/fp/chat/chat_feature.gd: rounds run with residents or while live replies work; _run_round(mayors_only); the busy and empty-city status cards.
  • scripts/fp/chat/talk_dialog.gd: the 8 s busy line, late replies accepted, _answered gates the end-of-conversation effects.

Tests

  • fp_chat_live_test (new, 27 checks): the empty city (mayors answer, the named mayor first, rounds once a minute, failures and offline give the busy card), then a grown city with a slow talk reply (busy line at 8 s, late reply shown, the parallel cap, the conversation remembered).
  • fp_ops_test: the temperature fallback and the request body.
  • fp_chat_test unchanged and passing.

Docs

docs/fp/slices/C-chat.md (§7, the budget table, tests, risks), docs/fp/ARCHITECTURE.md (C row), README (GMI section), docs/runbooks/gmi-outage.md (the new symptoms and the temperature 400), regenerated API docs.

Validation

  • GRIDFALL_OFFLINE=1 GATE_RETRIES=1 tools/gate.sh full: PASS (42 steps: import, parse, 37 unit tests, the orbit and first-person smokes), no retries.
  • pre-commit run --all-files and python tools/checks/run_all.py: PASS, no new findings.

…y are busy when no reply comes

In a city nobody lives in yet the chat stayed silent: rounds only ran
with residents, and a player line had nobody to answer it. Now the
rival mayors answer the player there (the mayor the line names first,
else the player's district's, then a rival) and argue among themselves
once a minute while live replies work. A player line nobody can answer,
offline or when the live call fails, gets a status card: "The mayors
are busy fighting right now. Chat later." The live-down card no longer
promises neighbours who do not exist.

Face to face, a reply still out after 8 s of feed time now gets the
resident's busy line instead of a made-up offline answer, and the late
reply still shows when it comes. Busy lines are not turns, quotes or
mood changes. Up to two talk calls may be out at once, and the free-
text line keeps what was typed while a reply is pending.

GmiClient retries a call once at temperature 1 when the model refuses
0.7 with an HTTP 400 (Kimi-K3 takes only 1) and keeps 1 for that model
for the session. Every failed live call prints one scrubbed
"GMI_FAIL role/agent on model: error" line (never the prompt), so a run
from the editor shows why replies fell back.

fp_chat_live_test (new) covers the empty city, the mayors' answers and
rounds, the busy card offline and on failure, and the slow face-to-face
reply; fp_ops_test covers the temperature fallback and the request
body. C-chat, ARCHITECTURE, README, the GMI outage runbook and the API
docs describe it.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

Automated review

No new findings on the 13 changed files (gdlint, complexity, TODO policy, dead code).

Run python3 tools/checks/run_all.py locally for the full set of checks.

@KunalSiyag
KunalSiyag merged commit ffac993 into main Oct 22, 2026
8 checks passed
@KunalSiyag
KunalSiyag deleted the fp/chat-mayors branch October 22, 2026 14:58
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