i18n: per-player EN/PT via Adventure GlobalTranslator #1
@@ -24,9 +24,11 @@ All player-facing text is Portuguese (pt-BR).
|
|||||||
| `enquete` | `/enquete Pergunta \| A \| B` — clickable voting with a live tally on the boss bar. |
|
| `enquete` | `/enquete Pergunta \| A \| B` — clickable voting with a live tally on the boss bar. |
|
||||||
| `ranking` | `/ranking mineracao` and friends. Covers **offline players too**. |
|
| `ranking` | `/ranking mineracao` and friends. Covers **offline players too**. |
|
||||||
| `marcos` | Announces round milestones — 100 km walked, 24 hours played — the first time someone crosses one. |
|
| `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. |
|
| `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`. `/mortes` lists your last 10 deaths with the cause and where each happened (`mortes.yml`) — your own only, since where someone died is where their stuff is. |
|
||||||
| `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). |
|
| `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). |
|
||||||
| `notas` | Notes in chat. `/save` pins where you are; `/nota add <texto>` writes a private one (only you see it, everyone may write); `/nota publica <texto>` writes one everyone reads, and needs `canalhandia.nota.publica` (default op). Every note stores its coordinates — click-to-copy on Java. Persisted to `notas.yml`. **No teleport**: nothing here touches gameplay. |
|
| `notas` | Notes in chat. `/save` pins where you are; `/nota add <texto>` writes a private one (only you see it, everyone may write); `/nota publica <texto>` writes one everyone reads, and needs `canalhandia.nota.publica` (default op). Every note stores its coordinates — click-to-copy on Java. Persisted to `notas.yml`. **No teleport**: nothing here touches gameplay. |
|
||||||
|
| `recados` | `/recado <jogador> <texto>` — a line for someone who is offline, delivered on their next join. `/recados` shows how many of yours are still unread. Persisted to `recados.yml`. |
|
||||||
|
| `conquistas` | Named achievements beyond the numeric milestones: "Casca Grossa" (50h, under 10 deaths), "Turista" (100h, barely mined), "Imortal às Avessas". `/conquistas` lists them all and marks yours. Persisted to `conquistas.yml`. |
|
||||||
| `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. |
|
| `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>`
|
Toggle any of them: `/canalhandia modulo <nome> <on|off>`
|
||||||
@@ -166,6 +168,11 @@ Player-facing:
|
|||||||
/nota buscar <texto> procura no texto das anotações
|
/nota buscar <texto> procura no texto das anotações
|
||||||
/nota ver <n> mostra uma anotação inteira
|
/nota ver <n> mostra uma anotação inteira
|
||||||
/nota remover <n> apaga uma anotação sua
|
/nota remover <n> apaga uma anotação sua
|
||||||
|
/recado <jogador> <texto> recado entregue quando a pessoa entrar
|
||||||
|
/recados quantos recados seus ainda não foram lidos
|
||||||
|
/mortes suas últimas mortes, com causa e lugar
|
||||||
|
/conquistas conquistas, com as suas marcadas
|
||||||
|
/ranking semanal [métrica] só o que foi ganho nesta semana
|
||||||
```
|
```
|
||||||
|
|
||||||
Admin (`canalhandia.admin`):
|
Admin (`canalhandia.admin`):
|
||||||
@@ -182,6 +189,8 @@ Admin (`canalhandia.admin`):
|
|||||||
/canalhandia zoacao limpar volta para as frases padrão
|
/canalhandia zoacao limpar volta para as frases padrão
|
||||||
/ia personalidade lista as personalidades da IA
|
/ia personalidade lista as personalidades da IA
|
||||||
/ia personalidade <nome> zoeiro | amigao | seco | aldeao | neutro
|
/ia personalidade <nome> zoeiro | amigao | seco | aldeao | neutro
|
||||||
|
/ia eventos <on|off> IA comenta mortes seguidas sozinha
|
||||||
|
/ia saudacao <on|off> IA dá as boas-vindas de quem entra
|
||||||
/canalhandia reload
|
/canalhandia reload
|
||||||
/curiosidade modo <entrada|intervalo|ambos|manual>
|
/curiosidade modo <entrada|intervalo|ambos|manual>
|
||||||
/curiosidade intervalo <min> intervalo do modo temporizado
|
/curiosidade intervalo <min> intervalo do modo temporizado
|
||||||
@@ -211,6 +220,7 @@ survive a restart.
|
|||||||
| `canalhandia.isento` | nobody | never be the subject |
|
| `canalhandia.isento` | nobody | never be the subject |
|
||||||
| `canalhandia.nota` | everyone | `/save` and private notes |
|
| `canalhandia.nota` | everyone | `/save` and private notes |
|
||||||
| `canalhandia.nota.publica` | op | write notes everyone can read |
|
| `canalhandia.nota.publica` | op | write notes everyone can read |
|
||||||
|
| `canalhandia.recado` | everyone | leave messages for other players |
|
||||||
| `canalhandia.ia` | op | `/ia` (public question, broadcast to chat) |
|
| `canalhandia.ia` | op | `/ia` (public question, broadcast to chat) |
|
||||||
| `canalhandia.ia.privado` | op | `/iap` (private question, answer only to the asker) |
|
| `canalhandia.ia.privado` | op | `/iap` (private question, answer only to the asker) |
|
||||||
| `canalhandia.ia.corrigir` | op | `/ia corrigir <resposta>` — register a correction for the last answer |
|
| `canalhandia.ia.corrigir` | op | `/ia corrigir <resposta>` — register a correction for the last answer |
|
||||||
@@ -289,6 +299,84 @@ text.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Weekly rankings
|
||||||
|
|
||||||
|
`/ranking semanal [métrica]` shows only what was **gained since the start of the
|
||||||
|
week**. On a server with three regulars an all-time board is decided by whoever
|
||||||
|
started first and then stops being a contest; subtracting a weekly baseline
|
||||||
|
makes it one again.
|
||||||
|
|
||||||
|
Rotation is time-based and idempotent: the snapshot carries the timestamp it was
|
||||||
|
taken at and is replaced only once a week has actually elapsed. **A restart
|
||||||
|
never rotates it** — a server that restarts nightly would otherwise reset the
|
||||||
|
week every day, which is the failure this design exists to avoid.
|
||||||
|
|
||||||
|
Players who did not move are dropped (the point is who is playing *this* week).
|
||||||
|
Someone missing from the baseline counts their whole value, having joined during
|
||||||
|
the week. A negative difference is dropped rather than shown: statistics only go
|
||||||
|
up, so a negative means a stale baseline or a reset stats file, not a result.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Spontaneous AI lines
|
||||||
|
|
||||||
|
Off by default (`ia.comentar-eventos`, `ia.saudacao`). The persona can comment
|
||||||
|
on a run of deaths and greet players as they join, using their own numbers. Both
|
||||||
|
are opt-in because a chatty AI nobody asked for is the fastest way to make
|
||||||
|
players hate the feature.
|
||||||
|
|
||||||
|
`/ia eventos <on|off>` and `/ia saudacao <on|off>` toggle them live.
|
||||||
|
|
||||||
|
### Why the budget is strict
|
||||||
|
|
||||||
|
A player question is self-limiting — someone chose to spend it. A line the AI
|
||||||
|
decides to make on its own is not, and it costs money every time. `Budget`
|
||||||
|
enforces three limits, **all** of which must pass:
|
||||||
|
|
||||||
|
| Limit | Default | Why |
|
||||||
|
|---|---|---|
|
||||||
|
| gap between any two lines | 10 min | stops chat spam |
|
||||||
|
| daily cap, separate from `/ia`'s | 20 | protects the spend |
|
||||||
|
| per-subject cooldown | 30 min | one unlucky player is not narrated all evening |
|
||||||
|
|
||||||
|
`allows()` does not spend, so a caller that decides not to fire (nobody online,
|
||||||
|
the model returned nothing) has burned nothing. `saySomething` spends **up
|
||||||
|
front** rather than on success: two events landing in the same tick would
|
||||||
|
otherwise both pass `allows()` and fire together — the exact double-message the
|
||||||
|
gap exists to prevent.
|
||||||
|
|
||||||
|
A death streak decays after 15 minutes. Three deaths across an evening is not a
|
||||||
|
streak; three in ten minutes is. Spontaneous lines are silent on failure —
|
||||||
|
nobody asked for it, so nobody should see it fail.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes on the BlueMap web map
|
||||||
|
|
||||||
|
Public notes are drawn as markers on BlueMap (`notas.no-mapa`, default on).
|
||||||
|
Notes already carry a world and coordinates and the server already runs BlueMap,
|
||||||
|
so this joins the two. **Private notes are never drawn, at any setting.**
|
||||||
|
|
||||||
|
BlueMap is an **optional** dependency. `BlueMapBridge` is the only class that
|
||||||
|
touches its API, and every entry point catches `NoClassDefFoundError` as well as
|
||||||
|
`Exception` — the failure mode of a missing optional dependency is a linkage
|
||||||
|
error, not an exception — so a server without BlueMap logs one fine-level line
|
||||||
|
and carries on.
|
||||||
|
|
||||||
|
The dependency is `provided` scope because BlueMap ships those classes itself; a
|
||||||
|
second copy inside this jar would shadow them and break the real plugin.
|
||||||
|
`preflight.sh` fails if that scope is ever dropped.
|
||||||
|
|
||||||
|
Markers are **rebuilt**, not incrementally patched: BlueMap discards everything
|
||||||
|
when it unloads and expects addons to re-create markers on its enable callback,
|
||||||
|
and a full rebuild of a tiny list cannot drift out of sync the way a missed
|
||||||
|
delete would. Notes are matched to the map that renders their world, or a Nether
|
||||||
|
note would be drawn at the same numeric coordinates in the overworld, pointing
|
||||||
|
at nothing. Note text is player-written and lands in a web page, so it is
|
||||||
|
HTML-escaped.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## IA (`/ia`)
|
## IA (`/ia`)
|
||||||
|
|
||||||
Chat Q&A backed by an OpenAI-compatible endpoint (default MiniMax). Gated to
|
Chat Q&A backed by an OpenAI-compatible endpoint (default MiniMax). Gated to
|
||||||
@@ -501,6 +589,12 @@ here is a crash-on-boot you get to fix while the server is still up.
|
|||||||
| `OfflineStats.java` | Reads stats JSON for offline players (rankings + the asker's stat summary for the IA) |
|
| `OfflineStats.java` | Reads stats JSON for offline players (rankings + the asker's stat summary for the IA) |
|
||||||
| `RankingMetric.java` | Leaderboard columns and their formatting |
|
| `RankingMetric.java` | Leaderboard columns and their formatting |
|
||||||
| `DeathFlavor.java` | Comic pt-BR verb phrases for each death cause (used by the `mortes` module) |
|
| `DeathFlavor.java` | Comic pt-BR verb phrases for each death cause (used by the `mortes` module) |
|
||||||
|
| `Mail.java` | Offline messages and their YAML storage |
|
||||||
|
| `DeathLog.java` | Recent deaths per player, for `/mortes` |
|
||||||
|
| `Achievement.java` / `Achievements.java` | The named-achievement catalogue (pure) and its award bookkeeping |
|
||||||
|
| `WeeklyStats.java` | Weekly ranking baseline and the delta arithmetic (pure) |
|
||||||
|
| `Budget.java` | The three-limit gate on spontaneous AI lines (pure) |
|
||||||
|
| `BlueMapBridge.java` | Public notes as markers on the BlueMap web map (optional dependency) |
|
||||||
| `Note.java` / `Notes.java` | One note (scope, text, place, visibility rules) and its YAML storage |
|
| `Note.java` / `Notes.java` | One note (scope, text, place, visibility rules) and its YAML storage |
|
||||||
| `Persona.java` | The AI's five tones, each carrying the safety guard |
|
| `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 |
|
| `ChatLog.java` | Bounded, thread-safe ring of recent public chat for the AI |
|
||||||
|
|||||||
Reference in New Issue
Block a user