Jak budować własne minigames w Hytale: Przewodnik programisty serwera

Nazwa Kategoria::: nazwa : min min read

Chcesz zbudować następny Bed Wars lub Gry śmierci na Hytale? Przewodnik ten obejmuje pełny przepływ pracy - od maszyn stanu gry i zarządzania areną po śledzenie graczy, swatanie i wdrażanie ECS. Zawiera rzeczywiste przykłady z istniejących modów CurseForge minigame.

< p > Architektura serwerowa Hytale sprawia, że nadaje się ona wyjątkowo do własnych minigamów. W przeciwieństwie do Minecraft, gdzie tryb gry wtyczek walki z piaskownicy wanilii, Hytale wtyczki API i ECS daje bezpośrednią kontrolę nad zachowaniem jednostki, stan świata i przepływ gry. Jeśli zbudowałeś minigames Bukkit, koncepcje tłumaczyć - ale implementacja jest czystsza. < / p > < p > Ten przewodnik obejmuje podstawowe systemy, których potrzebuje każda minigra: zarządzanie stanem gry, instancje areny, śledzenie graczy, punktacja, swatanie i wdrażanie. < / p > < h2 > Architektura: Jak Minigame Wtyczki działają w Hytale < / h2 > < p > Przed zanurzeniem w kodzie, zrozumieć architekturę high-level hytale minigame: < / p > < tabela > < głowa > < tr > < th > Warstwa < / th > < th > Cel < / th > < th > Wdrożenie < / th > < / tr > < / głowa > < tbody > < tr > < td > < strong > Game Manager < / strong > < / td > < td > Orchestrations wszystko - tworzy areny, zarządza lobby, trasy graczy < / td > < td > Singleton usługi w wtyczce < / td > < / tr > < tr > < td > < silny > Arena Instance < / silny > < / td > < td > Jedna uruchomiona sesja z własnym stanem gry, graczami i regionem świata < / td > < td > Klasa zarządzania światem lub regionem < / td > < / tr > < tr > < td > < strong > Game State Machine < / strong > < / td > < td > Steruje przepływem fazy - czekanie, odliczanie, gra, kończąc < / td > < td > Enum + timer logika na arenę < / td > < / tr > < tr > < td > < strong > Player Data < / strong > < / td > < td > Tracks perplayer state - score, team, alive / dead, stats < / td > < td > ECS Elementy przyłączone do podmiotów grających < / td > < / tr > < tr > < td > < silny > Obsługa zdarzeń < / silna > < / td > < td > Reakcja na działania gracza - kills, block breaks, zone entry < / td > < td > EventBus + ECS event systems < / td > < / tr > < / tbody > < / tabela > < h2 > Krok 1: Maszyna stanu gry < / h2 > < p > Każda minigra potrzebuje maszyny stanowej. Jest to kręgosłup, który kontroluje co się dzieje i kiedy. < / p > < pre > < code > public enum GameState { WAITING, / / Lobby, czeka na graczy STARSTING, / / Odliczanie przed rozpoczęciem gry Granie, / / Aktywna gra DEATHMATCH, / / Opcjonalnie: końcowa faza pokazowa ZAŁĄCZNIK / / Gra skończona, wyświetlanie wyników < / kod > < / przed > < p > Każda instancja areny posiada swój własny < kod > GameState < / kod >. Zmiany następują na podstawie warunków: < / p > < ul > < li > < silny > WAITING → STARTING: < / silny > Minimalna liczba graczy osiągnięta < / li > < li > < silny > STARTING → PLAYING: < / silny > Czas odliczania upływa < / li > < li > < strong > playing → DEATHMATCH: < / strong > Termin lub próg gracza < / li > < li > < mocne > PLAYING / DEATHMATCH → ENDING: < / strong > Wygrać warunek spełnione (ostatni gracz żywy, wynik osiągnięty, itp.) < / li > < li > < silny > ENDING → WAITING: < / silny > Wyniki wyświetlane, reset areny < / li > < / ul > < pre > < kod > klasa publiczna Arena { prywatny stan GameState = stan GameState. Oczekiwanie; Prywatna ostateczna lista & lt; PlayerRef & gt; gracze = nowa ArrayList & lt; & gt; (); odliczanie prywatnych int = 10; kleszcz pustki publicznej () { przełączanie (stan) { waiting case - > { jeżeli (players.size () > = {C: $aaccff} Tłumaczenie: state = GameState. STARSTING; odliczanie = 10; ¶ ¶ STARSTING - > { Liczenie -; BroadcastCountdown (odliczanie); jeżeli (odliczanie < = 0) { state = GameState. Gra; startGame (); ¶ ¶ case PLAYING - > { checkWinCondition (); ¶ DODATEK SPRAWY - > { displayResults (); Rewitalizacja Areny (); state = GameState. Oczekiwanie; ¶ ¶ ¶ < / kod > < / przed > < h2 > Krok 2: Dane gracza z komponentami ECS < / h2 > < p > Użyj Hytale 's Entity Component System do dołączania danych specyficznych dla danej gry do podmiotów gracza. Jest to czystsze niż utrzymanie zewnętrznego < kod > HashMap & lt; UUID, PlayerData & gt; < / kod > mapy - dane żyją na samej jednostce. < / p > < pre > < kod > klasa publiczna Minigame Gracz implementuje Składnik & lt; EntityStore & gt; { publiczna arena smyczkowa Id = ""; public String team = ""; public int kills = 0; zgony wśród ludności = 0; publiczny wynik punktowy = 0; publiczny boolean żywy = true; publiczny długo ostatni Śmierć = 0; @ Override klon MinigamePlayer () { Minigame Kopia gracza = nowy MinigamePlayer (); copyarena Id = this. ArenaId; Przyjąłem. team = this. team; Copy.kills = to. Kills; Copy.death = this. death; Copy.score = this. score; Copy.life = this. life; Copy.lastDeath = this. last Śmierć; kopie zwrotne; ¶ < / kod > < / przed > < p > Dołącz do tego komponentu, gdy gracz dołącza do areny, przeczytaj go podczas gry dla punktacji i logiki zespołu, a następnie usuń go po wyjściu. < / p > < h2 > Krok 3: Obsługa zdarzeń dla gry Logika < / h2 > < p > Minigames muszą reagować na działania gracza. Stosować odpowiedni system zdarzeń dla każdego typu: < / p > < h3 > Zdarzenie Wydarzenia autobusowe (globalne) < / h3 > < pre > < kod > / / Gracz dołącza do serwera - pokaż im lobby getEventRegistry () .registerGlobal ( PlayerReadyEvent.class, event - > teleportToLobby (event.getPlayer ()) ); / / Gracz rozłącza się - usunąć z areny getEventRegistry () .registerGlobal ( PlayerDisconnectEvent.class, event - > handlePlayerLeave (event.getPlayer ()) ); / / Polecenia rozmowy - / join, / leave, / spectate getEventRegistry () .registerAsyncGlobal ( PlayerChatEvent.class, future - > future.thenAccept (wydarzenie - > { String msg = event.getMessage (); if (msg.startWith ("/ join") { event.setCancelled (true); handleJoinCommand (event.getSender ()); ¶ ) ); < / kod > < / przed < h3 > ECS Wydarzenia (specyficzne dla uprawnień) < / h3 > < p > Dla przerw blokowych, uszkodzeń i innych działań na poziomie entity- level, stwórz < kod > EntityEventSystem < / code > podklasy: < / p > < pre > < kod > / / Track kills for scoring klasa publiczna KillTracker rozszerza RefChangeSystem & lt; EntityStore, Death Component & gt; @ Override pustka publiczna onComponent Dodano (sklep EntityStore, Jednostka zależna, Śmiertelna śmierć składowa) / / Podmiot zmarł - znaleźć zabójcę, uaktualnić wyniki Ref killer = death.getKiller (); jeśli (zabójca! = null) { Minigame KillerData = getComponent ( zabójca, MinigamePlayer.class); if (killerData! = null) { zabójca Data.kills + +; zabójca Data.score + = KILL _ POINTS; ¶ ¶ ¶ < / kod > < / przed > < p > < silny > Pamiętaj: < / silny > Zdarzenia związane z ECS muszą być anulowane w fazie < silnej > filtra < / silnej >, a nie w fazie kontrolnej. Jeśli chcesz zapobiec złamaniu bloku podczas fazy lobby, filtr musi sprawdzić stan gry i anulować przed wykonaniem działania. < / p > < h2 > Krok 4: Zarządzanie Areną < / h2 > < p > Dla gier, które potrzebują odizolowanych przestrzeni do gry (Gry śmierci, Bed Wars), trzeba areny instancje: < / p > < h3 > Wzorce wieloAreny < / h3 > < pre > < kod > klasa publiczna ArenaManager { Prywatna ostateczna mapa & lt; String, Arena & gt; arenas = nowy HashMap & lt; & gt; (); public Arena createArena (String id, Centrum Lokalizacji) { Arena arena = nowa Arena (id, center); arenas.put (id, arena); arena powrotna; ¶ public Arena findAvailableArena () { return arenas.values () .stream () .filter (a - > a.getState () = = GameState. / .filter (a - > a.getPlayerCount () < a.getMaxPlayers ()) .findFirst () .lubElse (null); ¶ Publiczna pustka tickAll () { arenas.values () .forEach (Arena:: tick); ¶ < / kod > < / przed > < h3 > Arena Reset < / h3 > < p > Po każdej grze arena musi powrócić do pierwotnego stanu. Dwa podejścia: < / p > < ul > < li > < strong > Snapshot przywracanie: < / strong > Zapisz dane bloku arena przed rozpoczęciem gry, przywróć go po. Wykorzystuje więcej pamięci, ale jest niezawodny. < / li > < li > < silny > Prefab reload: < / silny > Użyj Hytale built- w Prefab System do przechowywania areny jako prefab struktury i umieścić go po każdej grze. Czystsze i integruje się z natywnymi narzędziami Hytale. < / li > < / ul > < h2 > Krok 5: Zespoły i punkty < / h2 > < h3 > Przydział zespołów < / h3 > < pre > < kod > przypisanie pustki publicznej Zespoły (Arena Arena) { Lista graczy & lt; PlayerRef & gt; = arena.getPlayers (); Collections.shuffle (gracze); {"Red", "Blue", "Green", "Yellow"}; dla (int i = 0; i < players.size (); i + +) { Minigame Dane gracza = getComponent ( players.get (i), MinigamePlayer.class); data.team = zespoły [i% teams.length]; ¶ < / kod > < / przed > < h3 > Wyświetlacz tablicy wyników < / h3 > < p > Użyj Hytale 's < code > Wiadomość < / kod > klasa dla sformatowanych wyświetleń punktów. System Message obsługuje formatowanie kolorów, style pogrubione / italiczne oraz zastępowanie parametrów: < / p > < pre > < kod > public void transmission Wyniki (Arena Arena) { StringBuilder sb = nowy StringBuilder ("§ 6 = = = Tabela wyników = =\ n"); arena.getPlayers () .stream () .sorted (a, b) - > getScore (b) - getScore (a)) Dla każdego (p - > { Minigame Dane gracza = getComponent ( p, MinigamePlayer.class); sb.append (String.format ("§ f% s: § e% d kills § 7 is 124; § a% d pts\ n", p.getUsername (), data.kills, data.score); ); arena.transmission (sb.toString ()); < / kod > < / przed > < h2 > Krok 6: Wygrać warunki < / h2 > < p > Wspólne warunki wygranej minigame i sposób ich wdrożenia: < / p > < tabela > < głowa > < tr > < th > Typ gry < / th > < th > Wygraj warunek < / th > < th > Sprawdź w < / th > < / tr > < / głowa > < tbody > < tr > < td > Last Man Standing < / td > < td > 1 player / team living < / td > < td > Death handler - licz graczy żywych < / td > < / tr > < tr > < td > Punkt docelowy < / td > < td > Punkty od początku do X < / td > < td > Wynik aktualizacji - próg kontrolny < / td > < / tr > < tr > < td > Limit czasowy < / td > < td > Najwyższy wynik po upływie czasu < / td > < td > Tik gry - sprawdź timer < / td > < / tr > < tr > < td > Cel < / td > < td > Kompletne specyficzne zadanie (przechwytywanie flagi, niszczenie łóżka) < / td > < td > Zdarzenie ECS użytkownika dla obiektywnej interakcji < / td > < / tr > < tr > < td > Zaokrąglenia < / td > < td > Najlepsza z rund N < / td > < td > Obróbka okrągłych końców - wynik serii kontrolnej < / td > < / tr > < / tbody > < / tabela > < h2 > Krok 7: Tworzenie pasm i kolejki < / h2 > < p > Dla serwerów uruchamiających wiele równoległych gier, implementuj system kolejki: < / p > < pre > < kod > klasa publiczna Matchmaking Kolejka { finał prywatny Kolejka & lt; PlayerRef & gt; kolejka = nowa LinkedList & lt; & gt; (); Wymagana końcówka prywatna Gracze; public void addPlayer (PlayerRef player) { queue.add (gracz); kolejka kontrolna (); ¶ private void checkQueue () { if (queue.size () > = requiddPlayers) { Arena arena = arenaManager.findAvalableArena (); if (arena! = null) { dla (int i = 0; i < wymagane Gracze; i + +) { PlayerRef player = queue.poll (); arena.addPlayer (gracz); ¶ ¶ ¶ ¶ < / kod > < / przed > < p > Hytale 's built- in < strong > Party System < / strong > pozwala graczom grupować się i trzymać się razem pomiędzy transferami serwerów. Twoje swatanie powinno szanować grupy partyjne - kolejki członków partii razem i umieścić je w tym samym zespole, jeśli to możliwe. < / p > < h2 > Istniejące Mody Minigame do badania < / h2 > < p > Nie budujcie od zera - przestudiujcie co już jest na CurseForge: < / p > < tabela > < głowa > < tr > < th > Mod < / th > < th > Typ < / th > < th > Główne cechy badania < / th > < / tr > < / głowa > < tbody > < tr > < td > < silny > Gry głodowe < / silny > < / td > < td > Ostatni człowiek stojący < / td > < td > Zarządzanie wieloarenowe, system lobby, odliczanie, fazy PvP, auto- reset < / td > < / tr > < tr > < td > < strong > BossArena < / strong > < / td > < td > PvE Arena < / td > < td > Sklepy z kontraktami NPC, skrzynie z łupem dla graczy, konfigurowalne bossy < / td > < / tr > < tr > < td > < silny > Wave Combat Arenas < / strong > < / td > < td > Tryb hordy < / td > < td > Wave tarło, skalowanie trudności, systemy nagród < / td > < / tr > < tr > < td > < strong > Skyblock < / strong > < / td > < td > Island Survival < / td > < td > Perplayer world instances, progression tracking, boss meetters < / td > < / tr > < / tbody > < / tabela > < p > Moda gry głodowej jest szczególnie warta studiowania - pokazuje pełny cykl życia konkurencyjnego minigame: lobby → Countdown → PvP → deathmatch → reset. < / p > < h2 > Tworzenie funkcji platformy dla serwerów minigame < / h2 > < p > Hytale dostarcza kilka funkcji z pudełka, które serwery Minecraft potrzebują wtyczek do: < / p > < ul > < li > < strong > Discovery Katalog: < / strong > Wbudowany w menu głównym - gracze mogą znaleźć serwer minigame bez zewnętrznych stron listy < / li > < li > < silny > System partyjny: < / silny > Native friend grouping that persists across server transfers < / li > < li > < silny > Brama płatnicza: < / silny > Wbudowany w klienta dla serwerów, które chcą zarabiać kosmetyki lub bonusy < / li > < li > < mocne > Ramy uprawnień: < / silne > User- level, group- based, and wildcard authorisation matching < / li > < / ul > < h2 > Lista kontrolna wdrażania < / h2 > < ol > < li > < strong > Build your JAR: < / strong > < code >. / gradlew build < / code > < / li > < li > < silny > Test lokalny: < / silny > Zrzut do < kodu >% AppData% / Roaming / Hytale / UserData / Mods / < / code > < / li > < li > < silny > Test z wieloma klientami: < / silny > Aktualizacja 4 pozwala na wiele instancji Hytale na jednym komputerze - testować scenariusze multiplayer lokalnie < / li > < li > < strong > Deploy to server: < / strong > Wyślij JAR do < code > / opt / hytale / Server / mods / < / code > < / li > < li > < strong > Publish on CurseForge: < / strong > Pakiet jako wtyczka z prawidłowym < kodem > manifest.json < / kod > < / li > < li > < strong > Lista serwerów: < / strong > Dodaj do < a href = "/" > HytaleCharts < / a > za pomocą znacznika "Minigames", aby gracze mogli znaleźć Cię < / li > < / ol > < p > Dla podstawowych koncepcji wtyczki API ten przewodnik opiera się na, przeczytaj nasz < a href = "/ news / hytale- modding- api- server- plugin- development- guide" > Moding API Guide < / a >. A dla tworzenia treści o niekodowanym kodzie, które uzupełnia wtyczki, sprawdź nasze < a href = "/ news / hytale- visual- scripting- guide- no- code- mododing" > Visual Scritting Guide < / a >. < / p > < p > < em > Budowa serwera minigame? Podziel się nim na naszej Discord - regularnie oferujemy kreacje społeczności. < / em > < / p >