Comment construire des minigames personnalisés dans Hytale : Guide du développeur serveur

Par :nom Catégorie: :nom : minutes min lire

Vous voulez construire les prochains Bed Wars ou Hunger Games sur Hytale? Ce guide couvre l'ensemble du flux de travail, depuis les machines d'état de jeu et la gestion de l'aréna jusqu'au suivi, à la mise en correspondance et au déploiement des joueurs basés sur l'ECS. Comprend des exemples réels de minigames CurseForge existants.

L'architecture côté serveur d'Hytale le rend unique pour les mini-jeux personnalisés. Contrairement à Minecraft où les plugins de mode de jeu se battent contre le bac à sable vanille, l'API plugin d'Hytale et ECS vous donnent un contrôle direct sur le comportement de l'entité, l'état mondial et le flux de jeu. Si vous avez construit des minijeux Bukkit, les concepts traduisent — mais l'implémentation est plus propre. Ce guide couvre les systèmes de base de tous les minijeux nécessaires : gestion de l'état du jeu, instances aréna, suivi des joueurs, notation, matchmaking et déploiement. Architecture: Comment les plugins Minigame fonctionnent dans Hytale Avant de plonger dans le code, comprendre l'architecture de haut niveau d'un mini-jeu Hytale: LayerObjetMise en oeuvre Gestionnaire de jeuxOrchestres tout — crée des arènes, gère des lobbies, oriente les joueursService Singleton dans votre plugin Arena Instance Une session de jeu en cours avec son propre état, les joueurs et la région du monde Game State MachineContrôle le flux de phase — attente, compte à rebours, lecture, finEnum + logique de minuterie par aréna Données sur les joueursTracks par joueur — score, équipe, vivant/mort, statistiquesECS Composantes attachées aux entités de joueurs Manipulation des événements Réagir aux actions du joueur — tue, bloque l'entrée de la zoneEventBus + ECS event systems Étape 1: Jeu d'état machine Chaque mini-jeu a besoin d'une machine d'état. C'est l'épine dorsale qui contrôle ce qui se passe et quand. enum public GameState { WAITING, // Lobby, attendant les joueurs Commencer, // Compte à rebours avant le début du jeu JEUNER, // Gameplay actif DEATHMATCH, // Facultatif: phase finale d'affichage FIN // Jeu terminé, montrant les résultats } Chaque instance d'aréna détient son propre GameState. Les transitions se produisent en fonction des conditions: WAITING → Commencer: Nombre minimal de joueurs atteint STARTING → JEUNER: Le compte à rebours expire PLAYING → MORTHMATCH: Délai ou seuil du joueur PLAYING/DEATHMATCH → FIN : État de victoire satisfait (dernier joueur vivant, score atteint, etc.) TENIR → S'attendre: Résultats affichés, réinitialisation de l'arène Classe publique Arena { État de jeu privé = État de jeu. Attendez. final privé Liste etlt;PlayerRef etgt; joueurs = nouveau ArrayList etlt;>(); compte à rebours privé = 10; tique vide public() { interrupteur (état) { Cas d'attente -> { si (players.size() >= MIN_PLAYERS) { État = État du jeu. Commencer; compte à rebours = 10; } } Cas commençant -> { compte à rebours... diffusionCountdown(compte à rebours); si (compte à rebours teleportToLobby(event.getPlayer()) ); // Déconnecter le joueur — supprimer de l'arène getEventRegistry().registrerGlobal( PlayerDisconnectEvent.class, event -> handlePlayerLeave(event.getPlayer()) ); // Commandes de clavardage — /join, /leave, /spectate getEventRegistry().registrerAsyncGlobal( LecteurChatEvent.class, future -> future.thenAccept(événement -> { Chaîne msg = event.getMessage(); si (msg.startsWith("/join")) { event.setAnnulé(vrai); handleJoinCommand(event.getSender()); } }) ); ECS Événements (spécifiques à l'entité) Pour les bris de blocs, les dommages et autres actions au niveau de l'entité, créez EntitéEventSystem sous-classes: // La piste tue pour marquer classe publique KillTracker élargit RefChangeSystem { @Override vide public sur Composant Ajouté(EntityStore store, Réf entité, Décès du composant de décès) { // Entité décédée — trouver le tueur, mettre à jour les scores Réf tueur = mort.getKiller(); si (tueur != nul) { Mini-jeu Lecteur killerData = getComponent( tueur, MinigamePlayer.class); si (killerData != null) { tueur Données.kills++; tueur Données.score += _POUVOIRS; } } } } Souvenez-vous: Les événements du SCE doivent être annulés dans la phase filter, et non dans la phase d'inspection. Si vous voulez empêcher la rupture de bloc pendant la phase de lobby, le filtre doit vérifier l'état du jeu et annuler avant l'exécution de l'action. Étape 4: Gestion de l'aréna Pour les jeux qui ont besoin d'espaces de jeu isolés (Hunger Games, Bed Wars), vous avez besoin d'instances aréna: Multi-Arena Pattern classe publique ArenaManager { la carte finale privée;String, Arena> arènes = nouveau HashMap(); public Arena createArena(ID de positionnement, centre de localisation) { Arena arène = nouvelle Arena (id, centre); arènes.put(id, arène); arène de retour; } public Find de l'arénaDisponibleArena() { arènes de retour.valeurs().stream() .filter(a -> a.getState() == État du jeu. Attendez. .filter(a -> a.getPlayerCount() < a.getMaxPlayers()) .findFirst() .ouElse(null); } vide public ticAll() { arènes.valeurs().pourChacun(Arena::tick); } } Arena Réinitialiser Après chaque jeu, l'arène doit revenir à son état original. Deux approches : Restaurer l'instantané: Enregistrer les données de bloc de la région aréna avant le début du jeu, le restaurer après. Utilise plus de mémoire mais est fiable. Prefab recharge: Utilisez le système Prefab intégré d'Hytale pour stocker l'arène comme une structure préfab et la remplacer après chaque jeu. Plus propre et s'intègre aux outils natifs d'Hytale. Étape 5: Équipes et notation Travail d'équipe attribution du vide public Équipes (Arena arène) { List joueurs = arena.getPlayers(); Collections.shuffle(joueurs); Équipes à cordes = {"Rouge", "Blue", "Green", "Jaune"}; pour (int i = 0; i < players.size(); i++) { Mini-jeu Données du lecteur = getComponent( players.get(i), MinigamePlayer.class; data.team = équipes[i % teams.longueur]; } } Affichage du tableau de bord Utilisez la classe de Hytale Message pour les affichages de partition formatés. Le système Message prend en charge le formatage des couleurs, les styles bold/italiques et la substitution des paramètres : diffusion publique nulle Scores(Arena arena) { StringBuilder sb = nouveau StringBuilder("§6=== Tableau de bord ===\n"); arène.getPlayers().stream() .sorted(a, b) -> getScore(b) - getScore(a)) .pourchaque(p -> { Mini-jeu Données du lecteur = getComponent( p, MinigamePlayer.class); sb.append(String.format("§f%s: §e%d kills §7" §a%d pts\n", p.getUsername(), data.kills, data.score); }); arena.broadcast(sb.toString()); } Étape 6: Conditions de victoire Conditions communes de victoire et comment les mettre en œuvre: Type de jeuConditions d'utilisationChoisir Dernier homme debout1 joueur/équipe vivantGestionnaire de la mort — compter les joueurs vivants Cible de basePremière à X points Mise à jour des scores — seuil de vérification Délai Score le plus élevé à l'expiration du délaiCochez la case de jeu — vérifier le chronomètre Objectif Achèvement d'une tâche spécifique (plage de capture, destruction du lit)Événement du SCE personnalisé pour une interaction objective Rounds Meilleur de N roundsManipulateur d'extrémités rondes — vérifier le score de la série Étape 7: Matchmaking et files d'attente Pour les serveurs exécutant plusieurs jeux simultanés, implémenter un système de file d'attente: classe publique Demande { finale privée Queue file d'attente = nouveau LinkedList(); Int privé final requis Joueurs; public vide addPlayer(PlayerRef player) { file d'attente.add(joueur); vérifier la quantité(); } chèque de vide privéQuie() { si (queue.size() >= requisJoueurs) { Arena arène = arèneManager.findDisponibleArena(); si (arena != null) { pour (int i = 0; i < requis Joueurs; i++) { PlayerRef player = file d'attente.poll(); arène.addPlayer(joueur); } } } } } Le système intégré de Hytale Party System permet aux joueurs de se regrouper et de rester ensemble lors des transferts de serveur. Votre matchmaking devrait respecter les groupes du parti — les membres du parti en file d'attente ensemble et les placer dans la même équipe si possible. Modalités de jeu miniature existantes à étudier Ne pas construire à partir de rien — étudier ce qui est déjà sur la CurseForge: Mod Type Principales caractéristiques à étudier Hunger GamesLast Man StandingGestion multi-aréna, système de lobby, compte à rebours, phases PvP, rétablissement automatique BossArena PvE ArenaNPC ateliers contractuels, coffres à but lucratif par joueur, patrons configurables Wave Combat ArenasMode de l'HordeWave fraying, difficulté d'échelle, systèmes de récompense SkyblockSurvie de l'îlePar joueur instances mondiales, suivi de la progression, rencontres avec le patron Le mod Jeux de la Faim mérite particulièrement d'être étudié — il démontre le cycle de vie complet d'un minigame compétitif: lobby → compte à rebours → PvP → deathmatch → résultats → reset. Construire les fonctionnalités de la plate-forme pour les serveurs Minigame Hytale fournit plusieurs fonctionnalités de la boîte que les serveurs Minecraft ont besoin de plugins pour : Découverte Catalogue: Construit dans le menu principal — les joueurs peuvent trouver votre serveur minigame sans sites de listage externe Système parti: Groupe d'amis autochtones qui persiste dans les transferts de serveur Gateway de paiement: Construit dans le client pour les serveurs qui veulent monétiser les cosmétiques ou les avantages Cadre d'autorisations: Correspondance des autorisations de niveau utilisateur, de groupe et de wildcard Liste de contrôle du travail Construisez votre JAR: ./gradlew build Test local: Déposer dans %AppData%/Roaming/Hytale/UserData/Mods/ Test avec plusieurs clients: La mise à jour 4 permet plusieurs instances Hytale sur un seul PC — testez localement des scénarios multijoueurs Déployer vers le serveur: Télécharger JAR vers /opt/hytale/Server/mods/ Publier sur CurseForge: Paquet sous forme de plugin avec le bon manifest.json Liste de votre serveur: Ajoutez-le à HytaleCharts avec le tag "Minigames" pour que les joueurs puissent vous trouver Pour les concepts d'API de plugins fondamentaux sur lesquels ce guide s'appuie, lisez notre Modding API Guide. Et pour la création de contenu sans code qui complète vos plugins, consultez notre Guide d'écriture visuelle. Construire un serveur de mini-jeux? Partagez-le sur notre discorde — nous proposons régulièrement des créations communautaires.