Hytale의 Custom Minigames 구축 방법: 서버 개발자의 가이드

작성자 HytaleCharts Team 범주: : 이름 : 분 최소 읽기

Hytale에서 다음 Bed Wars 또는 Hunger Games를 구축하고 싶습니까? 이 가이드는 게임 상태 기계 및 arena 관리에서 ECS 기반 플레이어 추적, 매칭 및 배포에 이르기까지 전체 워크플로우를 다룹니다. 기존 CurseForge minigame mods에서 실제 예제를 포함합니다.

Hytale's server-side Architecture는 사용자 정의 미니게임에 독특하게 적합합니다. 게임 모드 플러그인이 vanilla sandbox, Hytale 's 플러그인 API 및 ECS에 대한 싸움이 당신에게 엔티티티티 행동, 세계 상태, 게임 흐름을 통해 직접 제어를 제공합니다. Bukkit minigames를 구축 한 경우, 개념 번역 — 하지만 구현은 클리너입니다. 이 가이드는 핵심 시스템의 모든 미니 게임 요구 사항을 다룹니다: 게임 상태 관리, 경기장 인스턴스, 플레이어 추적, 득점, 매칭, 및 배포. Architecture: How Minigame Plugins work in Hytale Before diving into code, 히스토리 미니게임의 고급 아키텍처를 이해: Layer목적Implementation 게임 관리자Orchestrates 모두 — arenas를 생성, 로보비 관리, 경로 플레이어Singleton 서비스 플러그인 Arena 인스턴스 자신의 국가, 플레이어 및 세계 지역과 함께 하나의 실행 게임 세션세계 또는 지역 관리 Game State Machine단계 흐름 제어 - 대기, 카운트다운, 재생, 종료Enum + 타이머 논리 per arena Player DataTracks per-player state — score, team, live/dead, 통계ECS 플레이어 엔티티티에 부착 된 구성 요소 이벤트 핸들러 React to Player action — kills, block breaks, zone entryEventBus + ECS 이벤트 시스템 단계 1: 게임 주 기계 모든 minigame는 국가 기계를 필요로 합니다. 이것은 어떤 일이 일어나는 일과 언제 제어하는 백본입니다. public enum 게임스테이트 이름 * WAITING, // 로비, 플레이어 기다리고 있습니다. STARTING, // 게임이 시작되기 전에 카운트다운 재생, // 게임 플레이 DEATHMATCH, // 선택 사항: 최종 결과 단계 런닝 // 게임, 결과보기 자주 묻는 질문 Each arena 인스턴스는 자체 GameState를 보유하고 있습니다. 전환은 조건에 따라 발생합니다. WAITING → 시작: 최소 플레이어 수 도달 STARTING → 재생: 카운트다운 타이머는를 만료합니다. PLAYING → DEATHMATCH: 시간 제한 또는 플레이어 임계 값 PLAYING/DEATHMATCH → 종료: Win 상태 충족 (마지막 플레이어 살아, 점수 도달, 등) 엔딩 → WAITING: 표시된 결과, arena 재설정 공동 클래스 아레나 이름 * 개인 GameState 상태 = GameState. 회의; 개인 최종 List 플레이어 = new ArrayList(); 개인 int 카운트 다운 = 10; 공개 void tick() 이름 * 스위치 (state) { 사례 연구 if (players.size() >= MIN_PLAYERS (으)로 이동 상태 = GameState. 시작; 카운트 다운 = 10; 이름 * 이름 * 케이스 시작 -> { 카운트다운-; 방송Countdown(countdown); if (countdown { 표시결과(); resetArena(); 상태 = GameState. 회의; 이름 * 이름 * 이름 * 자주 묻는 질문 Step 2: ECS 구성 요소와 플레이어 데이터 Use Hytale's Entity Component System을 사용하여 게임별 데이터를 플레이어에 부착합니다. 외부 를 유지하는 것보다 클리너입니다. HashMap maps — 데이터는 기업의 자체에 살고 있다. 공석 미니게임 Player 구현 컴포넌트 { 공공 문자열 arena 나는 = "; public String 팀 = "; 공공 int kills = 0; 공중 int 죽음 = 0; 공개 int 점수 = 0; boolean 살아 = true; 공공 오래 지속 죽음 = 0; @Override의 장점 MinigamePlayer 복제() { 미니게임 플레이어 복사 = new MinigamePlayer(); 복사.arena 나는 = this.arenaId; 이름 * 팀 = this.team; copy.kills = 이.kills; copy.deaths = 이.deaths; 복사.score = this.score; copy.alive = this.alive; copy.lastDeath = 마지막으로 죽음; 반환 사본; 이름 * 자주 묻는 질문 선수가 경기장에 합류 할 때이 구성 요소는 스코링 및 팀 논리에 대한 게임 플레이 중에 읽고, 떠나면 제거. Step 3: 게임 논리에 대한 이벤트 처리 Minigames는 플레이어 행동에 반응해야합니다. 각 유형에 적합한 이벤트 시스템을 사용합니다: 행사 버스 이벤트 (Global) // Player는 서버에 가입 — 로비를 표시 getEventRegistry().register글로벌() PlayerReadyEvent.class는, 이벤트 -> teleportToLobby(event.getPlayer) · // Player breaks – arena에서 제거 getEventRegistry().register글로벌() PlayerDisconnectEvent.class는, 이벤트 -> handlePlayerLeave(event.getPlayer) · // 채팅 명령 - /join, /leave, /spectate getEventRegistry().registerAsyncGlobal(()를 호출합니다. PlayerChatEvent.class는, 미래 -> 미래.thenAccept(event -> { 문자열 msg = event.getMessage(); 만약 (msg.startsWith("/join")) 이름 * event.setCancelled (true); handleJoinCommand (event.getSender()); 이름 * 사이트 맵 ); ECS는 이벤트 (Entity-Specific) 블록 브레이크, 손상 및 기타 엔터프라이즈 레벨 동작을 위해 EntityEventSystem subclasses를 생성합니다. // scoring에 대한 트랙 킬 공공 클래스 KillTracker 기타 제품 RefChangeSystem { @Override의 장점 공개 void onComponent 추가(EntityStore 저장소, 회사 소개 사망자 사망자 // Entity 일어난다 — killer, 업데이트 점수 Ref killer = 죽음.getKiller(); if (killer != null) { 미니게임 Player killer데이터 = getComponent(을) 킬러, MinigamePlayer.class); if (killerData != null) { 뚱 베어 데이터.kills++; 뚱 베어 데이터.score += KILL_POINTS는 이름 * 이름 * 이름 * 자주 묻는 질문 회원: ECS 이벤트는 검사 단계가 아닌 filter 단계에서 취소해야합니다. 로비 단계에서 차단을 방지하려면 필터가 게임 상태를 확인하고 행동이 실행되기 전에 취소해야합니다. Step 4: 아레나 관리 고립된 놀이 공간 (Hunger Games, Bed Wars)가 필요한 게임의 경우, 당신은 arena 인스턴스가 필요합니다: Multi-Arena 패턴 공동 클래스 ArenaManager 이름 * 개인 최종 Map arenas = 새로운 HashMap(); public Arena createArena(String id, 위치 센터) 이름 * 아레나는 = new Arena(id, center); arenas.put (id, arena); 반환 isna; 이름 * 공공의 아레나 findAvailableArena() 이름 * 반환 arenas.values().stream() .filter(a -> a.getState() == 게임 전략. 관련 상품 .filter(a -> a.getPlayerCount() < a.getMaxPlayers()) .findFirst ()를 .orElse (null); 이름 * 공개 void tickAll() { arenas.values().forEach(아레나::tick); 이름 * 자주 묻는 질문 Arena 재설정 각 경기 후, the arena는 원래 상태로 돌아갈 필요가있다. 두 가지 접근법: Snapshot 복원: 게임 시작 전에 arena 지역의 블록 데이터를 저장하고 나중에 복원하십시오. 더 많은 메모리를 사용하지만 신뢰할 수 있습니다. Prefab 재부팅: Hytale의 내장 Prefab 시스템을 사용하여 조립식 구조로 arena를 저장하고 각 게임 후에 다시 배치하십시오. 클리너 및 Hytale의 기본 도구와 통합합니다. 5 단계: 팀과 득점 팀 할당 public void 할당 팀 (아레나 arena) 이름 * List 플레이어 = isna.getPlayers(); Collections.shuffle(플레이어); String[] 팀 = {"Red", "Blue", "Green", "Yellow"}; (int i = 0; i < players.size(); ₢ 킹 미니게임 플레이어 데이터 = getComponent( players.get (i), MinigamePlayer.class; data.team = 팀[i % team.length]; 이름 * 자주 묻는 질문 Scoreboard 디스플레이 Use Hytale's Message 형식의 점수 표시를 위한 클래스. 메시지 시스템은 색상 포맷, 대담한/이탈리아 스타일 및 매개 변수 대체를 지원합니다: public void 방송 점수 (Arena arena) { StringBuilder sb = 새로운 StringBuilder("§6==== 득점판 ===\n"); arena.getPlayers().스트림() .sorted((a, b) -> getScore(b) - getScore(a)) .forEach(p -> { 미니게임 플레이어 데이터 = getComponent( p, MinigamePlayer.class;에 대 한 sb.append(String.format("§f%s: §e%dd §7| §a%d pts\n", p.getUsername(), data.kills, data.score); 으로 arena.broadcast(sb.toString()); 자주 묻는 질문 단계 6: 승리 조건 Common minigame win 조건 및 구현 방법 : 게임 타입Win 조건체크인 마지막 남자 서 있는1 플레이어/팀 라이브Death 핸들러 - 라이브 플레이어 스코어 대상초점 점수 업데이트 — 체크 임계값 시간 제한 시간 만료시 가장 높은 점수Game tick — check timer Objective에 대하여 특정 작업을 완료 (캡쳐 플래그, 파괴 침대)사용자 정의 ECS 이벤트 대상 상호 작용 라운드 N roundsRound end 핸들러 - 체크 시리즈 점수 Step 7 : 매치메이킹 및 큐 여러 동시 게임을 실행하는 서버의 경우, 큐 시스템 구현: 공석 매칭 이름 * 개인 최종 Queue 큐 = 새로운 LinkedList< & gt;(); 개인정보 보호정책 선수; public void addPlayer(PlayerRef 플레이어) { queue.add(플레이어); 체크쿼시(); 이름 * 개인 void checkQueue() { if (queue.size() >=필수Players) 이름 * 아레나 isna = isnaManager.findAvailableArena(); if (arena != null) { (int i = 0; i