i18n: per-player EN/PT via Adventure GlobalTranslator #1
@@ -26,7 +26,7 @@ All player-facing text is Portuguese (pt-BR).
|
||||
| `marcos` | Announces round milestones — 100 km walked, 24 hours played — the first time someone crosses one. |
|
||||
| `mortes` | Replaces each death message with a comic pt-BR line (cause-based flavor + a death counter) and sends the death coordinates **privately** to the dead player on respawn (the death screen swallows chat sent during the event), so they can run back to their dropped items. Respects `keepInventory`. No storage, no command. |
|
||||
| `zoacao` | A chat message matching the trigger (a pattern + a match mode) is swapped for a random line from `zoacao.mensagens` — a chat gag. The player's name still prefixes it. Default: a bare `f`/`F` (trimmed) → a random gag line. Match modes: `igual` (equals), `contem` (contains), `comeca` (starts with), `termina` (ends with), `regex`. The mode, the pattern, and the message list are all editable in-game with `/canalhandia zoacao ...`. Pure chat swap; the `luto` tribute is unaffected (paying respects still needs the `[F]` button or `/f`). Affects Bedrock chat too (it's a chat event, not a click). |
|
||||
| `ia` | `/ia <pergunta>` asks an OpenAI-compatible model in chat. Optional wiki grounding, per-player memory, operator corrections. |
|
||||
| `ia` | `/ia <pergunta>` asks an OpenAI-compatible model in chat. Has a personality (`zoeiro` by default — it will tease you), sees the last few chat lines and the live server state, and grounds answers in the asker's real stats. Optional wiki lookup, per-player memory, operator corrections. |
|
||||
|
||||
Toggle any of them: `/canalhandia modulo <nome> <on|off>`
|
||||
|
||||
@@ -170,6 +170,8 @@ Admin (`canalhandia.admin`):
|
||||
/canalhandia zoacao adicionar <frase> adiciona uma frase de zoação
|
||||
/canalhandia zoacao remover <n|texto> remove uma frase de zoação
|
||||
/canalhandia zoacao limpar volta para as frases padrão
|
||||
/ia personalidade lista as personalidades da IA
|
||||
/ia personalidade <nome> zoeiro | amigao | seco | aldeao | neutro
|
||||
/canalhandia reload
|
||||
/curiosidade modo <entrada|intervalo|ambos|manual>
|
||||
/curiosidade intervalo <min> intervalo do modo temporizado
|
||||
@@ -227,6 +229,8 @@ executed command.
|
||||
|---|---|
|
||||
| `/ia <pergunta>` | Asks the model. Public by default — the question and answer broadcast. Needs `canalhandia.ia`. |
|
||||
| `/iap <pergunta>` | Asks privately — the answer goes only to the asker. Needs `canalhandia.ia.privado`. |
|
||||
| `/ia personalidade` | Lists the tones and marks the active one. Needs `canalhandia.ia.perfil`. |
|
||||
| `/ia personalidade <nome>` | Switches tone live: `zoeiro` (default), `amigao`, `seco`, `aldeao`, `neutro`. |
|
||||
| `/ia perfil <economico\|preciso>` | Switches profile live. `ECONOMICO` skips the wiki (fast); `PRECISO` consults the Minecraft Wiki (slower, grounded). Needs `canalhandia.ia.perfil`. |
|
||||
| `/ia corrigir <resposta correta>` | Records a correction for the last answered question. Future similar questions get it as context — the cheap alternative to fine-tuning. Needs `canalhandia.ia.corrigir`. |
|
||||
| `/ia feedback ruim` | Flags the last answer wrong (in-memory counter shown in `/canalhandia status`). |
|
||||
@@ -236,6 +240,57 @@ Subcommands only hijack when their second token is one they act on (a known
|
||||
profile key, or `ruim`), so `/ia perfil do servidor` falls through and is asked.
|
||||
`corrigir` stays greedy — a correction always reads the rest of the line.
|
||||
|
||||
### Personality
|
||||
|
||||
`ia.personalidade` picks the tone. It is expressed purely as extra system
|
||||
instructions appended after the base ones, so it changes **how** the model
|
||||
talks and never **what it may do**.
|
||||
|
||||
| Persona | Tone |
|
||||
|---|---|
|
||||
| `zoeiro` | Default. A grumpy server veteran: teases the asker, turns their own stats against them ("você já morreu 47 vezes e vem me perguntar sobre lava?"), but answers the question for real. |
|
||||
| `amigao` | Warm and patient, jokes rarely. For servers with new players. |
|
||||
| `seco` | Deadpan, one or two sentences, no exclamation marks. |
|
||||
| `aldeao` | In character as an ancient villager. Flavour only; still answers. |
|
||||
| `neutro` | No personality — the pre-persona behaviour. |
|
||||
|
||||
Every persona, `neutro` included, carries `Persona.GUARD`, which restates the
|
||||
limits inside the persona's own frame: still no server/terminal/file access,
|
||||
still no commands, no inventing stats, no leaking the prompt. That is the
|
||||
layer that stops "you are a grumpy veteran" from reading as licence to claim
|
||||
powers the plugin never grants. Each teasing persona also states where the
|
||||
line is (no real insults, nothing about family, appearance, race, religion,
|
||||
sexuality or money; drop the ribbing if the player asks). Tests assert both
|
||||
properties hold for every persona, so adding a new one cannot quietly skip them.
|
||||
|
||||
Switch live with `/ia personalidade <nome>` — read per-question, no restart.
|
||||
|
||||
### Chat and world awareness
|
||||
|
||||
- **Recent chat** (`contexto-chat`, default 5, 0 disables): the last N public
|
||||
chat lines are sent as context, so the AI can follow what the room is talking
|
||||
about. Held in a bounded in-memory ring (50 lines max, 200 chars per line);
|
||||
nothing is written to disk and a restart starts it empty. Recorded at
|
||||
`MONITOR` priority with `ignoreCancelled`, so what it stores is what players
|
||||
actually saw — a `zoacao` swap included — and a cancelled message is never
|
||||
stored.
|
||||
- **Live server state** (`estado-servidor`, default on): who is online and on
|
||||
which platform, the asker's dimension, in-game time of day, weather, and
|
||||
their coordinates, health, hunger and XP level. This is what lets the AI
|
||||
answer "quem tá online?" or "tá chovendo?" instead of insisting it has no
|
||||
access. Captured on the main thread before the async call — every field
|
||||
reads the Bukkit world API, which is not safe off it — so only the formatted
|
||||
string crosses the thread boundary.
|
||||
|
||||
### Answer styling
|
||||
|
||||
With `estilo-rico` on (default), Java players get the answer with a hover card
|
||||
showing the original question and the active persona, plus a click that
|
||||
pre-fills `/ia ` for a follow-up. The click uses `suggestCommand`, never
|
||||
`runCommand`: nothing executes without the player pressing enter. Bedrock
|
||||
renders neither hover nor click, so it always gets the plain line — built via
|
||||
`broadcastPerPlatform`, like every other interactive message here.
|
||||
|
||||
### Profile
|
||||
|
||||
`ECONOMICO` skips the wiki round trip — fast, ungrounded. `PRECISO` runs a
|
||||
@@ -311,9 +366,42 @@ path for a new jar — `/canalhandia reload` only re-reads `config.yml`.
|
||||
```bash
|
||||
POD=$(microk8s kubectl get pod -n minecraft -l app=crafty-controller -o name | head -1)
|
||||
SRV=/crafty/servers/6e39a8b2-300b-42d6-8139-f397c23e461b
|
||||
microk8s kubectl exec ${POD#pod/} -n minecraft -- \
|
||||
cp $SRV/plugins/Canalhandia-1.0.0.jar $SRV/plugins/Canalhandia-1.0.0.jar.bak-$(date +%F)
|
||||
microk8s kubectl cp target/Canalhandia-1.0.0.jar minecraft/${POD#pod/}:$SRV/plugins/Canalhandia-1.0.0.jar
|
||||
# The JVM runs as uid 1000 / gid 0; a root-owned jar is one it cannot read,
|
||||
# and the failure looks exactly like "the plugin just did not load".
|
||||
microk8s kubectl exec ${POD#pod/} -n minecraft -- chown 1000:0 $SRV/plugins/Canalhandia-1.0.0.jar
|
||||
```
|
||||
|
||||
### Pre-flight
|
||||
|
||||
`./preflight.sh [jar]` checks a staged deploy **before** anyone restarts
|
||||
anything. Every check is read-only; it never restarts the server, never writes
|
||||
to `plugins/`, and never touches the world.
|
||||
|
||||
```
|
||||
$ ./preflight.sh
|
||||
1. Local build jar opens, plugin.yml present, all 16 commands declared,
|
||||
config.yml bundled
|
||||
2. Tests surefire totals, 0 failures
|
||||
3. Cluster crafty pod found, plugins directory reachable
|
||||
4. Staged jar hash matches the local build, owned 1000:0, a rollback
|
||||
.bak jar exists
|
||||
5. Live config parses as YAML, carries the keys this deploy needs, has a
|
||||
.bak to roll back to
|
||||
6. Health the log is readable and free of recent ERROR lines
|
||||
|
||||
PRE-FLIGHT CLEAN — safe to restart.
|
||||
```
|
||||
|
||||
It exits non-zero on any failure. A missing YAML parser reports as *not
|
||||
checked* rather than *invalid*: a harness that cries wolf is one people learn
|
||||
to ignore.
|
||||
|
||||
Because the plugin is staged dormant (copied in, not restarted), a red line
|
||||
here is a crash-on-boot you get to fix while the server is still up.
|
||||
|
||||
---
|
||||
|
||||
## Source layout
|
||||
@@ -334,6 +422,9 @@ microk8s kubectl cp target/Canalhandia-1.0.0.jar minecraft/${POD#pod/}:$SRV/plug
|
||||
| `OfflineStats.java` | Reads stats JSON for offline players (rankings + the asker's stat summary for the IA) |
|
||||
| `RankingMetric.java` | Leaderboard columns and their formatting |
|
||||
| `DeathFlavor.java` | Comic pt-BR verb phrases for each death cause (used by the `mortes` module) |
|
||||
| `Persona.java` | The AI's five tones, each carrying the safety guard |
|
||||
| `ChatLog.java` | Bounded, thread-safe ring of recent public chat for the AI |
|
||||
| `ServerState.java` | Main-thread snapshot of the live world for the AI |
|
||||
| `Msg.java` | Shared chat formatting and pt-BR number/duration formatting |
|
||||
|
||||
### Adding a curiosity
|
||||
|
||||
Reference in New Issue
Block a user