Jak budovat vlastní minigames v Hytale: Server Developer 's Guide

By HytaleCharts Team Category: technical 7 min read

Chcete postavit další Bed Wars nebo Hunger Games na Hytale? Tato příručka pokrývá plný pracovní průtok - od herních stavů a vedení arény až po sledování hráčů na bázi ECS, dohazování a nasazení. Zahrnuje skutečné příklady z existujících minigamových modů CurseForge.

< p > Hytale serverside architektura je jedinečně vhodný pro vlastní minigames. Na rozdíl od Minecraft, kde herní režim pluginy bojovat proti vanilkové pískoviště, Hytale plugin API a ECS vám dá přímou kontrolu nad chování subjektu, světový stav, a herní tok. Pokud jste postavili Bukkit minigames, pojmy přeložit - ale implementace je čistší. < / p > < p > Tato příručka pokrývá hlavní systémy, které každá minigame potřebuje: správu stavu hry, instance arény, sledování hráčů, bodování, matchmaking a nasazení. < / p > < h2 > Architektura: Jak minigamové moduly fungují v Hytale < / h2 > < p > Před potápění do kódu, pochopit vysokou úroveň architektury Hytale minigame: < / p > < tabulka > < hlava > < tr > < th > Layer < / th > < th > Účel < / th > < th > Implementace < / th > < / tr > < / thead > < tbody > < tr > < td > < silný > Game Manager < / silný > < / td > < td > orchestráty vše - vytváří arény, spravuje lobby, tratě hráči < / td > < td > Singleton služby ve vašem plugin < / td > < / tr > < tr > < td > < silný > Arena instance < / silný > < / td > < td > Jedno běžící herní sezení s vlastním státem, hráči a světovým regionem < / td > < td > Třída řízení světa nebo regionu < / td > < / tr > < tr > < td > < silný > Game State Machine < / silný > < / td > < td > Ovládá fázový tok - čekání, odpočítávání, přehrávání, končící < / td > < td > Enum + timer logic per arena < / td > < / tr > < tr > < td > < silný > Player Data < / silný > < / td > < td > Tracks per- player state - skóre, tým, živý / mrtvý, statistiky < / td > < td > ECS Součásti připojené k hráčům < / td > < / tr > < tr > < td > < silné > manipulátory s událostmi < / silné > < / td > < td > Reagovat na akce hráčů - zabití, blokování, vstup do zóny < / td > < td > EventBus + ECS event systems < / td > < / tr > < / tbody > < / tabulka > < h2 > Krok 1: Hra State Machine < / h2 > < p > Každý minigame potřebuje stavový stroj. To je páteř, která kontroluje, co se děje a kdy. < / p > < pre > < kód > veřejné enum GameState { Čekání, / / Lobby, čekání na hráče Startování, / / odpočítávání před začátkem hry PLAYING, / / Aktivní hra DEATHMATCH, / / Volitelně: finální fáze zúčtování VSTUP / / Hra skončila, výsledky ukazují } < / kód > < / pre > < p > Každá instance arény má vlastní < kód > GameState < / kód >. K přechodům dochází na základě podmínek: < / p > < ul > < li > < silný > ČASOVÉ → ZAHÁJENÍ: < / silný > Minimální počet hráčů dosáhl < / li > < li > < silný > STARTING → PLAYING: < / silný > Časovač odpočítávání vyprší < / li > < li > < silný > PLAYING → DEATHMATCH: < / silný > Časový limit nebo práh hráče < / li > < li > < silný > PLAYING / DEATHMATCH → ENDING: < / silný > Vyhrát podmínka splněna (poslední hráč živý, skóre dosaženo, atd.) < / li > < li > < silný > ENDING → Čekání: < / silný > Zobrazené výsledky, reset arény < / li > < / ul > < pre > < kód > veřejná třída Arena { soukromý stát GameState = stát GameState. Čekání; soukromý závěrečný seznam & lt; PlayerRef & gt; hráči = nový ArrayList & lt; & gt; (); soukromý int odpočítávání = 10; veřejné prázdné klíště () { přepínač (stav) { ČEKÁVÁNÍ - > { pokud (players.size () > = MIN _ PLAYERS) { stát = GameState. ZAHÁJENÍ; odpočet = 10; } } PŘÍPAD ZAHÁJENÍ - > { Odpočet...; widcastCountdown (odpočet); pokud (odpočítávání < = 0) { stát = GameState. Hra; startGame (); } } Přehrávání případů - > { checkWinCondition (); } KONEC - > { displayResults (); resetArena (); stát = GameState. Čekání; } } } } < / kód > < / pre > < h2 > Krok 2: Přehrávač s ECS komponenty < / h2 > < p > Použijte Hytler 's Entribute Component System pro připojení hraných dat k subjektům přehrávačů. To je čistší než udržování externího < kódu > HashMap & lt; UUID, PlayerData & gt; < / code > maps - data žijí na samotném subjektu. < / p > < pre > < kód > veřejná třída Minigame Nástroje pro přehrávání Komponent & lt; ComponentyStore & gt; { veřejné String arena Id = ""; veřejný tým String = ""; veřejný int kills = 0; úmrtí na veřejnosti = 0; veřejné int score = 0; veřejný boolean alive = true; na veřejnosti dlouho naposledy Smrt = 0; @ Override veřejný klon MinigamePlayer () { Minigame Kopie přehrávače = nový MinigamePlayer (); copy.arena Id = this. arenaId; Rozumím. tým = tento tým; copy.kills = this. kills; copy.death = this. death; copy.score = this.score; copy.alive = this. alive; copy.lastDeath = this. last Smrt. vrácená kopie; } } < / kód > < / pre > < p > Připojte tuto složku, když hráč vstoupí do arény, přečtěte si ji během hry pro bodování a týmovou logiku, a odstraňte ji, když odejde. < / p > < h2 > Krok 3: Událost řešení hry Logika < / h2 > < p > Minigames musí reagovat na akce hráče. Pro každý typ použijte vhodný systém událostí: < / p > < h3 > Událost Bus events (Global) < / h3 > < před > < kód > / / Hráč se připojí k serveru - ukázat jim lobby getEventRegister () .registerGlobal ( PlayerReadyEvent.class event - > teleportToLobby (event.getPlayer ()) ); / / Hráč se odpojí - odstranit z arény getEventRegister () .registerGlobal ( PlayerDiscontenEvent.class, event - > handlePlayerLeach (event.getPlayer ()) ); / / Chat příkazy - / připojit, / odejít, / diváci getEventRegister () .registerAsyncGlobal ( PlayerChatevent.class, future - > future.thenAccept (event - > { String msg = event.getMessage (); pokud (msg.startsWith ("/ připojit")) { event.setCancelled (true); handleJoinCommand (event.getSender ()); } }) ); < / kód > < / pre > < h3 > ECS Události (specifické) < / h3 > < p > Pro blokové přestávky, poškození a další akce na úrovni atributů vytvořte < kód > CovertyEventSystem < / code > podtřídy: < / p > < před > < kód > / / Stopy zabíjí pro bodování veřejná třída KillTracker Rozšíření RefChangeSystem & lt; CommittyStore, DeathComponent & gt; { @ Override Veřejná prázdnota onComponent Přidáno (Prostory Store, Ref. subjekt, DeathComponent death) { / / Subjekt zemřel - najít vraha, aktualizovat skóre Ref killer = death.getKiller (); Pokud (vrah! = null) { Minigame Player killerData = getComponent ( vrah, MinigamePlayer.class); if (killerData! = null) { vrah Data.kills + +; vrah Data.score + = KILL _ POINTS; } } } } < / kód > < / pre > < p > < silný > Pamatujte: < / silný > Události ECS musí být zrušeny v < silném > filtru < / silném > fázi, nikoli v kontrolní fázi. Chcete-li zabránit přerušení bloku během lobby fáze, filtr musí zkontrolovat stav hry a zrušit před akcí. < / p > < h2 > Krok 4: Arena Management < / h2 > < p > Pro hry, které potřebují izolované hrací prostory (Hunger Games, Bed Wars), potřebujete instance arény: < / p > < h3 > Multi- Arena Pattern < / h3 > < pre > < kód > veřejná třída ArenaManager { soukromé konečné mapy & lt; String, Arena & gt; arény = nové HashMap & lt; & gt; (); veřejná Arena createArena (String id, Poloha centra) { Arena arena = nová Arena (id, center); arenas.put (id, arena); zpáteční aréna; } veřejnost Arena findDotaz ableArena () { return arenas.values () .stream () .filter (a - > a.getState () = = GameState. Čekejte. .filter (a - > a.getPlayerCount () < a.getMaxPlayers ()) .findFirst () .orElse (null); } veřejné prázdné tickAll () { arenas.values () .forEach (Arena:: tick); } } < / kód > < / pre > < h3 > Arena Reset < / h3 > < p > Po každé hře se aréna musí vrátit do původního stavu. Dva přístupy: < / p > < ul > < li > < silný > Obnovit snímek: < / silný > Uložit bloková data arény před zahájením hry, obnovit po. Používá více paměti, ale je spolehlivá. < / li > < li > < silné > Přetížení Prefabu: < / silné > Použijte Hytale 's built- in Prefab System pro uložení arény jako prefab struktury a re-umístit ji po každé hře. Čistič a integruje se s původními nástroji Hytale. < / li > < / ul > < h2 > Krok 5: Týmy a bodování < / h2 > < h3 > Týmové přiřazení < / h3 > < pre > < kód > veřejná prázdnota přiřadit Týmy (Arena arena) { Seznam & lt; PlayerRef & gt; hráči = arena.getPlayers (); Collections.shuffle (hráči); String [] teams = {"Red", "Blue", "Green", "Yellow"}; pro (int i = 0; i < players.size (); i + +) { Minigame Data přehrávače = getComponent ( players.get (i), MinigamePlayer.class); data.team = týmy [i% teams.length]; } } < / kód > < / pre > < h3 > Zobrazení hodnotící tabulky < / h3 > < p > Použijte Hytale < kód > Zpráva < / kód > třída pro zobrazení formátovaného skóre. Systém zprávy podporuje formátování barev, tučné / italické styly a substituci parametru: < / p > < pre > < kód > veřejnoprávní vysílání s prázdnou Výsledky (Arena arena) { StringBuilder sb = nový StringBuilder ("§ 6 = = = Skóre = = =\ n"); arena.getPlayers () .stream () .setříděn (a, b) - > getScore (b) - getScore (a)) .forEach (p - > { Minigame Data přehrávače = getComponent ( p, MinigamePlayer.class); sb.append (String.format ("§ f% s: § e% d kills § 7 tis. 124; § a% d pts\ n", p.getUsername (), data.kills, data.score); }); arena.broadcast (sb.toString ()); } < / kód > < / pre > < h2 > Krok 6: Výherní podmínky < / h2 > < p > Společné podmínky výhry minigamu a jejich realizace: < / p > < tabulka > < hlava > < tr > < th > Typ hry < / th > < th > Win Stav < / th > < th > Check In < / th > < / tr > < / thead > < tbody > < tr > < td > Last Man Standing < / td > < td > < 1 hráč / tým naživu < / td > < td > < td > Death handler - počítat živé hráče < / td > < / tr > < tr > < td > Score Target < / td > < td > První až X body < / td > < td > Aktualizace skóre - kontrola prahu < / td > < / tr > < tr > < td > Time Limit < / td > < td > Nejvyšší skóre, když vyprší čas < / td > < td > Game tick - check timer < / td > < / tr > < tr > < td > Cíl < / td > < td > Kompletní specifický úkol (zachytit vlajku, zničit postel) < / td > < td > Vlastní ECS událost pro objektivní interakci < / td > < / tr > < tr > < td > Rounds < / td > < td > Nejlepší z N kol < / td > < td > Round end handler - kontrolní skóre série < / td > < / tr > < / tbody > < / tabulka > < h2 > Krok 7: Matchmaking and Queues < / h2 > < p > Pro servery běžící více souběžných her, implementujte frontový systém: < / p > < pre > < kód > veřejná třída Matchmaking Fronta { soukromé finále Queue & lt; PlayerRef & gt; fronta = nový LinkedList & lt; & gt; (); Vyžadován soukromý konečný tip Hráči; veřejné prázdné addPlayer (přehrávač PlayerRef) { queue.add (player); kontrolní fronta (); } soukromá prázdná kontrolní fronta () { if (queue.size () > = requiddPlayers) { Arena arena = arenaManager.findDotaz ableArena (); pokud (arena! = null) { pro (int i = 0; i < požadované Hráči; i + +) { PlayerRef player = queue.poll (); arena.addPlayer (player); } } } } } < / kód > < / pre > < p > Hytale 's built- in < strong > Party System < / strong > umožňuje hráčům seskupit a zůstat pohromadě přes serverové přenosy. Vaše dohazování by mělo respektovat skupiny stran - členové fronty strany společně a umístit je na stejný tým, pokud je to možné. < / p > < h2 > Existující Modies Minigame to Study < / h2 > < p > Nebudujte od nuly - studujte, co je již na CurseForge: < / p > < tabulka > < hlava > < tr > < th > Mod < / th > < th > Typ < / th > < th > Klíčové vlastnosti studie < / th > < / tr > < / thead > < tbody > < tr > < td > < silný > Hunger Games < / silný > < / td > < td > Last Man Standing < / td > < td > Multi- arena management, lobby system, countdown, PvP fáze, autoreset < / td > < / tr > < tr > < td > < silný > Bossarena < / silný > < / td > < td > PvE Arena < / td > < td > NPC smluvní obchody, per- player kořist truhly, konfigurovatelné šéfy < / td > < / tr > < tr > < td > < silný > Wave Combat Arenas < / silný > < / td > < td > Horde Mode < / td > < td > < td > Vave spawning, obtížnost škálování, systémy odměn < / td > < / tr > < tr > < td > < silný > Skyblock < / silný > < / td > < td > přežití ostrova < / td > < td > Per- player světové instance, sledování progrese, setkání šéfů < / td > < / tr > < / tbody > < / tabulka > < p > Hunger Games mod je zvláště stojí za studium - to ukazuje celý životní cyklus konkurenční minigame: lobby → odpočítávání → PvP → smrtelný zápas → výsledky → reset. < / p > < h2 > Built- in Platform Functions for Minigame Servers < / h2 > < p > Hytale poskytuje několik funkcí z krabice, že Minecraft servery potřebují pluginy pro: < / p > < ul > < li > < silný > Discovery Catalogue: < / silný > Zabudovaný do hlavního menu - hráči mohou najít minigame server bez externích zobrazovacích stránek < / li > < li > < silný > Party System: < / silný > Rodné skupiny přátel, které přetrvávají napříč servery přenosy < / li > < li > < silný > Platební brána: < / silný > Zabudovaný do klienta pro servery, které chtějí zpeněžit kosmetiku nebo výhody < / li > < li > < silný > Rámec oprávnění: < / silný > User- level, group- based, a wildcard povolení odpovídající < / li > < / ul > < h2 > Kontrolní seznam nasazení < / h2 > < ol > < li > < siln > Build your JAR: < / strong > < code >. / gradlew build < / code > < / li > < li > < silný > Test na místě: < / silný > Přepnout do < kódu >% AppData% / Roaming / Hytale / UserData / Mods / < / kód > < / li > < li > < silný > Test s více klienty: < / silný > Aktualizace 4 umožňuje více Hytale instancí na jednom PC - testovací multiplayer scénáře lokálně < / li > < li > < strong > Nasadit na server: < / strong > Upload JAR na < code > / opt / hytale / Server / mods / < / code > < / li > < li > < silný > Publikovat na CurseForge: < / silný > Balení jako modul s řádným < kódem > manifest.json < / kód > < / li > < li > < strong > Seznam serveru: < / strong > Přidat do < a href = "/" > HytaleCharts < / a > s "Minigames" tag, takže hráči vás mohou najít < / li > < / ol > < p > Pro základní plugin API koncepty tento průvodce staví na, Přečtěte si naše < a href = "/ novinky / hytale-modding-api-server-plugin-development- guide" > Modding API Guide < / a >. A pro no- code obsah tvorby, která doplňuje vaše plugins, podívejte se na naše < a href = "/ novinky / hytale- vizual- scripting-guide-no-code-modding" > Průvodce vizuálním skriptem < / a >. < / p > < p > < em > Budování minigame serveru? Sdílejte ji na našem Discordu - pravidelně se objevujeme v komunitních výtvorech. < / em > < / p >