Hytaleでカスタムミニゲームを作成する方法:サーバー開発者のガイド

によって HytaleCharts Team カテゴリー: technical :mins min 読み込み

Hytaleで次のBed WarsやHunger Gamesをビルドしたいですか? ゲームのステートマシンやアリーナ管理からECSベースのプレイヤートラッキング、マッチメイキング、展開まで、ワークフロー全体をフルにカバーします。 既存の CurseForge minigame mods から実際の例が含まれています.

Hytaleのサーバーサイドアーキテクチャは、カスタムミニゲームに一意に適しています。 ゲームモードプラグインがバニラサンドボックスと戦うMinecraftとは異なり、HytaleのプラグインAPIとECSは、エンティティティの行動、世界状態、ゲームフローを直接制御します。 Bukkit minigamesをビルドすると、コンセプトは翻訳されますが、実装はクリーナーです。 このガイドでは、ゲームの状態管理、アリーナインスタンス、プレイヤートラッキング、スコアリング、マッチメイキング、デプロイメントなど、すべてのミニゲームニーズのコアシステムをカバーしています。 Architecture:MinigameプラグインがHytaleでどのように機能するか ダイビングをコード化し、ハイターミニゲームのハイレベルなアーキテクチャを把握する: LayerPurpose Game Manager すべて — senas を生成し、lobbies を管理し、usersSingleton をプラグインでルーティングします Arena Instance 独自の状態、プレイヤー、および世界領域で実行中のゲームセッション世界または地域を管理するクラス Game State Machine フェーズフローの制御 — 待機、カウントダウン、再生、終了 Player Data Per-player 状態のトラック — スコア、チーム、ライブ/デッド、statsECS プレイヤーのエンティティティティに添付されたコンポーネント イベントハンドラ プレイヤーアクションに反応 — キル、ブロックブレイク、ゾーンエントリーイベントバス+ECSイベントシステム ステップ1:Game State Machine 全てのミニゲームはステートマシンが必要です。 これは何が起こるか、いつ制御するバックボーンです。 公開enum GameState お問い合わせ WAITING, // ロビー, プレイヤーを待っている スタート, // ゲーム開始前のカウントダウン プレイ, // アクティブなゲームプレイ DEATHMATCH, // オプション: 最終的な showdown フェーズ 終了 // ゲームオーバー、結果を表示 お問い合わせ Each は GameState を所有しています。 条件に基づく移行: WAITING → スタート: 最小プレイヤー数に達しました スターティング → プレイング: カウントダウンタイマーが切れる PLAYING → DEATHMATCH: 時間制限またはプレイヤーのしきい値 PLAYING/DEATHMATCH → ENDING: ウィン条件を満たした(プレイヤーのライブ、スコアの到達など) ENDING → WAITING: 表示される結果、isna reset 公開クラスアリーナ お問い合わせ プライベートゲームステート = GameState. ウェイティング プライベート最終リストプレーヤー =新しいArrayList(); プライベートintカウントダウン = 10; パブリック void チェック() お問い合わせ スイッチ (state) { ケースWAITING -> { もし(players.size() >= MIN_PLAYERS(ミニプレイヤー) ステート = GameState. スタート; カウントダウン = 10; お問い合わせ お問い合わせ ケースの開始 -> { カウントダウン-; 放送カウントダウン(カウントダウン)。 もし(countdown { チェックWinCondition(); お問い合わせ ケース ENDING -> { 表示結果(); リセットアリーナ(); ステート = GameState. ウェイティング お問い合わせ お問い合わせ お問い合わせ お問い合わせ ステップ2:ECSコンポーネントでプレイヤーデータ Hytaleのエンティティ・コンポーネント・システムを使用して、ゲーム固有のデータをプレーヤー・エンティティティに添付します。 外部の を維持するよりもクリーナーです。 HashMap 地図 — データは、エンティティティティティリティ自体に住んでいます。 パブリッククラスミニゲーム プレイヤーの実装 コンポーネントとlt;EntityStore> { パブリックストリングアリーナ Id = ""; パブリックストリングチーム = ""; パブリックintキル = 0; 公の侵入死 = 0; パブリックintスコア = 0; パブリックボolean = true; 公共 長 最後の 死亡 = 0; @オーバーライド パブリックミニゲームプレイヤークローン() { ミニゲーム プレーヤーのコピー = 新しいMinigamePlayer(); コピー.arena Id = この.arenaId; コピー チーム = this.team copy.kills = このキル; copy.deaths = この.deaths; copy.score = このスコア; copy.alive = this.alive ; copy.lastDeath = この.last をコピーします。 死; コピーを返す; お問い合わせ お問い合わせ プレイヤーがアリーナに参加したときにこのコンポーネントをアタッチし、スコアリングとチームロジックのGameplay中に読み、退去時に削除します。 ステップ3:ゲームロジックのイベント処理 ミニゲームはプレイヤーアクションに反応する必要があります。 各タイプに適切なイベントシステムを使用する: イベント バスイベント(グローバル) ///>>>>>/>>/>>>>>>>>>>>>>>>>>>>>/>/>/> プレイヤーはサーバーに参加し、ロビーを表示 getEventRegistry().registerGlobal() PlayerReadyEvent.class は、 イベント -> TeleportToLobby(event.getPlayer()) ;;; // // // // プレイヤーの切断 — アリーナから削除 getEventRegistry().registerGlobal() プレイヤーDisconnectEvent.class, イベント -> handlePlayerLeave(event.getPlayer())) ;;; // // // // チャットコマンド — /join, /leave, /spectate getEventRegistry().registerAsyncGlobal() プレイヤーチャットイベント.class, 未来 -> Future.thenAccept(event -> {) 文字列msg = event.getMessage(); もし(msg.startsWith("/join")) お問い合わせ event.setCancelled(true) は、 handleJoinCommand(event.getSender()); ); お問い合わせ お問い合わせ ; ECS イベント(Entity-Specific) ブロックのブレーク、ダメージ、および他のエンティティティレベルアクションの場合は、EntityEventSystem サブクラス: ///>>>>>/>>>/>>>>>>>>>/>>>>>>>>>>>>>>>>>/>/>/>>>>>>>>/>>>>/>>>/>/> スコアリングのキルを追跡する パブリッククラス KillTracker エクステンション RefChangeSystem{ @オーバーライド パブリック void コンポーネント 追加(EntityStore store) 所属機関, デスコンポーネントの死) { // // // // Entity が死んだ — 殺人者、更新スコアを見つける Ref のキラー = 死.getKiller(); もし (killer != null) { ミニゲーム プレイヤーキラーデータ=getComponent() キラー、MinigamePlayer.class); もし(killerData != null) { キラー データキル ++; キラー データスコア += ログイン お問い合わせ お問い合わせ お問い合わせ お問い合わせ Remember: 検査フェーズではなく、filter フェーズでECSイベントをキャンセルする必要があります。 ロビーフェーズ中にブロックが破綻しないようにしたい場合は、アクションが実行される前に、フィルタはゲームの状態を確認し、キャンセルしなければなりません。 ステップ4:アリーナマネジメント 独立したプレイスペース(ハンガーゲーム、ベッドウォーズ)を必要とするゲームでは、アリーナインスタンスが必要です。 マルチアリーナパターン パブリッククラスのArenaManager お問い合わせ プライベート最終マップアリーナ=新しいHashMap(); 公共闘技場 createArena(String id, Location center) お問い合わせ アリーナ=新しいアリーナ(id、中心); isnas.put(id, isna); は、 リターンアリーナ; お問い合わせ 公共 闘技場 所蔵AvailableArena() お問い合わせ isnas.values().stream() を返します。 .filter(a -> a.getState() ==== ゲーム統計 ウェイティング .filter(a -> a.getPlayerCount() < a.getMaxPlayers())) .findFirst() .orElse(null); お問い合わせ パブリック void markAll() { isnas.values().forEach(Arena::tick)。 お問い合わせ お問い合わせ Arena Reset 各ゲームの後、アリーナは元の状態に戻る必要があります。 2つのアプローチ: スナップショット復元: ゲームが始まる前に、アリーナ地域のブロックデータを保存し、その後復元します。 より多くのメモリを使用するが、信頼できる。 プレファブリロード: Hytaleの組み込みのプレハブ システムを使用して、アリーナをプレハブ構造として保存し、各ゲーム後に再配置します。 Hytaleのネイティブツールと統合します。 ステップ5:チームとスコアリング チームアサイン public void 代入 チーム(アリーナアリーナ) お問い合わせ Listプレーヤー = isna.getPlayers(); コレクション。シャッフル(プレイヤー); String[] チーム = {"Red", "Blue", "Green", "Yellow"}; で (int i = 0; i < player.size(); お問い合わせ ミニゲーム プレイヤーデータ = getComponent() Player.get(i), MinigamePlayer.class); は、 data.team = チーム[i % team.length]; お問い合わせ お問い合わせ スコアボードディスプレイ Hytale の Message クラスを使用して、フォーマットされたスコアの表示を行います。 メッセージシステムでは、カラーフォーマット、太字/italicスタイル、パラメータ置換をサポートしています。 public void 放送 スコア(アリーナアリーナ) { 文字列Builder sb = new 文字列Builder("§6======= スコアボード ==\n; isna.getPlayers().stream() は、 .sorted((a, b) -> getScore(b) - getScore(a)) お問い合わせ ミニゲーム プレイヤーデータ = getComponent() p, MinigamePlayer.class ; sb.append(String.format("§f%s:§e%dは§7を殺します_ §a%d pts\n", p.getUsername()、data.kills、data.score)。 お問い合わせ isna.broadcast(sb.toString()); ; お問い合わせ ステップ6: 勝利条件 Common minigameの勝利条件とそれらを実装する方法: Game TypeWin ConditionCheck In Last Manスタンディング1プレーヤー/チームアライブDeathハンドラー — ライブプレーヤー数 コアターゲット スコアの更新 — threshold をチェックする Time Limit 期限が切れるときに最も高いスコアGameティック — タイマー オブジェクト 完全な特定のタスク(キャプチャフラグ、ベッドを破壊)客観的な相互作用のためのカスタムECSイベント Rounds N ラウンドのベスト ラウンドエンドハンドラ — シリーズのスコア ステップ7:マッチメイキングとキューイング 複数の同時ゲームを実行しているサーバーの場合、キューシステムを実行します。 パブリッククラスのマッチメイキング お問い合わせ プライベートファイナル Queue キュー = 新しいLinkedList(); プライベートファイナルイント必須 プレイヤー パブリック void addPlayer(PlayerRef プレーヤー) { queue.add(プレイヤー); チェックイン お問い合わせ プライベート void checkQueue() もし(queue.size() >=必須プレイヤー) お問い合わせ アリーナ = isnaManager.findAvailableArena(); もし (rena != null) { (int i = 0; i < 必須) プレイヤー、i++ PlayerRef プレーヤー = queue.poll(); isna.addPlayer(プレイヤー); お問い合わせ お問い合わせ お問い合わせ お問い合わせ お問い合わせ Hytale の組み込み Party System は、サーバーの転送をグループ化し、サーバーの転送全体に滞在できるようにします。 マッチメイキングはパーティーグループを尊重し、パーティーメンバーを一緒にキューに入れ、可能であれば同じチームに配置する必要があります。 ミニゲーム Mod を Study に追加 CurseForge: で既にあることを調べて、ゼロからビルドしないでください。 Mod タイプ Study の主な特徴 ハンガーゲームLast Man Standingマルチアリーナ管理、ロビーシステム、カウントダウン、PvPフェーズ、オートリセット BossArena PvE アリーナNPC コントラクトショップ、per-player loot チェスト、設定可能な上司 Wave Combat ArenasHorde ModeWave spawning、難易度スケーリング、報酬システム SkyblockIsland SurvivalPer-playerの世界インスタンス、進行状況追跡、上司は Hunger Games mod は、特に勉強する価値があります。競争のミニゲームの完全なライフサイクル:ロビー → カウントダウン → PvP → デッドマッチ → 結果 → リセット. ミニゲームサーバ向けプラットフォーム機能搭載 Hytale は、Minecraft サーバーが次のプラグインを必要とするボックスからいくつかの機能を提供しています: Discovery カタログ: メインメニューに組み込まれたプレイヤーは、外部リストサイトなしでミニゲームサーバーを見つけることができます パーティシステム: ネイティブな友人が、サーバーの転送を横断するグループ化 決済ゲートウェイ: 化粧品や perks を収益化したいサーバーのクライアントに構築 パーミッションフレームワーク: ユーザーレベル、グループベース、ワイルドカード権限マッチング 採用チェックリスト JAR: ビルド ローカルテスト: %AppData%/Roaming/Hytale/UserData/Mods/ にドロップ 複数のクライアントのテスト: 更新 4 は複数の Hytale インスタンスを 1 つの PC で許可します。 — ローカルでマルチプレイヤーのシナリオをテストします。 サーバーへのDeploy: JARを/opt/hytale/Server/mods/にアップロードする CurseForge で公開: 適切な manifest.json を持つプラグインとしてパッケージ化 サーバの一覧: HytaleCharts に に追加して、プレイヤーはあなたを見つけることができます 基本プラグイン API の概念では、このガイドが構築されています。