본문으로 건너뛰기
5분 AI.
TRENDSHIFT #8 딥다이브 · 2026-10-25 분석

ludovic111/horizon 딥다이브
— Minecraft를 Rust로 다시 쓰고, 원본과 숫자 단위로 대조하는 법

앱

빠른 판단

무엇
Minecraft Java 26.3을 Rust(wgpu)로 다시 쓴 비공식 게임·런처·서버. 원본 대조 하네스 300여 개로 검증
이럴 때
정품 Minecraft 26.3이 있을 때 Rust판 게임을 돌리거나, 원본과 대조하는 차분 테스트·WASM 모드·MCP 조작 구조를 배울 때
입력
사용자가 가진 Minecraft Java 26.3 설치본과 JDK 25(리소스 준비 1회)
결과
플레이 가능한 게임 클라이언트·전용 서버·런처
도입 전 확인
Microsoft 계정 로그인이 없어 온라인 모드 서버에는 접속 불가. 정품 파일 필요, 준비 결과(.local/) 공유 금지
Horizon은 Minecraft: Java Edition 26.3을 Rust(wgpu)로 다시 구현한 비공식 게임입니다. 같은 월드 파일을 읽고, 같은 규칙으로 움직이고, 같은 지형을 만드는지를 원본 게임을 직접 돌려 얻은 결과와 비교하는 테스트(하네스) 326개로 확인합니다. 게임 본체 외에 런처, 서버, WebAssembly 모드 시스템, AI 에이전트가 게임을 조작하는 horizon-ctl(MCP 지원)까지 한 저장소에 있습니다. 이 글은 커밋 00705d8(2026-10-25)을 읽기만 해서 썼고, 빌드나 실행은 하지 않았습니다.

추가 검토 · fa093994 · 2026-10-25

아래 본문은 00705d8의 최초 분석을 보존했습니다. 코드·파일 수, 하네스 326개와 당시 최신 게임 릴리스 v0.2.50 표기는 그 시점의 관측값입니다. 추가 검토는 fa093994ae5c3618acb87bb1c7711fda9e3ec93f까지의 차이를 읽은 결과이며, 전체 수치를 새로 측정하거나 게임을 실행한 결과는 아닙니다.

릴리스 추가 관측: 최초 표 이후 v0.2.51이 2026-10-25 07:15 UTC에 공개됐습니다. 제작자 변경 기록에는 서버 전환·피격 화면·낙하 아이템/블록·렌더링·IPv4 우선 연결 수정이 있습니다. 이 릴리스와 위 기본 브랜치 소스 검토는 서로 다른 기준이며, 성능·호환성을 직접 재현하지 않았습니다.

목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

게임을 새로 만든 것이 아니라, 이미 있는 게임을 “같은 답이 나오게” 다시 쓴 프로젝트

Horizon은 Minecraft Java 26.3과 같은 월드·규칙·지형을 내도록 Rust로 처음부터 다시 쓴 게임이며, 게임 파일은 한 줄도 들어 있지 않고 사용자가 가진 정품 파일에서 리소스를 만들어 씁니다. README는 무료·오픈소스·비공식이며 Mojang이나 Microsoft과 관련이 없다고 밝힙니다. 라이선스는 MIT(프로젝트 고유 코드에 한함)입니다.

저장소는 게임 하나가 아니라 네 갈래입니다. 게임 클라이언트(crates/horizon-client), 전용 서버(horizon-server), 설치와 업데이트를 맡는 런처(launcher/), 그리고 모드·모드팩·에이전트 조작 같은 확장입니다.

핵심 비유

원본 악보를 보면서, 연주를 녹음해 파형까지 맞춰 보는 복제 연주

보통의 “마인크래프트 같은 게임”은 비슷한 분위기를 내면 성공입니다. Horizon은 같은 악보(원본 동작)를 연주한 뒤 두 녹음의 파형을 겹쳐 보는 방식입니다. 파형이 어긋나면 틀린 쪽을 고칩니다.

여기서 악보는 원본 게임의 동작, 연주는 Rust 코드, 파형 비교는 “하네스”라는 자동 비교 테스트입니다.

용어 먼저
차분 테스트(differential testing)
같은 입력을 두 구현(원본과 새 구현)에 넣고 출력이 같은지 비교하는 테스트입니다. 정답표를 미리 만드는 대신 “원본이 곧 정답”이 됩니다. 이 프로젝트의 원본 쪽 실행기를 오라클(oracle)이라고 부릅니다.

1-1. 한눈에 보는 구성 요소

구성위치하는 일
게임 클라이언트crates/horizon-client창·입력·렌더링·월드 틱·UI. 내장 서버(싱글플레이)와 --dedicated 서버 모드 포함
월드 데이터crates/horizon-worldNBT, 리전 파일, 청크, 데이터 픽서, 월드 생성, 블록 동작
기초 연산crates/horizon-coreJava 난수, HotSpot과 같은 Math, 노이즈, 팔레트 저장소
네트워크crates/horizon-protocol프로토콜 777 패킷 코덱
런처launcher/GPUI 기반 설치·업데이트·서버 관리·모드 브라우저
모드crates/horizon-mods · horizon-mod-sdkWebAssembly 컴포넌트 모드의 실행기와 SDK
에이전트 조작horizon-ctl게임 상태를 JSON으로 읽고 플레이어처럼 행동하는 CLI + MCP 서버
검증 도구tools/ · mods/horizon/…/parityPython 하네스 326개와 Java 오라클

이 저장소에서 배울 핵심은 “큰 시스템을 다시 쓸 때 원본을 정답지로 삼아 기계적으로 대조하는 작업 방식”입니다.

추천 독자
Rust 중급 이상이고, 대형 코드베이스의 구조가 궁금한 개발자

게임을 직접 돌리려면 정품 Minecraft가 필요합니다. 하지만 읽기만 해도 하네스 설계, 부동소수점 재현, 모드 샌드박스 같은 주제를 배울 수 있습니다.

2왜 주목받는가

“다시 쓴 게임”이라는 소재와, 이를 검증하는 방식의 집요함

2026-10-25 GitHub 기준 스타 1,328개, 포크 90개이며 TrendShift 순위 8위로 잡혔습니다. 저장소는 2026-10-03에 만들어졌고 최신 릴리스는 게임 v0.2.50, 런처 launcher@0.2.6입니다. 만든 지 22일 만에 이 규모라는 점, 최근 푸시가 분석 당일 아침이라는 점에서 개발 속도가 매우 빠릅니다. 스타 수는 관심도일 뿐 품질 지표가 아닙니다.

2-1. 주목받는 이유를 코드에서 확인한 것

AI가 코드를 쏟아내는 시대에 “원본과 대조하는 자동 심판”을 먼저 세우는 것이 이 프로젝트를 가능하게 한 설계로 보입니다.

읽을 때 주의
숫자와 문서가 서로 다른 시점을 가리킨다

README는 “281 differential harnesses”(2026-10-13 감사 기준)라고 쓰지만, 이번 커밋의 tools/에는 하네스 스크립트가 326개이고 CLAUDE.md는 “324개”와 “329개(2026-10-23 측정)”를 함께 씁니다. 하루에도 늘어나는 숫자라 문서마다 시점이 다릅니다. 또 docs/world-generation.md는 “완전한 지형 생성은 아직”이라고 적혀 있어 README의 100%와 맞지 않는데, 오래된 문서가 남은 것으로 보입니다. 이 글의 수치는 커밋 00705d8에서 직접 센 값을 우선합니다.

한계
온라인 서버에는 아직 못 들어간다

README의 Known issues와 현황 표대로, Microsoft 계정 로그인이 없어 계정을 검증하는 서버에는 접속할 수 없고 오프라인 모드 서버·LAN만 됩니다. Java 모드 jar도 실행되지 않으며 Horizon 전용 모드만 지원합니다. “100%”는 하네스가 비교하는 범위의 100%이며 모든 차이가 없다는 증명이 아니라고 README가 직접 밝힙니다.

3기술 스택 전체 지도

Rust가 중심이고, Python과 Java는 검증 도구로만 쓴다

CLAUDE.md의 규칙은 “플레이어가 실행하는 것은 모두 Rust, Python/Java는 tools/의 개발 도구와 하네스 드라이버에만”입니다. 추적 파일 3,110개 중 확장자별로 Rust 1,548개, Python 474개, JSON 358개, Java 304개입니다.

3-1. 코드 규모 (커밋 00705d8, 물리 줄 수)

구분줄 수비고
Rust 전체693,694git ls-files '*.rs' 전체. 테스트·예제 포함
horizon-client368,479src/ 아래 Rust 파일 549개, 그중 게임 바이너리 game/ 189개
horizon-world162,538worldgen/ 125개 파일, datafix/ 22개 파일
launcher28,341별도 워크스페이스
horizon-core19,531
horizon-protocol10,425
Python (tools/)67,449하네스·드라이버
Java42,982원본 동작을 뽑아내는 오라클. 원본 게임에 컴파일해 붙이는 방식

3-2. 영역별 스택

영역사용 기술근거
렌더링wgpu 30.0.1(Vulkan·Metal), naga(WGSL), winit 0.30.13, glamcrates/horizon-client/Cargo.toml. 셰이더는 .wgsl 12개
오디오cpal 0.16(선택 기능), symphonia(ogg·vorbis)같은 파일. --no-default-features로 오디오·컨트롤러를 뺀 서버 빌드
데이터serde_json(raw_value), flate2(zlib-rs), sha1·sha2NBT·리전 압축, 서버 리소스 팩 SHA-1 검증
모드wasmtime 36 + 컴포넌트 모델, wit-componentcrates/horizon-mods/Cargo.toml
런처 UIgpui 0.2.2, ureq, clap, self-replacelauncher/Cargo.toml
서명 업데이트horizon-release-sign, minisign 검증docs/security.md의 서명된 체크섬
검증Python 3.10+, JDK 25, unittestREADME의 요구사항
CIGitHub Actions 8개: ci · parity · nightly · release · launcher 등.github/workflows/
웹사이트website/(playhorizon.dev), Caddyfile·Dockerfile파일 존재만 확인. 내용은 읽지 않음

워크스페이스는 edition 2024, 릴리스 프로파일은 lto = "thin", codegen-units = 1입니다. 빠른 반복용 fast 프로파일(LTO 없음, 코드 생성 단위 16)이 따로 있습니다. 또 third_party/wgpu-hal은 특정 Intel 윈도우 드라이버 크래시를 피하려고 wgpu-hal 30.0.1을 패치해 넣은 사본이며, 업스트림 수정이 나오면 지우라는 주석이 있습니다.

4아키텍처 심화 분석

크레이트 지도, 검증 루프, 부동소수점, 모드 샌드박스

4-1. 전체 구조

┌──────────────── launcher/ (GPUI) ────────────────┐ │ 설치·업데이트·서버 페이지·모드 브라우저·MCP │ └───────────────┬──────────────────────────────────┘ │ 실행 ┌──────────────────────────────▼──────────────────────────────┐ │ horizon-client (lib 평면 모듈 약 190 + bin game.rs·game/)│ │ 창·입력 · gfx(wgpu) · 메시 · 모브 AI · UI · 내장 서버 │ │ --dedicated → 헤드리스 서버 control.rs → horizon-ctl │ └───┬───────────┬───────────┬──────────────┬──────────────────┘ │ │ │ │ horizon-world horizon- horizon- horizon-mods (wasmtime) (NBT·청크· protocol assets ↑ WIT: horizon:mods@0.1.0 worldgen· (777) (모델·아틀라스) 블록 틱) │ horizon-core (Java Random · jmath · 노이즈 · 팔레트 저장소 · 버전 상수) [검증 쪽] tools/test_*_parity.py ──┬─▶ Java 오라클 (원본 26.3 jar에 붙여 실행) └─▶ Rust probe (examples/*_probe.rs 등) └─ 두 JSON을 비교

한 가지 특이점은 클라이언트가 Game 구조체 하나(필드 약 290개, 비공개)에 모든 상태를 두고, 메서드를 game/<기능>.rs 파일 약 180개에 impl Game 블록으로 나눠 놓는다는 점입니다(CLAUDE.md). 기능을 찾을 때는 fn tick_<기능>을 검색하라고 안내합니다. 라이브러리 쪽은 Game을 볼 수 없고, 바이너리가 horizon_client::<모듈>으로 가져다 씁니다.

4-2. 핵심 설계 패턴

패턴설명실제 위치
원본 시그니처 1:1 이식루트 Cargo.toml 주석: 포트는 원본 Java의 시그니처·인덱스 루프·중첩 제네릭을 그대로 따라가 디컴파일 소스와 대조할 수 있게 한다. 그래서 clippy의 too_many_arguments 등을 허용[workspace.lints.clippy]
하네스 3종 세트하네스(Python) + 오라클(Java) + probe(Rust). 두 쪽 출력 JSON을 비교tools/test_*_parity.py
오라클 결과 캐시java·javac 앞에 끼워 넣는 shim이 명령줄·입력 파일 해시가 같으면 이전 결과를 재사용. Rust만 바꾼 변경은 Rust 쪽 비용만 낸다tools/parity_shim.py
영향 범위 선택 실행parity.py --changed origin/main이 바뀐 파일에 영향받는 하네스만 고른다. 문서 기준으로 horizon-core 파일 하나를 고치면 약 119개가 다시 돈다CLAUDE.md, docs/architecture.md
기능 권한(capability) 샌드박스모드는 WASM 컴포넌트이고, 쓰는 인터페이스를 매니페스트에 선언해야 한다. 선언 안 한 것을 import하면 게임이 거부crates/horizon-mod-sdk/wit/horizon.wit
공개 트리 가드게임 jar·에셋·디컴파일 소스가 커밋되지 않게 git hook과 CI가 거부tools/check_public_tree.py

4-3. 같은 수식을 같은 비트로: jmath.rs

Rust의 f64::sin은 플랫폼의 libm을 부르고, 거기서는 마지막 비트가 달라지는 경우가 있습니다. 원본 Java는 HotSpot이 일부 Math 메서드를 CPU별 intrinsic으로 바꿔서, 이 결과도 머신마다 다릅니다. 파일 머리말은 이를 이렇게 정리합니다.

// crates/horizon-core/src/jmath.rs (발췌)
pub fn sin(x: f64) -> f64 {
    if cfg!(target_arch = "aarch64") {
        aarch64::sin(x)      // HotSpot의 AArch64 intrinsic과 같은 계산
    } else {
        x.sin()              // x86-64: 플랫폼 libm
    }
}

그래서 규칙은 “원본의 Math 호출은 horizon_core::jmath로, 난수는 horizon_core::random으로, 난수는 원본과 같은 순서로 뽑는다”입니다(CLAUDE.md). 월드 생성이 시드 하나로 원본과 같은 지형을 내려면 이 수준이 필요합니다.

“비슷하게 동작”과 “비트 단위로 같은 결과”는 전혀 다른 난이도이며, Horizon은 후자를 목표로 비용을 치릅니다.

4-4. 하네스 한 개는 어떻게 생겼나

tools/test_composter_parity.py는 퇴비통이 설계 목적인 하네스입니다. 무작위 채움 레벨의 퇴비통에 대해 네 가지 동작(플레이어 우클릭, 위 호퍼가 넣기, 아래 호퍼가 꺼내기, 드로퍼가 투입)을 만들고, 양쪽이 블록 변화·컨테이너 내용·생성된 아이템·소리·게임 이벤트·플레이어 통계·레벨 난수 상태까지 출력해 비교합니다. 케이스 생성부는 시드를 받는 random.Random이라 재현할 수 있습니다.

def cases(facts, items, count, seed):
    rng = random.Random(seed)
    modes = ['use', 'use', 'hopper_in', 'hopper_out', 'dispense']
    for n in range(count):
        mode = modes[n % len(modes)]
        ...

4-5. 모드: 인터페이스는 WIT 한 파일

horizon.wit의 패키지는 horizon:mods@0.1.0입니다. 인터페이스 log는 항상 허용되고, 나머지(game, chat, hud 등)는 매니페스트에 선언해야 하는 권한입니다. 예제 모드 coords-hud의 매니페스트는 다음과 같이 세 가지만 요청합니다.

id = "coords_hud"
api = "0.1"
side = "client"
capabilities = ["game-read", "hud", "chat"]
비유

앱이 처음 설치될 때 “위치, 알림 권한 허용”을 묻는 스마트폰과 비슷합니다. 모드가 쓰려는 권한이 플레이어에게 먼저 보이고, 선언하지 않은 능력은 쓸 수 없습니다.

5디렉토리 구조 해부

최상위 폴더 10여 개 중 어디를 먼저 열어야 하나
horizon/ ├── Cargo.toml # 워크스페이스(멤버 25, launcher 등은 exclude), 린트·프로파일 ├── research-lock.json # 지원하는 원본 버전(26.3)의 매니페스트 SHA-1 등 고정값 ├── CLAUDE.md / AGENTS.md # 에이전트용 지도: 크레이트·기능→파일 표 ├── crates/ # 23개 크레이트 │ ├── horizon-client/ # 게임 (lib ~190+ 모듈, bin game.rs + game/) │ ├── horizon-world/ # NBT·리전·datafix·worldgen·level(블록 동작) │ ├── horizon-core/ # jmath · random · 노이즈 · version.rs │ ├── horizon-protocol/ # 프로토콜 777 │ ├── horizon-mods/ horizon-mod-sdk/ cargo-horizon-mod/ # 모드 │ └── horizon-server/ horizon-friends/ horizon-relay/ ... ├── launcher/ # GPUI 런처 (별도 워크스페이스) ├── tools/ # Python 하네스 326개 + parity.py · pr_ready.py · lab.py ├── mods/horizon/…/dev/horizonlab/parity/ # Java 오라클 ├── tests/ # Python 단위 테스트 ├── docs/ # 아키텍처·모드·호스팅·보안·릴리스 흐름 ├── website/ # playhorizon.dev ├── third_party/wgpu-hal # 패치한 wgpu-hal 사본 └── .local/ # (gitignore) 사용자 정품 파일에서 만든 리소스. 커밋 금지

5-1. 처음 열어볼 파일 순서

순서파일이유
1README.md무엇이 되고 안 되는지, 상태 표
2CLAUDE.md크레이트 지도와 “기능 → 파일” 표. 이 저장소 전체를 탐색하는 가장 좋은 입구
3docs/architecture.md최근 30일 가장 자주 바뀐 40개 영역과 각각의 파일·검사 하네스
4crates/horizon-core/src/jmath.rs정확도에 대한 이 프로젝트의 태도가 가장 잘 보이는 617줄
5tools/test_composter_parity.py하네스 한 개를 끝까지 읽기
6crates/horizon-mod-sdk/wit/horizon.wit모드가 쓸 수 있는 능력의 전체 목록

5-2. 이식할 때 쓰는 이름 규칙

docs/architecture.md는 영역을 L/(crates/horizon-client/src/), G/(…/src/game/), W/(crates/horizon-world/src/)로 줄여 부릅니다. 예를 들어 월드 생성은 W/worldgen/과 L/vanillagen.rs, 이를 검사하는 하네스는 chunk_generation, feature_graph 등입니다. 하네스 이름은 tools/test_<이름>_parity.py로 대응됩니다.

6학습 포인트 (기술별)

읽기만 해도 얻는 것과, 손으로 해볼 아이디어

6-1. 기술별로 배울 것

주제어디를 보나배울 점
차분 테스트 설계tools/test_*_parity.py, parity_shim.py오라클 결과 캐시와 입력 해시로 반복 비용을 줄이는 법
재현 가능한 난수horizon-core/src/random*, jmath.rsJava 난수와 수학 함수를 Rust에서 비트까지 맞추기
월드 포맷horizon-world의 NBT·region·datafixAnvil 리전 파일과 DataFixer로 구버전 세이브(1.8~26.2)를 올리는 방식
GPU 렌더링horizon-client/src/gfx*, *.wgslwgpu로 청크 메시·컬링·반투명 처리를 구성하는 법
프로토콜horizon-protocol패킷 코덱·암호화·상태 머신(핸드셰이크→로그인→설정→플레이)
WASM 샌드박스horizon-mods, horizon.witwasmtime 컴포넌트 모델로 권한을 선언형으로 관리
에이전트 조작면horizon-ctl, docs/horizon-ctl-commands.md명령표 하나에서 CLI와 MCP 도구와 문서를 함께 생성
저작권 경계 지키기tools/check_public_tree.py금지 확장자·폴더를 hook과 CI에서 거부하는 방식
AI 에이전트 운영CLAUDE.md, docs/security.md에이전트가 쓴 글에 표식을 달고, 실제 사용자 데이터 폴더를 건드리지 못하게 하는 규칙

6-2. 에이전트 조작: 같은 명령을 CLI와 MCP로

docs/horizon-ctl-commands.md는 명령표에서 자동 생성된 문서라고 첫 줄에 적혀 있습니다. 한 표에서 CLI 명령, MCP 도구 이름(find-block → find_block), 인자 설명이 함께 나옵니다. README의 예시는 다음과 같습니다.

horizon-ctl launch --world Survival --seed 5 --wait
horizon-ctl state                       # 위치, 체력, 허기, 바라보는 대상, 화면...
horizon-ctl find-block birch_log
horizon-ctl goto -0.5 65 -2.5 --near 2.5
horizon-ctl break -1 65 -3              # 캐고, 떨어진 아이템을 응답으로 돌려줌

명령은 동작이 끝날 때까지 기다렸다가 결과를 JSON으로 돌려주고, 오류는 종류별 종료 코드로 구분됩니다(README). 리눅스·macOS는 Unix 소켓, Windows는 토큰이 있는 localhost 포트로 통신합니다.

흥미로운 설계
“No AI” 스위치

crates/horizon-core/src/no_ai.rs는 게임의 horizon-extras.txt에 noAi: true 한 줄이 있으면 컴패니언, 제어 소켓, horizon-ctl, MCP 서버, 런처의 AI 기능을 모두 끄는 단일 설정입니다. AI 조작면이 있는 도구는 그것을 한 번에 끄는 장치가 필요하다는 좋은 예입니다.

6-3. 실습 아이디어

7하드웨어 / 시스템 요구사항

플레이와 소스 빌드는 요구사항이 다르다

7-1. 플레이(런처 설치)

항목요구사항출처
OSLinux x86-64 · macOS(Apple Silicon) · Windows x64README Download
GPULinux·Windows는 Vulkan 지원 GPU, macOS는 Apple SiliconREADME
정품 게임Minecraft: Java Edition 26.3을 한 번 실행한 설치본(공식 런처·Prism·MultiMC 등)README
JavaJDK 25 — 처음 리소스를 준비할 때 한 번만README

7-2. 소스 빌드(개발자)

항목요구사항메모
RustREADME는 1.90 이상. Cargo.toml의 rust-version은 1.85문서와 선언값이 다르니 README 쪽을 따르는 게 안전
Python3.10 이상하네스·도구용
JDK25리소스 준비 단계와 오라클용
Linux 패키지libasound2-dev libudev-dev(Debian·Ubuntu)오디오·컨트롤러. --no-default-features로 생략 가능
개발 환경하네스는 Linux에서 개발·실행README
법적·정책 확인
정품 파일이 없으면 게임이 시작되지 않는다

README는 Horizon이 게임 파일을 포함하지도, 내려받지도 않는다고 합니다. 리소스는 사용자 본인 설치본에서 만들고(research-lock.json의 체크섬으로 검증), 결과는 gitignore된 .local/에 둡니다. 이것을 공유하거나 커밋하면 안 된다고 명시합니다. Minecraft EULA에 대한 판단은 이 글이 하지 않으며, 사용 전 직접 확인하세요.

8직접 해볼 수 있는 실습 과제

정품 Minecraft 없이도 되는 과제부터 순서대로
과제 1 · 입문 정품 불필요

저장소를 읽으며 지도 만들기

클론한 뒤 빌드하지 않고 CLAUDE.md의 “horizon-client: where things live” 표에서 관심 기능 하나(예: Mobs)를 골라, 표에 적힌 파일을 열어 모듈 구성을 한 장으로 그려 봅니다.

git clone https://github.com/ludovic111/horizon.git
cd horizon
ls crates tools | head -50
git ls-files 'tools/test_*_parity.py' | wc -l
과제 2 · 입문 정품 불필요

공개 트리 검사 읽고 돌려 보기

tools/check_public_tree.py는 git ls-files의 경로만 보고 .local, assets, minecraft 같은 폴더나 .jar·.class·.java 확장자를 거부합니다(허용 목록의 예외 포함). 어떤 파일이 예외인지 코드를 먼저 읽고 결과를 예측한 뒤 실행합니다.

python3 tools/check_public_tree.py
python3 tools/check_public_tree.py --history
과제 3 · 초중급 정품 불필요

수정한 파일이 어느 하네스에 영향을 주는지 알아보기

CLAUDE.md가 안내하는 방식으로, 파일 경로 목록을 만들어 영향받는 하네스만 나열합니다. 이 방식은 하네스를 실행하지 않고 목록만 보여 줍니다.

printf '%s\n' crates/horizon-core/src/jmath.rs > paths.txt
python3 tools/parity.py --changed-files paths.txt --list

horizon-core 파일과 horizon-world 파일의 결과 개수를 비교해 의존 방향과 영향 범위를 설명해 보세요. 이 명령을 실제로 돌려 본 결과는 이 글에 적지 않았습니다.

과제 4 · 중급 모드 이해

예제 모드를 읽고 권한 하나 바꿔 보는 설계

crates/horizon-mod-sdk/examples/coords-hud/의 horizon-mod.toml과 src/lib.rs를 읽습니다. 소스는 방향을 yaw 90도 단위로 나누고 하루 24000틱을 시각으로 변환합니다. chat 권한을 빼면 어떤 코드가 막혀야 하는지 적어 본 다음 docs/mods.md와 비교합니다.

과제 5 · 중상급 정품 Minecraft 26.3 + JDK 25 필요

README 순서대로 리소스 준비와 실행

이 과제는 코드를 내려받아 빌드·실행하므로 신뢰할 수 있는 환경에서만 하세요. README의 명령은 다음과 같습니다.

cargo run --release -p horizon-prepare -- --prepare --server-jar ~/Downloads/server.jar
cargo run --release -p horizon-client

준비 결과는 .local/에 생기며 커밋하면 안 됩니다. 에이전트 조작을 시험할 때는 CLAUDE.md의 지침대로 실제 플레이 데이터가 아닌 임시 폴더를 HORIZON_HOME 등으로 지정하세요.

에이전트에게 게임을 맡기는 실험은 반드시 임시 데이터 폴더에서만 하는 것이 이 저장소가 스스로 정한 안전 규칙입니다.

9관련 기술 심화 학습 로드맵

6주 계획 예시
주차주제할 일
1주Rust 워크스페이스Cargo 워크스페이스·feature·exclude 개념을 익히고 이 저장소의 Cargo.toml 해설해 보기
2주월드 포맷NBT와 Anvil 리전 구조를 공부하고 horizon-world의 nbt.rs·region.rs 읽기
3주난수·부동소수점IEEE 754와 fdlibm, Java의 Random 선형 합동 생성기를 공부한 뒤 jmath.rs 읽기
4주그래픽스wgpu 튜토리얼로 삼각형·텍스처를 그린 뒤 gfx/의 컬링·메시 업로드 구조 보기
5주WebAssembly 컴포넌트WIT·컴포넌트 모델 문서를 읽고 horizon.wit과 예제 모드 대조
6주검증 문화차분 테스트·속성 기반 테스트 자료를 읽고, 하네스 한 개를 직접 분해해 발표 자료 만들기

10핵심 키워드 사전

처음 보면 막히는 용어
용어뜻
parity(패리티)원본 동작과 같은 정도. 이 프로젝트에서는 하네스가 비교하는 항목에 한해 “일치”를 뜻함
harness(하네스)입력을 만들고 두 구현에 넣어 출력을 비교하는 테스트 틀. tools/test_*_parity.py
oracle(오라클)정답을 알려 주는 쪽. 여기서는 원본 26.3 jar를 실제로 돌려 값을 뽑는 Java 코드
probe(프로브)Rust 쪽에서 같은 입력을 받아 JSON을 내보내는 작은 실행 파일(examples/*_probe.rs)
wgpu · WGSLVulkan·Metal·DX12 등을 감싸는 Rust 그래픽스 라이브러리와 그 셰이더 언어
NBT · Anvil 리전Minecraft의 데이터 직렬화 형식과 월드를 담는 리전(.mca) 파일 형식
DataFixer · DataVersion구버전 세이브를 현재 형식으로 올리는 변환기와 세이브의 버전 번호(코드에서 5023)
프로토콜 777Minecraft 26.3의 네트워크 프로토콜 번호(version.rs)
HotSpot intrinsicJVM이 일부 수학 함수를 CPU 전용 구현으로 바꿔 쓰는 최적화. 플랫폼마다 결과가 달라질 수 있음
WIT · 컴포넌트 모델WebAssembly 모듈이 주고받을 인터페이스를 선언하는 언어와 그 규격
capability모드가 쓰겠다고 선언해야 하는 권한 단위(game-read, hud, chat)
MCPAI 에이전트가 도구를 호출하는 표준 규약. horizon-ctl mcp가 명령마다 도구 하나를 제공
GPUI런처 UI에 쓰인 Rust GUI 프레임워크

11참고 링크

공식 자료와 개념 학습

외부 문서는 시간이 지나며 바뀔 수 있습니다. 이 글의 파일·수치 설명은 커밋 00705d8에 맞췄습니다. 하네스를 실제로 실행한 결과, 성능, 정확도의 독립 검증은 이 글에 포함되지 않습니다.

현재 상태 (2026-10-25 확인)

항목내용기준
저장소ludovic111/horizonGitHub
스타 / 포크1,328 / 902026-10-25 GitHub
생성일2026-10-03GitHub
최신 릴리스v0.2.50 · launcher@0.2.6릴리스 태그
소스 기준 커밋00705d8 · 2026-10-25 · PR #1630 병합고정 SHA
추적 파일3,110개같은 커밋
지원 게임 버전Minecraft Java 26.3 (프로토콜 777, DataVersion 5023)version.rs
하네스스크립트 326개 (README는 281, CLAUDE.md는 324·329를 언급)직접 센 값과 문서 값이 다름
라이선스MIT (프로젝트 고유 코드만). Minecraft 자산은 Mojang/Microsoft 소유LICENSE, README
한계와 사용 조건
이 글이 확인하지 않은 것

실행은 하지 않았습니다. 코드를 읽고 파일을 센 것이며, 빌드·하네스·게임 실행 결과는 없습니다. README의 “100% 일치”는 저장소의 자체 감사 주장이고 독립 검증이 아닙니다.

빠르게 변하는 저장소입니다. 하루에도 여러 PR이 병합되고 문서 수치가 서로 어긋난 곳이 있습니다. 쓰기 전에 최신 README와 릴리스를 확인하세요.

저작권 경계는 사용자 책임입니다. 저장소는 게임 자산을 포함하지 않는다고 하지만, 원본과의 대조 과정에 정품 jar가 쓰입니다. 개인 환경에서 정품 파일과 함께 쓰고 산출물을 공유하지 마세요.