promotional bannermobile promotional banner

Arcadia Games

A server-side minigames mod featuring

File Details

arcadia_games-1.3.0

  • R
  • Jun 9, 2026
  • 240.07 KB
  • 11
  • 1.21.1
  • NeoForge

File Name

arcadia_games-1.3.0.jar

Supported Versions

  • 1.21.1

Curse Maven Snippet

NeoForge

implementation "curse.maven:arcadia-games-1507012:8221624"
Curse Maven does not yet support mods that have disabled 3rd party sharing

Learn more about Curse Maven

## [1.3.0] - 2026-06-02 (latest)

### Added

- **Bilingual quiz with 181 fact-checked questions** — The Quiz minigame was rewritten from 30 hardcoded French questions to a verified bilingual bank (`QuizQuestions.ALL`, 181 entries: geography, history, science, arts, sport, nature and Minecraft). Each question carries a FR and EN wording, a canonical answer and accepted answer variants (synonyms, FR/EN spellings, numeric word forms). The displayed wording follows the server language; any matching variant scores. Sources were web-verified during generation.
- **Quiz answer matching with accent folding and variants** — Player input is now NFD-normalized (accents folded to base letters) and matched against the canonical answer plus all variants, so both accented and unaccented spellings and common synonyms are accepted.
- **`Component`-based broadcast/send overloads** — `Minigame` gained `broadcastMessage(Component)` / `sendMessage(player, Component)` so item, block and mob names can be embedded as `Component.translatable(...)` and rendered in each client's own locale.

### Fixed

- **Race to Position was unplayable ~2/3 of the time** — The target dimension was picked at random from Overworld/Nether/End; Nether and End targets are effectively unreachable within the timer, so most rounds ended with no finishers. The target dimension is now constrained to dimensions participants currently occupy. The target Y is resolved via an O(1) heightmap lookup instead of a full column scan, fixing both an unreachable-target edge case and a per-game chunk-scan hitch.
- **Chat-based games could corrupt state from the network thread** — `ChatMixin` ran `onPlayerChat` on the Netty thread, racing the server tick over non-thread-safe score/round maps (CME risk). Chat handling is now marshaled onto the main server thread via `server.execute(...)`, fixing all chat-based games at once.
- **PvP Arena credited premature/multiple kills** — Elimination was tested as `getHealth() - damage <= 4` inside `LivingDamageEvent.Post`, where health is already reduced, double-subtracting the damage. The victim could be credited several kills before respawning. Now tests the post-hit health directly and eliminates synchronously so the victim is flagged invulnerable immediately.
- **Echo Chamber stalled with fewer than 3 players** — A round only closed after 3 distinct echoes and had no timeout, so small lobbies froze for the rest of the game. Added a 20s per-round timeout and a close condition scaled to the participant count.
- **Quiz, Word Guess, Speed Typing and Anagram were monolingual** — Quiz/Word Guess/Speed Typing shipped French-only content and Anagram English-only, so the other locale was unplayable. All four now select a language-appropriate content bank from the server language.
- **Word Guess rejected correctly accented answers** — Answer matching stripped accents as unknown characters (`é` removed, not folded), so the natural spelling failed. Both sides are now NFD-normalized before comparison.
- **Speed Typing rejected entries with stray internal spacing** — Matching collapsed only leading/trailing whitespace; internal double spaces now collapse on both sides.
- **Zombie Pinata over-credited damage past its virtual HP** — Late hits in the same tick were counted beyond `maxVirtualHp`, distorting the leaderboard. Credited damage is now capped to the remaining pool and the game ends immediately when depleted. Removed the unreachable real-HP re-heal branch (the entity is invulnerable; combat is virtual).
- **Highest Point rewarded starting elevation, not climbing** — Score was absolute world Y, favouring players who spawned on tall terrain. Score is now the climb delta (max reached minus start Y), so everyone starts at 0. The start teleport uses a heightmap lookup and no longer silently fails to reposition.
- **Farming scored immature crops** — Breaking age-based crops at any stage scored a point. Age-based crops must now be at max age (`CropBlock.isMaxAge`) to count.
- **Block Placing could be farmed by place/break/replace** — Each placement scored unconditionally. Each world position is now counted once per player, and creative-mode placements/breaks are ignored.
- **Block breaks counted even when cancelled / in creative** — `onBlockBreak` now ignores cancelled events and creative players, so protection mods and creative farming no longer award points.

### Changed

- **Infection now reads its config keys** — `infection_range_blocks`, `infection_check_interval_ticks` and `infection_points_per_infection` were defined but ignored (hardcoded constants). They are now applied at game start, and patient zero reliably receives an infection score.
- **Item, block, mob and wool-color names are now client-localized** — Color Match, Drop Item, Treasure Hunt, Craft Race, Mob Kill and Photo Safari previously displayed hardcoded single-language names; they now use `Component.translatable(...)` so each player sees the name in their own client locale.
- **Quiz timing reads config** — `quiz_question_interval_seconds` / `quiz_question_timeout_seconds` are now honoured instead of hardcoded constants.

### Performance

- **Config defaults built once** — `ArcadiaConfig` now resolves the ~120-entry defaults map and blocked-commands list from a single static `DEFAULTS` instead of rebuilding it on every getter fallback.
- **Jump Master throttled** — Jump detection sampled every server tick; it now samples every 2 ticks (still catches every jump) and caches the vertical velocity read.
- **Heightmap lookups replace column scans** — Race to Position and Highest Point now resolve ground Y via the heightmap (O(1)) instead of scanning the full block column at game start.

### Ajouts

- **Quiz bilingue avec 181 questions vérifiées** — Le mini-jeu Quiz passe de 30 questions françaises codées en dur à une banque bilingue vérifiée (`QuizQuestions.ALL`, 181 entrées : géographie, histoire, sciences, arts, sport, nature et Minecraft). Chaque question a une formulation FR et EN, une réponse canonique et des variantes acceptées (synonymes, orthographes FR/EN, nombres en lettres). La formulation affichée suit la langue du serveur ; toute variante correcte marque. Sources vérifiées sur le web lors de la génération.
- **Reconnaissance des réponses avec gestion des accents et variantes** — La saisie du joueur est normalisée (NFD, accents repliés) et comparée à la réponse canonique et à toutes ses variantes ; les orthographes avec ou sans accents et les synonymes courants sont acceptés.
- **Surcharges `Component` pour broadcast/send** — `Minigame` gagne `broadcastMessage(Component)` / `sendMessage(joueur, Component)` pour intégrer des noms d'items/blocs/mobs via `Component.translatable(...)` rendus dans la langue de chaque client.

### Correctifs

- **Course vers la Position injouable ~2/3 du temps** — La dimension cible était tirée au hasard parmi Overworld/Nether/End ; le Nether et l'End sont inatteignables dans le temps imparti, donc la plupart des parties finissaient sans arrivant. La cible est désormais limitée aux dimensions occupées par les participants. Le Y cible est résolu via le heightmap (O(1)) au lieu d'un scan de colonne, corrigeant à la fois un cas de cible inatteignable et un à-coup serveur au lancement.
- **Les jeux de chat pouvaient corrompre l'état depuis le thread réseau** — `ChatMixin` exécutait `onPlayerChat` sur le thread Netty, en concurrence avec le tick serveur sur des Maps non thread-safe (risque de CME). Le traitement du chat est désormais renvoyé sur le thread serveur principal via `server.execute(...)`, corrigeant tous les jeux de chat d'un coup.
- **L'Arène PvP créditait des éliminations prématurées/multiples** — L'élimination était testée par `getHealth() - damage <= 4` dans `LivingDamageEvent.Post`, où les PV sont déjà réduits, soustrayant deux fois les dégâts. La victime pouvait être créditée plusieurs fois avant de réapparaître. On teste maintenant directement les PV post-coup et on élimine de façon synchrone pour marquer la victime invulnérable immédiatement.
- **La Chambre d'Écho se bloquait à moins de 3 joueurs** — Un round ne se fermait qu'après 3 échos distincts, sans délai d'expiration, gelant les petites parties. Ajout d'un timeout de 20s par round et d'une condition de fin adaptée au nombre de participants.
- **Quiz, Devinez le Mot, Frappe Rapide et Anagramme étaient monolingues** — Quiz/Devinez le Mot/Frappe Rapide n'avaient que du contenu français et Anagramme que de l'anglais ; l'autre langue était injouable. Les quatre choisissent désormais une banque de contenu adaptée à la langue du serveur.
- **Devinez le Mot rejetait les réponses correctement accentuées** — La comparaison supprimait les accents comme caractères inconnus (`é` retiré, non replié), faisant échouer l'orthographe naturelle. Les deux côtés sont désormais normalisés (NFD) avant comparaison.
- **Frappe Rapide rejetait les saisies avec espaces internes parasites** — Seuls les espaces de début/fin étaient gérés ; les doubles espaces internes sont désormais réduits des deux côtés.
- **Zombie Piñata sur-créditait les dégâts au-delà de ses PV virtuels** — Les coups tardifs du même tick étaient comptés au-delà de `maxVirtualHp`, faussant le classement. Les dégâts crédités sont plafonnés au reste du pool et la partie se termine dès épuisement. Suppression de la branche de re-soin inatteignable (l'entité est invulnérable ; le combat est virtuel).
- **Sommet du Monde récompensait l'altitude de départ, pas l'escalade** — Le score était le Y absolu, favorisant ceux qui apparaissaient sur un terrain élevé. Le score est désormais le delta d'escalade (max atteint moins Y de départ), tout le monde part de 0. Le TP de départ utilise le heightmap et ne rate plus silencieusement le repositionnement.
- **Fermier Express comptait les cultures immatures** — Casser une culture à n'importe quel stade marquait un point. Les cultures à âge doivent désormais être à maturité (`CropBlock.isMaxAge`) pour compter.
- **Poseur de Blocs exploitable par poser/casser/reposer** — Chaque pose marquait sans condition. Chaque position est désormais comptée une seule fois par joueur, et les poses/cassages en créatif sont ignorés.
- **Les cassages de blocs comptaient même annulés / en créatif** — `onBlockBreak` ignore désormais les événements annulés et les joueurs en créatif.

### Modifications

- **Infection lit enfin ses clés de config** — `infection_range_blocks`, `infection_check_interval_ticks` et `infection_points_per_infection` étaient définies mais ignorées (constantes en dur). Elles sont appliquées au lancement, et le patient zéro reçoit un score d'infection de manière fiable.
- **Noms d'items, blocs, mobs et couleurs de laine localisés côté client** — Couleur Cible, Lâcher l'Item, Chasse au Trésor, Course au Craft, Chasseur de Mobs et Photo Safari affichaient des noms codés en dur dans une seule langue ; ils utilisent désormais `Component.translatable(...)` pour un affichage dans la langue du client.
- **Le timing du Quiz lit la config** — `quiz_question_interval_seconds` / `quiz_question_timeout_seconds` sont respectées au lieu de constantes en dur.

### Performance

- **Defaults de config construits une seule fois** — `ArcadiaConfig` résout la map de ~120 valeurs par défaut et la liste de commandes bloquées depuis un unique `DEFAULTS` statique au lieu de la reconstruire à chaque repli de getter.
- **Maître du Saut throttlé** — La détection de saut échantillonnait chaque tick ; elle échantillonne désormais tous les 2 ticks (sans manquer de saut) et met en cache la lecture de vitesse verticale.
- **Heightmap au lieu des scans de colonne** — Course vers la Position et Sommet du Monde résolvent le Y du sol via le heightmap (O(1)) au lieu de scanner toute la colonne au lancement.