Give the AI a personality, chat awareness and live server state

The AI could only see three static facts about the server, so it answered
"quem tá online?" and "tá chovendo?" by insisting it had no access — true of
the model, but not of the plugin, which has all of it on hand. It also had no
tone: correct answers delivered like a manual, on a server whose whole point
is people ribbing each other.

Persona: five tones (zoeiro, amigao, seco, aldeao, neutro), switchable live
with /ia personalidade <nome>. Personality is expressed only as extra system
instructions and changes how the model talks, never what it may do. Every
persona — including the blank one — carries Persona.GUARD, which restates the
no-commands/no-server-access limits inside the persona's own frame, so a
roleplay instruction cannot read as licence to claim powers the plugin does
not grant it. The guard also forbids inventing stats, which matters now that
real numbers are being fed in. The teasing personas each state where the line
is; a test asserts every one of them does.

ChatLog: a 50-line in-memory ring of public chat, the last few lines handed to
the model so a follow-up like "quem tá reclamando aí?" has a referent. Written
from the chat event (off the main thread) and read from /ia, so it is
synchronised; a concurrency test hammers it from eight threads, because an
unsynchronised deque here would throw ConcurrentModification into a player's
answer. Recorded at MONITOR priority so what is stored is what the room saw —
a zoacao swap included — and cancelled messages are never stored. Nothing
touches disk.

ServerState: who is online with their platform, dimension, time of day,
weather, and the asker's coordinates, health, hunger and XP. Captured on the
main thread before the async call — every field reads the Bukkit world API,
which is not safe off it — and only the formatted string crosses the thread
boundary. Formatting is pure and tested, including the negative-tick case a
raw modulo would drop through every band.

Styling: Java players get a hover card with the original question and the
active persona, plus a click that pre-fills "/ia " for a follow-up.
suggestCommand, not runCommand: nothing executes without the player pressing
enter. Bedrock renders neither hover nor click, so it keeps the plain line,
built through broadcastPerPlatform like every other interactive message here.

preflight.sh: a read-only pre-restart harness. It verifies the jar opens, that
plugin.yml declares all 16 commands, that the staged jar's hash matches the
local build and is owned 1000:0, that the live config parses as YAML and
carries the keys this deploy depends on, and that a rollback jar and config
backup both exist. It never restarts anything. A missing YAML parser reports
as "not checked" rather than "invalid" — a harness that cries wolf gets
ignored.

176 tests, up from 101.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pEyCmrAYHBFgpYjwFxKxh
This commit is contained in:
marcos
2026-08-07 22:49:02 +00:00
parent b77a38b394
commit 0726ce3794
12 changed files with 1264 additions and 7 deletions
+31
View File
@@ -201,6 +201,37 @@ ia:
asteriscos, crases ou emoji, porque o chat do Minecraft não formata nada
disso.
# Tom de voz da IA. Muda só COMO ela fala, nunca o que ela pode fazer: todas
# as regras acima continuam valendo por baixo, e são repetidas junto com a
# personalidade a cada pergunta.
#
# zoeiro - veterano brincalhão, zoa o jogador e usa as estatísticas dele
# contra ele; provoca, mas responde de verdade (padrão)
# amigao - simpático e paciente, brinca pouco
# seco - curto, seco e sarcástico
# aldeao - fala como aldeão antigo e misterioso
# neutro - assistente direto, sem personalidade
#
# Troque em jogo com /ia personalidade <nome>.
personalidade: zoeiro
# Quantas linhas recentes do chat público a IA vê, para entender do que estão
# falando ("quem tá reclamando aí?"). 0 desliga. Nada vai para disco — é só
# memória, apagada em cada reinício. Teto: 50.
contexto-chat: 5
# true: manda um retrato do servidor agora junto com a pergunta — quem está
# online, dimensão, hora do dia, chuva, coordenadas/vida/fome de quem
# perguntou. É o que deixa a IA responder "quem tá online?" e "tá chovendo?".
estado-servidor: true
# true: no Java, a resposta ganha um card ao passar o mouse (pergunta original
# e personalidade) e um clique que já escreve "/ia " no chat para a próxima
# pergunta. O clique só SUGERE o comando — nada executa sozinho.
# No Bedrock a resposta é sempre texto simples: ele não renderiza nem hover
# nem clique.
estilo-rico: true
# ECONOMICO pula a consulta à wiki (resposta rápida, sem fonte).
# PRECISO consulta a wiki (mais lento, mais correto). Troque em jogo com
# /ia perfil <nome>.