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

PCL 딥다이브
— 게임 실행 버튼 뒤의 작은 작업 관리자

데스크탑 런처

빠른 판단

무엇
Minecraft Java Edition의 설치·Java 선택·모드·다운로드·실행·오류 진단을 관리하는 Windows 런처
이럴 때
게임별 실행 환경과 모드를 설정하고 시작 실패를 진단할 때
Minecraft를 켜는 버튼 하나 뒤에는 Java 선택, 계정 인증, 파일 다운로드, 실행 인자 조립, 프로세스 감시가 이어집니다. Plain Craft Launcher(PCL)는 이 과정을 VB.NET과 WPF로 묶은 Windows 데스크톱 앱입니다. 이 글은 커밋 6b9a50d의 실제 함수와 설정을 따라가며, 긴 작업을 나누고 실패를 다루는 방법을 설명합니다. 저장소: Meloong-Git/PCL · 스타 8,836 · 포크 1,229 · 주 언어 Visual Basic .NET · 최신 릴리스 2.99.0.0 · 2026-10-23 GitHub 기준.
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

Minecraft 실행을 준비하고, 시작하고, 지켜보는 Windows 앱

PCL은 Minecraft Java Edition의 설치와 실행을 돕는 런처입니다. 게임 엔진을 구현하는 프로그램이 아니라, 게임이 실행될 환경을 준비하는 프로그램입니다. 이 저장소의 핵심 학습 주제는 실행 버튼 하나를 여러 개의 추적 가능한 작업으로 바꾸는 방법입니다.

소스의 Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb를 보면 이 말이 구체적으로 드러납니다. 공개 진입점 McLaunchStart()를 거쳐 호출되는 비공개 McLaunchStart(Loader)는 Java 확보, 로그인, 누락 파일 보충, 인자 생성, 압축 해제, 사전 처리, 사용자 명령, 프로세스 시작, 창 대기, 마무리를 작업 목록으로 만듭니다.

한 문장 비유

게임이 비행기라면, PCL은 출발 준비를 맡은 지상 관제실입니다

탑승권을 확인하고, 연료와 짐을 점검하고, 출발 허가를 내는 순서가 있어야 비행기가 뜹니다. PCL도 계정·Java·파일·설정을 확인한 뒤 게임 프로세스를 시작합니다.

어느 단계가 실패했는지 모르면 “비행기가 안 떠요”라는 말밖에 할 수 없습니다. 단계마다 상태와 로그를 남기면 “필수 파일의 검증이 실패했어요”라고 좁힐 수 있습니다.

용어
런처와 런타임
런처는 다른 프로그램을 실행하도록 준비하는 앱입니다. 런타임은 그 프로그램이 동작하는 실행 환경입니다. PCL 자체의 실행 환경은 .NET Framework이고, Minecraft의 실행 환경은 Java입니다. 둘의 버전 문제는 따로 생각해야 합니다.
사용자에게 보이는 일소스에서 만나는 책임
게임 실행Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb: Java 선택, 로그인, 인자 생성, 프로세스 시작
버전·모드 관리Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb, Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb, Plain Craft Launcher 2/Modules/Resource/
필요한 파일 받기Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb가 다운로드 목록을 만들고 Plain Craft Launcher 2/Modules/Base/ModNet.vb가 전송
진행 상황 표시Plain Craft Launcher 2/Modules/Base/ModLoader.vb의 작업 상태·진행률과 WPF 컨트롤의 연결
실패 원인 안내Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb의 감시와 Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb의 로그 분석
첫 독서 목표
처음부터 5만 줄을 읽을 필요는 없습니다

McLaunchStart()의 작업 목록을 읽고, 각 작업이 무엇을 입력받아 무엇을 내놓는지만 적어 보세요. 이 지도 하나가 있어야 다운로드나 설정 코드를 읽을 때 길을 잃지 않습니다.

2왜 주목받는가

순위의 원인은 단정하지 않고, 코드가 보여 주는 매력을 살펴보기

2-1. 평범한 실행 버튼에 실전 문제가 모여 있다

2026-10-23 TrendShift Repositories #4 선정과 스타 8,836개는 관심의 신호입니다. 다만 이 숫자만으로 특정 기능이나 게시물이 상승을 일으켰다고 증명할 수는 없습니다. 10월 20일의 2.99.0.0 릴리스와 분석일이 가깝다는 사실도 인과관계와 구분해야 합니다.

코드에서 확인되는 주목할 점은 분명합니다. 다운로드 소스가 중간에 실패하고, Java 버전이 맞지 않고, 게임 파일 일부가 지워지고, 모드가 충돌하는 상황을 각각 처리합니다. PCL은 새로운 문법보다 오래 살아남는 데스크톱 제품의 예외 처리와 작업 조율을 배우기에 좋은 사례입니다.

2-2. 이 저장소에서 직접 확인되는 강점

중국어 검색어를 영문 검색어로 바꾸는 처리도 ResourceSearcher.Run()에 있습니다. 이는 해당 언어권 사용자를 위한 세부 구현의 예입니다. 한국어 검색을 같은 수준으로 지원한다고 해석해서는 안 됩니다. 화면과 문서의 언어도 학습 진입 비용에 포함됩니다.

2-3. 다른 런처와 비교할 때 볼 기준

비교 축PCLPrism Launcher / HMCL
플랫폼WPF·.NET Framework 기반 Windows 앱Prism은 Windows·macOS·Linux 지원을 명시하고, HMCL은 크로스플랫폼 런처로 소개
기술 학습VB.NET·WPF, C# 혼합, 직접 구현한 작업·다운로드 모듈Prism은 Qt 기반이라고 명시, HMCL은 JavaFX 관련 프로젝트로 소개
자원 연결CurseForge·Modrinth 통합 검색을 소스에서 추적 가능Prism도 두 서비스의 모드 설치·업데이트를 지원한다고 명시
읽기의 장점실행·네트워크·화면 피드백의 연결을 한 제품 안에서 학습크로스플랫폼 설계나 다른 UI 기술과 비교하며 학습 가능
라이선스GitHub 판정 NOASSERTION, 별도 LICENCE 확인 필요Prism과 HMCL 공식 페이지는 GPL-3 계열 라이선스를 표시

비교 근거(2026-10-23 공식 소개 기준): Prism Launcher 공식 소개, HMCL 공식 저장소. 기능의 독점성이나 속도 우위를 뜻하는 표는 아닙니다. 같은 게임을 실행하더라도 PCL은 Windows UI와 시스템 연동을 공부하려는 독자에게 특히 맞습니다.

비유

여러 여행사가 같은 목적지에 데려다주더라도 예약·짐 관리·사고 대응 방식은 다릅니다. 런처 비교도 “버튼이 몇 개 더 있나”보다 “내가 배우려는 문제를 어느 코드에서 볼 수 있나”로 접근하면 훨씬 생산적입니다.

3기술 스택 전체 지도

화면, 로컬 처리, 외부 서비스, 빌드를 분리해서 읽기

웹 서비스의 용어를 빌리면 화면은 프론트엔드, 설치·실행·다운로드는 백엔드 역할을 합니다. 하지만 PCL에는 이 기능을 제공하는 자체 웹 서버가 필요한 구조가 보이지 않습니다. PCL의 화면과 핵심 업무 로직은 같은 데스크톱 프로세스 안에 있고, 게임은 별도 Java 프로세스로 실행됩니다.

3-1. 프론트엔드: XAML로 그리고 VB.NET으로 반응하기

구성확인되는 설정·역할근거 파일
WPF / XAML창·페이지·스타일·컨트롤 템플릿. WinExe 출력Plain Craft Launcher 2/FormMain.xaml, Plain Craft Launcher 2/Application.xaml, Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj
Visual Basic .NETOptionExplicit On, OptionInfer On, OptionStrict OffPlain Craft Launcher 2/Plain Craft Launcher 2.vbproj
자체 컨트롤MyCheckBox, MyCard, MyLoading 등Plain Craft Launcher 2/Controls/
화면 동작RunInUi(), Dispatcher.Invoke()로 UI 스레드에 작업 전달Plain Craft Launcher 2/Modules/Base/ModLoader.vb, Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb
효과·이미지·소리직접 구현한 애니메이션 모듈, WebP 이미지·오디오 라이브러리 참조Plain Craft Launcher 2/Modules/Base/ModAnimation.vb, 프로젝트의 DLL 참조

OptionStrict Off는 VB 코드에서 암시적 변환 등에 관대한 설정입니다. 편하게 작성할 수 있지만 타입 실수가 실행 시점까지 숨어 있을 수 있습니다. 학습용 작은 예제에서는 타입을 명시하고 Option Strict On도 비교해 보세요.

3-2. 로컬 백엔드와 실제 의존성 버전

의존성의 중심은 package.json이 아니라 Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj와 PCLCS/PCLCS.csproj입니다. 아래 DLL 숫자는 VB 프로젝트의 어셈블리 참조 버전이며, NuGet 패키지의 세부 배포 버전과 같다고 단정하지 않습니다.

기술·의존성선언된 버전이 프로젝트에서의 의미
.NET Frameworkv4.8 / net48VB 앱과 C# 라이브러리의 대상 실행 환경
C#LangVersion 13.0PCLCS에서 사용. 언어 버전과 런타임 버전은 별개
PolySharpNuGet 1.15.0C# 프로젝트의 빌드 보조 의존성, PrivateAssets=all
Newtonsoft.Json13.0.0.0게임 버전 메타데이터와 외부 API의 JSON 처리
CacheCow 3종2.13.1.0HTTP 캐시 관련 Client·Common·FileStore 참조
ThrottleDebounce2.0.2.0빈번한 호출을 조절하는 라이브러리 참조
Imazen.WebP10.0.1.0WebP 처리. 별도 네이티브 DLL 항목도 존재
NAudio1.7.3.0오디오 관련 참조
Ookii.Dialogs.Wpf1.0.0.0WPF 대화상자 관련 참조
HTTP Formatting5.2.7.0System.Net.Http.Formatting 참조. 웹 서버 사용의 증거는 아님
MeloongCore98157d65…서브모듈 고정 커밋. 버전 태그 대신 Git 포인터로 식별
용어
언어 버전과 대상 프레임워크
언어 버전은 “어떤 문법을 컴파일러가 읽는가”이고, 대상 프레임워크는 “어떤 실행 환경과 API를 기준으로 프로그램을 만드는가”입니다. C# 13.0을 썼다는 사실이 .NET 13을 요구한다는 뜻은 아닙니다. 반대로 최신 문법을 허용해도 새 런타임 API가 자동으로 생기지는 않습니다.

3-3. 인프라·빌드: Windows CI가 만드는 실행 파일

.github/workflows/build.yml은 windows-latest에서 Debug와 Release 두 구성을 빌드합니다. actions/checkout@v6, microsoft/setup-msbuild@v3, actions/upload-artifact@v7을 사용하고 MSBuild는 x64로 설정합니다. 이들은 CI 액션의 버전이지 PCL에 포함되는 런타임 의존성이 아닙니다.

# .github/workflows/build.yml에 선언된 주요 빌드 명령
dotnet restore PCLCS\PCLCS.csproj
msbuild "Plain Craft Launcher 2\Plain Craft Launcher 2.vbproj" -p:Configuration=Release

# 설명용 인용입니다. 소스 독해에는 빌드 실행이 필요하지 않습니다.

CI는 서브모듈을 함께 가져오고, LTCatt/PCL2Help의 도움말을 압축해 Plain Craft Launcher 2/Resources/Help.zip으로 교체합니다. 또 OAuth 클라이언트 ID와 CurseForge API 키를 CI 비밀값으로 주입하고, CommitHash를 빌드 커밋으로 채웁니다. 공개 소스와 배포 산출물 사이에 이런 준비 단계가 있다는 뜻입니다.

현재 워크플로의 경로 필터는 Plain Craft Launcher 2/**와 .github/workflows/**입니다. PCLCS/**만 바뀐 push·PR은 이 필터에 걸리지 않을 수 있습니다. 또한 빌드·업로드 단계는 있지만 테스트 실행 단계는 없습니다. 빌드 성공과 동작 검증의 범위를 구분해 읽어야 합니다.

설정 파일을 읽을 때의 함정
오래된 표기보다 실제 빌드 대상과 시작 검사까지 함께 보세요

Plain Craft Launcher 2/App.config에는 .NET Framework 4.6.2 표기가 남아 있고, VB 프로젝트의 부트스트래퍼 항목에는 4.5.2도 있습니다. 그러나 두 프로젝트의 대상은 4.8이며, Application_Startup()은 레지스트리 Release 값 528040 미만을 검사합니다. “4.6.2만 있으면 된다”고 안내할 근거로 오래된 한 줄을 선택하면 안 됩니다.

4아키텍처 심화 분석

실행 경로 하나로 살펴보는 네 가지 설계 아이디어

4-1. 전체 구조: UI, 작업, 파일, 게임 프로세스

출발점은 Plain Craft Launcher 2/Application.xaml.vb의 Application_Startup()입니다. 공통 코어와 WPF를 초기화하고, 일반 실행에서는 중복 실행을 검사하고 로그를 준비합니다. WaitingMutex()는 PCL_SingletonMutex라는 이름의 뮤텍스로 이미 실행 중인 인스턴스가 있는지 확인합니다. 개발자 빌드와 업데이트 등 일부 명령행 작업은 이 검사를 건너뜁니다.

[Application_Startup] | +-- MeloongCore 초기화 / 로그 / 단일 인스턴스 검사 | v [FormMain + Pages + Controls] <--- UI 스레드 | 사용자 입력 ^ 상태·진행률 이벤트 v | [McLaunchStart / LoaderCombo / LoaderTask] | +-- Java 선택 ----------> SelectOrDownloadJava / PCLCS.Java +-- 로그인 -------------> 계정 인증 서비스 +-- DlClientFix --------> 누락 파일 목록 | | | v | LoaderDownload / NetFile | | | HTTP 소스 / 로컬 파일 | +-- JVM·게임 인자 / natives / 사전 처리 | v [McLaunchRun] ----> [java.exe: Minecraft 별도 프로세스] | 표준 출력·오류 / 창 상태 v [Watcher] | [CrashAnalyzer] 로그 분류·원인 후보

이 그림은 실행 경로 중심의 요약입니다. 모드 검색·설정·연결 기능이 모두 이 경로를 그대로 통과하는 것은 아닙니다. 공통 코어 내부 구현과 외부 인증 서버도 그림의 바깥 경계로 남겨 둡니다.

4-2. 패턴 ① 복합 작업과 상태 머신

Plain Craft Launcher 2/Modules/Base/ModLoader.vb에서 LoaderBase는 상태·진행률·취소·오류의 공통 틀입니다. LoaderTask(Of TIn, TOut)는 한 작업, LoaderCombo(Of InputType)는 여러 작업의 묶음입니다. 묶음도 같은 기반 타입이므로 다른 묶음 안에 넣을 수 있습니다. 이것이 복합체(Composite) 패턴로 읽을 수 있는 부분입니다.

Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb의 비공개 McLaunchStart(Loader)는 실제 작업 목록을 만듭니다. DlClientFix()가 반환하는 파일 보충 작업도 다시 LoaderCombo로 감싸집니다. 작업 하나와 작업 묶음이 같은 인터페이스를 가지면, 복잡한 절차를 작은 절차의 조합으로 표현할 수 있습니다.

' ModLaunch.vb의 작업 구성 방식을 설명하기 위한 축약 예시
Dim steps As New List(Of LoaderBase) From {
    New LoaderTask(Of Integer, Integer)("Java 준비", AddressOf McLaunchJava) With {
        .ProgressWeight = 4, .Block = False},
    McLoginLoader,
    New LoaderCombo(Of String)("파일 보충", DlClientFix(McInstanceSelected, False, True)) With {
        .ProgressWeight = 15, .Show = False},
    New LoaderTask(Of String, Integer)("인자 생성", AddressOf McLaunchArgumentMain) With {
        .ProgressWeight = 2}
}

Block=False는 해당 작업을 처음 시작한 뒤 같은 순회에서 다음 작업의 시작을 막지 않도록 하는 설정입니다. Java 준비와 로그인처럼 겹쳐 진행할 수 있는 일이 있습니다. 다만 LoaderCombo.Update()의 재순회·입력 갱신 로직까지 포함된 조율이므로 이 목록을 임의의 의존성 그래프를 해결하는 범용 병렬 스케줄러라고 부르지는 않는 편이 정확합니다.

상태뜻읽어 볼 동작
Waiting대기다음 작업을 시작할 수 있는지 검사
Loading처리 중작업 스레드에서 진행률 갱신
Finished완료출력을 다음 작업 입력으로 넘길 수 있음
Failed실패Error를 보관하고 묶음의 다른 작업을 취소
Canceled취소취소 토큰을 알리고 사용자 중단으로 처리

LoaderCombo.Progress는 각 작업의 ProgressWeight를 이용합니다. 예를 들어 가중치가 4와 2이고 진행률이 50%와 0%이면 전체는 (4 × 0.5 + 2 × 0) / 6 = 약 33.3%입니다. 이는 파일 바이트 수나 남은 시간을 그대로 측정한 값이 아니라 제품이 정한 가중 진행률입니다.

주의할 구현도 있습니다. LoaderBase.Progress는 처리 중이 아닌 종료 상태에서 1을 돌려줍니다. 따라서 진행률이 100%라고 성공을 판정하면 안 됩니다. 성공 여부는 반드시 State=Finished인지 확인해야 합니다.

용어
상태 머신과 협력적 취소
상태 머신은 프로그램이 지금 어느 단계에 있는지 이름 붙이고, 그 상태에 맞는 반응을 정하는 방식입니다. 협력적 취소는 실행 중인 코드가 취소 요청을 확인하고 스스로 멈추는 방식입니다. PCL에는 취소 토큰과 IsCanceled 검사, Thread.Interrupt() 호출이 함께 있으므로 하나의 방식만 쓴다고 요약하면 안 됩니다.

4-3. 패턴 ② 전송과 검증을 나눈 복구 흐름

Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb의 DlClientJarGet()는 게임 JSON의 다운로드 URL·크기·SHA-1을 읽어 FileChecker와 NetFile을 만듭니다. 이미 검증을 통과한 파일이면 다운로드를 생략할 수 있습니다. “무엇을 받을지 결정하기”와 “실제로 전송하기”를 나누는 설계입니다.

전송은 Plain Craft Launcher 2/Modules/Base/ModNet.vb의 LoaderDownload·NetFile이 맡습니다. NetFile.IsNoSplit는 크기를 모르거나 파일이 1 MiB보다 작으면 분할하지 않습니다. 분할 전송에는 HTTP Range 헤더를 사용하고, 소스가 이를 지원하지 않거나 실패하면 다른 소스·단일 전송 경로를 시도하는 처리가 있습니다.

[메타데이터: URL 후보 + 크기 + 해시] | v [기존 파일 검사] -- 정상 --> [다운로드 생략] | 필요 v [다운로드 / 필요 시 분할] | v [Merge: 합치기] | v [FileChecker 검사] | | 정상 실패 | | v v [Finish] [재시도 / 소스 변경 / 실패 전달]

NetFile.Merge()는 분할 데이터를 합친 뒤 Check?.Check(LocalPath)를 호출합니다. 병합 실패는 최대 세 번 시도하며, 다음 시도 전 500 × RetryCount 밀리초를 기다립니다. 복구가 안 되면 해당 소스를 배제하고 재다운로드를 시도하는 경로로 이어집니다.

여기서 배울 핵심은 “응답을 받았다”와 “쓸 수 있는 파일을 얻었다”를 나누는 것입니다. 해시는 파일의 일치 여부를 확인하는 재료입니다. 메타데이터의 출처까지 검증하는 서명이나 신뢰 체계 전체를 대신하지는 않습니다. FileChecker 내부 구현은 별도 공통 코어 경계에 있으므로 여기서는 호출과 전달값까지만 확정합니다.

4-4. 패턴 ③ 서로 다른 API를 하나의 모델로 연결하기

Plain Craft Launcher 2/Modules/Resource/ResourceSearcher.vb의 SearchRequest는 자원 종류·모드 로더·게임 버전·검색어를 담습니다. GetCurseForgeAddress()와 GetModrinthAddress()가 이 공통 입력을 각 서비스의 요청 형식으로 바꿉니다. 이를 어댑터 역할로 이해할 수 있습니다.

차이CurseForgeModrinth
페이지 위치CurseForgeOffsetModrinthOffset
결과 배열datahits
전체 수pagination.totalCounttotal_hits
검색 조건개별 쿼리 파라미터facets 배열
변환 이후ResourceProject 목록으로 취급하고 중복 제거

페이지당 요청 크기는 RESULT_PAGE_SIZE=40입니다. GetLoader()는 ReloadTimeout=60 * 1000으로 작업을 만듭니다. 이 값은 입력이 같을 때 재실행을 제어하는 작업 설정이지, 모든 HTTP 응답을 60초 동안 디스크 캐시에 넣는다는 뜻은 아닙니다.

Run()은 작업 스레드를 기다린 뒤 한 서비스만 실패하고 다른 서비스의 결과가 남아 있으면 SearchResult.ErrorMessage에 불완전한 결과임을 적습니다. 중복 제거 전에는 완료 순서와 관계없이 CurseForge 쪽을 먼저 놓고 IsLike()로 중복을 걸러냅니다. 최종 표시 목록은 다운로드 수와 검색 관련도 등의 점수로 다시 정렬합니다. 앞의 처리 순서를 CurseForge가 항상 화면 위에 표시된다는 뜻으로 읽으면 안 됩니다.

비유

두 서점이 책 정보를 다른 양식으로 보내도 내 책장에는 같은 카드 양식으로 꽂습니다. 한 서점이 문을 닫았을 때 다른 서점의 결과까지 버릴 필요는 없지만, “오늘은 한 곳의 목록만 보입니다”라는 안내는 있어야 합니다.

4-5. 패턴 ④ 부착 속성과 인터페이스로 설정 연결하기

Plain Craft Launcher 2/Pages/PageSetup/SettingService.vb는 WPF의 DependencyProperty.RegisterAttached()로 Key·Value를 정의합니다. 화면은 어떤 설정을 다루는지만 적고, 실제 저장은 공통 코드에 맡깁니다.

<!-- 실제 설정 키를 사용한 설명용 XAML -->
<local:MyCheckBox
    local:SettingService.Key="LaunchArgumentRam"
    Text="실행 전 메모리 정리" />

' MyCheckBox.xaml.vb의 설정 연결
Private Sub SaveSetting() Handles Me.Change
    SettingService.SaveSetting(Me)
End Sub

ISettingControl의 두 메서드 RefreshSetting()·GetCurrentSetting()가 컨트롤과 설정 서비스 사이의 약속입니다. SaveSetting()은 키를 읽고 Settings.Set()을 호출합니다. RefreshSettings()와 ResetSettings()는 논리 트리를 따라 하위 컨트롤까지 처리합니다.

또한 AniControlEnabled가 0이 아니면 저장을 건너뜁니다. 화면에 값을 채우는 과정에서 변경 이벤트가 일어나 다시 저장되는 상황을 제어합니다. 변수 이름만 보고 단순 애니메이션 스위치로 생각하기 쉽지만 설정 흐름에도 영향을 줍니다.

이 구조를 “엄격한 MVVM”이라고 소개하기는 어렵습니다. FrmMain 같은 전역 화면 참조와 코드 비하인드가 업무 모듈에도 등장합니다. 반복을 줄인 부분을 배우면서, 화면과 업무 로직이 결합된 비용도 함께 읽는 것이 좋습니다.

Plain Craft Launcher 2/Pages/PageSetup/Settings.vb의 Setting.Save()는 저장 위치도 나눕니다. Sources.Normal은 공통 INI, Sources.Registry는 현재 사용자 레지스트리, Sources.Instance는 해당 버전의 PCL\Setup.ini로 이어집니다. 설정 화면의 컨트롤 이름과 실제 저장 위치를 분리하면, 화면을 바꾸더라도 저장 규칙을 유지하기 쉽습니다.

4-6. 마지막 경계: 프로세스 시작 이후에도 일이 남는다

McLaunchArgumentMain()는 JVM 인자, JSON의 mainClass, 게임 인자를 차례로 모으고 치환값과 따옴표 처리를 적용합니다. 이어 McLaunchRun()은 java.exe용 ProcessStartInfo를 만들고, 작업 디렉터리·환경 변수·인코딩을 설정합니다.

' McLaunchRun()에서 확인되는 핵심 설정
StartInfo.WorkingDirectory = McInstanceSelected.PathIndie
StartInfo.UseShellExecute = False
StartInfo.RedirectStandardOutput = True
StartInfo.RedirectStandardError = True
StartInfo.CreateNoWindow = True
StartInfo.Arguments = McLaunchArgument

McLaunchWait()와 Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb의 Watcher는 게임 창과 프로세스를 살핍니다. BeginOutputReadLine()·BeginErrorReadLine()으로 로그를 읽고, Loading·Running·Crashed·Ended 등의 상태를 구분합니다. 프로세스가 생성됐다는 사실과 사용자가 게임을 할 수 있다는 사실은 다르기 때문입니다.

문제가 생기면 Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb의 CrashAnalyzer가 Collect() → Prepare() → Analyze() 흐름으로 로그를 수집·정리·분석합니다. AnalyzeCrit1()·AnalyzeCrit2()의 알려진 패턴을 먼저 보고, 스택 단서와 모드 이름을 찾은 뒤 낮은 우선순위 패턴을 봅니다. LLM을 부르는 분석이 아니라 소스에 작성된 규칙과 문자열 처리에 기반한 진단입니다.

5디렉토리 구조 해부

화면에서 시작해 모듈과 C# 모델로 이동하는 읽기 지도
PCL/ ├── README.md ├── LICENCE ├── .gitmodules ├── .github/ │ ├── workflows/build.yml │ └── ISSUE_TEMPLATE/ ├── Plain Craft Launcher 2.sln ├── Plain Craft Launcher 2/ │ ├── Plain Craft Launcher 2.vbproj │ ├── Application.xaml / Application.xaml.vb │ ├── FormMain.xaml / FormMain.xaml.vb │ ├── App.config / app.manifest │ ├── Controls/ │ │ ├── Behaviors/ │ │ ├── MyCheckBox.xaml / MyCheckBox.xaml.vb │ │ └── MyVirtualizingElement.vb │ ├── Pages/ │ │ ├── PageLaunch/ │ │ ├── PageDownload/ │ │ ├── PageInstance/ │ │ ├── PageSetup/ │ │ ├── PageLink/ │ │ └── PageOther/ │ ├── Modules/ │ │ ├── Base/ │ │ ├── Minecraft/ │ │ ├── Resource/ │ │ ├── ThirdParty/ │ │ ├── ModMain.vb │ │ └── ModSecret.vb │ ├── My Project/ │ ├── Images/ │ └── Resources/ ├── PCLCS/ │ ├── PCLCS.csproj │ ├── Java.cs / Configs.cs / Constants.cs │ ├── Minecraft/ │ ├── Resource/ │ └── Launch/ ├── MeloongCore/ [별도 저장소의 서브모듈] ├── patches/ [과거 변경 패치] └── 最新正式版.zip [정식판 배포 압축 파일]
위치책임과 읽는 관점
Plain Craft Launcher 2/Controls/체크박스·카드·로딩 표시 등 재사용 UI. 설정 인터페이스와 시각적 반응을 함께 확인
Plain Craft Launcher 2/Pages/실행·설치·인스턴스·설정 화면. XAML과 같은 이름의 코드 비하인드를 짝지어 읽기
Plain Craft Launcher 2/Modules/Base/작업 조율, 네트워크 전송, 애니메이션, 로깅 등 제품 공통 기반
Plain Craft Launcher 2/Modules/Minecraft/게임 버전·파일·Java·로그인·프로세스·충돌 분석의 도메인 로직
Plain Craft Launcher 2/Modules/Resource/외부 자원 검색, 프로젝트·버전 모델, 로컬 자원 처리
PCLCS/C# 보조 라이브러리. 버전 모델·Java 탐색·설정 항목·설치 구성과 파일 목록
Plain Craft Launcher 2/Resources/도움말·DLL·JAR 등 리소스. 모두 직접 작성한 소스라고 계산하면 안 됨
MeloongCore/공통 코어. Shared·Wpf 프로젝트를 참조하며 Git 커밋으로 연결
patches/과거 릴리스의 차이 파일. 현재 구현 파일과 합산하면 코드량을 중복 해석할 위험

5-1. 코드 규모: 공백·주석을 포함한 물리적 줄 수

종류파일 수줄 수포함·제외 기준
VB.NET11343,116.vb 전체. 자동 생성 Designer 파일도 포함
C#9921PCLCS/의 .cs 파일
XAML635,625화면·스타일 마크업
위 세 종류 합계18549,662서브모듈 내부·압축 파일 내부·DLL 제외
과거 패치1443,119.patch. 위 합계에 넣지 않음

줄 수는 복잡도나 품질 점수가 아닙니다. Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb는 2,221줄, Plain Craft Launcher 2/Modules/Base/ModNet.vb는 1,933줄로 책임이 큰 파일입니다. 처음에는 이를 통독하지 말고 함수 이름을 검색하며 필요한 범위만 읽는 편이 좋습니다. 두 Plain Craft Launcher 2/My Project/*.Designer.vb는 합계 304줄이며 VB 집계에 포함되어 있습니다.

5-2. 추천 독서 순서

  1. Plain Craft Launcher 2/Application.xaml.vb: 시작 시 검사와 초기화 경계를 확인합니다.
  2. Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb: 실행 작업 목록과 최종 프로세스 생성을 연결합니다.
  3. Plain Craft Launcher 2/Modules/Base/ModLoader.vb: 상태·진행률·실패 전파의 공통 규칙을 읽습니다.
  4. Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb와 Plain Craft Launcher 2/Modules/Base/ModNet.vb: 파일 목록과 전송 엔진의 역할을 나눕니다.
  5. Plain Craft Launcher 2/Pages/PageSetup/SettingService.vb·Plain Craft Launcher 2/Controls/MyCheckBox.xaml.vb: 화면의 값이 저장되는 경로를 따라갑니다.
  6. PCLCS/Minecraft/McVersion.cs: 더 작은 입력 변환 문제로 돌아와 이해를 확인합니다.

6학습 포인트 (기술별)

특정 언어보다 다른 프로젝트에서도 쓸 수 있는 사고법에 집중하기

VB.NET을 처음 접해도 Class, Function, Sub, AddressOf, With의 역할만 알면 큰 흐름을 읽을 수 있습니다. 문법을 전부 익히기 전에 입력·상태·출력·실패의 네 칸을 채우는 것이 소스 독해의 좋은 출발점입니다.

VB.NET · 제네릭 · 델리게이트

6-1. 타입이 다른 작업을 같은 틀에 넣기

LoaderTask(Of TIn, TOut)는 입력과 출력 타입을 달리할 수 있는 작업입니다. AddressOf McLaunchRun은 함수를 즉시 실행하는 것이 아니라 나중에 호출할 수 있도록 참조를 전달합니다. JavaScript의 콜백이나 C#의 델리게이트와 연결해 이해하면 쉽습니다.

실습 아이디어: “문자열 길이 계산”와 “숫자 두 배 계산”을 같은 작업 모양으로 적어 보세요. Start(), State, Output 중 어떤 것이 공통이고 어떤 것이 타입에 따라 달라지는지 표시합니다.

WPF · UI 스레드 · 이벤트

6-2. 화면 갱신과 오래 걸리는 처리를 분리하기

LoaderBase.State의 변경은 RunInUi()를 통해 OnStateChangedUi 이벤트로 이어집니다. 한편 작업은 별도 스레드에서 실행됩니다. “백그라운드에서 계산하고 화면 스레드에서 그린다”는 경계를 배울 수 있습니다.

실습 아이디어: 가짜 다운로드의 상태 변화를 종이에 적고 각 문장에 “작업 스레드” 또는 “UI 스레드”를 붙입니다. Dispatcher.Invoke()는 호출자가 완료를 기다린다는 점도 확인하세요. 서로를 기다리는 구조가 되면 화면 멈춤이나 교착 문제가 생길 수 있습니다.

HTTP · 파일 I/O · 복구

6-3. 네트워크 응답을 검증된 파일로 이어 가기

NetFile의 URL 목록, FileSize=-2의 미확인 상태, IsUnknownSize, Merge() 이후 검증을 함께 보세요. 크기를 아직 모르는 것과 크기를 알 수 없는 것은 다른 상태입니다.

실습 아이디어: “응답은 왔지만 크기가 다름”, “Range 미지원”, “취소됨” 세 가지를 서로 다른 결과로 분류합니다. 같은 “실패”라도 재시도할지, 다른 소스로 갈지, 즉시 멈출지 결정이 달라야 합니다.

C# · 정규화 · 경계값

6-4. 이름을 그대로 비교하지 말고 비교 가능한 값으로 바꾸기

PCLCS/Minecraft/McVersion.cs의 NameToVersion()은 1.20.3을 내부적으로 20.0.3으로 바꿉니다. 새로운 형태의 26.1은 26.1.0이 됩니다. 문자열 정렬 대신 일관된 숫자 비교가 가능하도록 표현을 정규화합니다.

실습 아이디어: 1.9와 1.10을 문자열로 정렬했을 때와 숫자로 비교했을 때를 비교하세요. 이 함수는 모든 버전 규칙을 처리하는 범용 SemVer 파서가 아니라 Minecraft 이름 규칙에 맞춘 코드라는 점을 함께 적습니다.

UI 성능 · 지연 초기화

6-5. 보이지 않는 컨트롤을 언제 만들 것인가

Plain Craft Launcher 2/Controls/MyVirtualizingElement.vb는 초기화 함수를 보관했다가 LazyLoadBehavior.OnFirstEnterScrollViewerViewport()를 통해 처음 화면 범위에 들어오면 실제 컨트롤로 교체합니다. Plain Craft Launcher 2/Controls/Behaviors/LazyLoadBehavior.vb는 처리 후 LayoutUpdated 이벤트 구독을 해제합니다.

실습 아이디어: 카드 1,000개 중 화면에 10개만 보이는 상황을 그려 보세요. 처음부터 전부 만드는 방식과 나중에 만드는 방식의 차이를 설명합니다. 이 구현은 자리 표시자를 실제 컨트롤로 교체하는 지연 초기화이며, 스크롤할 때 컨트롤을 계속 재활용하는 완전한 항목 가상화와는 구별해야 합니다.

6-6. 보안과 데이터 수명도 코드 독해의 일부다

McLaunchLog()는 FilterAccessToken()과 FilterUserName()을 거쳐 로그를 남깁니다. Plain Craft Launcher 2/Pages/PageSetup/Settings.vb에는 계정 캐시를 Encrypted:=True로 선언한 항목이 있습니다. 이를 보고 모든 로그·모든 데이터가 안전하다고 결론 내리지 말고, 민감한 값이 어느 경로로 저장·출력되는지 더 확인해야 합니다.

또한 SystemSystemTelemetry의 기본값은 True이고, 실행 성공·실패 경로에는 Telemetry() 호출이 있습니다. 그러나 ModSecret 모듈의 ClsBaseUrl은 빈 문자열이고, ModMain 모듈의 해당 함수는 주소가 http로 시작하지 않으면 즉시 반환합니다. 따라서 이 커밋의 해당 경로에서는 텔레메트리를 전송하지 않습니다. 게임 인증·자원 조회 등의 네트워크 요청과는 구분해야 합니다.

학습 노트 양식
각 함수에 네 질문만 반복하세요

무엇을 입력받는가? 어떤 상태를 바꾸는가? 무엇을 출력하는가? 실패하거나 취소되면 누가 다음 행동을 결정하는가? 이 네 질문은 런처뿐 아니라 설치 프로그램·파일 동기화·배치 작업에도 적용할 수 있습니다.

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

런처 실행, 게임 실행, 소스 학습을 서로 다른 요구로 보기

PCL이 실행되는 조건과 Minecraft가 쾌적하게 돌아가는 조건은 서로 다릅니다. 소스에는 PCL 자체의 공식 CPU·RAM·GPU 최소 사양표가 없습니다. 대신 시작 검사와 빌드 설정에서 확정할 수 있는 조건은 다음과 같습니다.

항목코드에서 확인되는 조건학습할 때의 해석
운영체제WPF·.NET Framework, 시작 시 32비트 OS 거부Windows 64비트 환경 필요. macOS·Linux용 네이티브 앱으로 안내하지 않음
.NET두 프로젝트 모두 4.8 대상, 시작 검사도 4.8 기준게임의 Java와 별개. 개발에는 대상 프레임워크 참조 도구도 필요
JavaJava.CheckAsync()는 64비트 여부와 버전 출력 검사런처를 읽는 데 불필요. 실제 게임·설치기 실행에는 맞는 Java가 필요
화면Plain Craft Launcher 2/FormMain.xaml의 최소 크기 810 × 470WPF 논리 단위의 창 크기. 물리 해상도나 게임 해상도 요구와 다름
권한Plain Craft Launcher 2/app.manifest의 asInvoker일반 실행 자체가 관리자 권한을 요구하는 선언은 아님
네트워크계정·버전·자원 API와 파일 다운로드에 사용모든 기능이 오프라인이라는 보장은 없음. 소스 독해는 오프라인 가능
디스크게임·라이브러리·자원·캐시·임시 분할 파일 저장모드팩 크기와 다운로드 중 임시 공간까지 따로 계산

7-1. Java는 “최신 하나”로 끝나는 문제가 아니다

Plain Craft Launcher 2/Modules/Minecraft/ModJava.vb의 GetJavaRequirement()는 게임 버전과 설치된 구성요소가 요구하는 Java 범위의 교집합을 구합니다. 조건이 충돌하면 경고를 남기고 새 조건으로 대체하며, 사용자가 버전 설정에서 범위를 지정하면 그 값을 우선합니다. 원본 메타데이터의 새로운 Java 요구도 반영합니다. 아래는 해당 함수의 일부 분기이며 전체 호환성 표가 아닙니다.

게임 조건소스의 기본 제약 예시
1.12부터의 일부 구간Java 8 이상. 이후 분기의 더 높은 최소 요구와 구분
1.17 구간Java 16 이상
1.18부터의 구간Java 17 이상
1.20.5부터의 구간Java 21 이상
새 메타데이터javaVersion.majorVersion 또는 java_version이 22 이상이면 그 최소값 반영
일부 구형 OptiFine상한이나 정확한 Java 8 구간을 추가. 무조건 최신 Java를 고르면 안 됨

PCLCS/Java.cs의 CheckAsync()는 -XshowSettings:properties -version 출력을 읽고 인코딩 속성도 얻습니다. 검사 제한 시간은 15000밀리초입니다. 게임 실행 실패가 단순히 “Java가 없다”가 아니라 버전·비트수·인코딩 문제일 수도 있음을 보여 줍니다.

7-2. 학습 환경을 고른다면

소스만 읽을 때는 편집기와 텍스트 검색 도구면 충분합니다. WPF 예제를 별도로 만들어 볼 때는 Windows 11 64비트와 C# 13을 지원하는 컴파일러, .NET Framework 4.8 대상 개발 도구를 우선 고려할 수 있습니다. 이 저장소의 CI가 사용하는 windows-latest는 고정된 Windows·SDK 버전 이름이 아닙니다.

편집기·개발 도구를 함께 쓰는 편의를 위한 참고선은 RAM 8GB 이상, 여유가 있다면 16GB, SSD의 충분한 빈 공간입니다. 이는 이 글의 학습 환경 제안이며 PCL의 공식 최소 사양이나 Minecraft 성능 보장이 아닙니다. GPU·게임용 RAM은 게임 버전과 모드·셰이더 구성에 따라 별도로 정해야 합니다. 런타임의 운영체제 호환성은 Microsoft의 .NET Framework 시스템 요구사항을 참고하세요.

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

실제 계정·다운로드 없이도 핵심 설계를 익히는 다섯 과제

실습은 원본을 고쳐 빌드하기보다, 독립된 작은 예제와 가짜 데이터로 진행하도록 구성했습니다. 정상 동작을 흉내 내는 데서 끝내지 말고, 실패와 취소가 어떻게 구분되는지까지 확인하세요.

과제 1 · 입문

실행 버튼의 호출 지도를 그리기 약 30~45분

읽을 곳: Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb의 McLaunchStart(), McLaunchJava(), McLaunchRun(), McLaunchWait().

할 일: 단계마다 입력·출력·실패 원인 하나를 표로 정리합니다. 어느 함수가 UI 스레드를 요구하는지, 어느 단계가 Process를 출력하는지도 표시하세요.

완료 기준: “프로세스 생성은 성공했지만 창은 아직 없다”를 별도 상태로 설명할 수 있어야 합니다. 저장소의 프로그램 실행은 필요하지 않습니다.

과제 2 · 입문

버전 문자열 비교표 만들기 약 45~60분

읽을 곳: PCLCS/Minecraft/McVersion.cs의 NameToVersion().

할 일: 아래 입력을 먼저 손으로 계산한 뒤, 별도의 짧은 함수로 숫자 비교를 흉내 냅니다. 파일명이나 문자열 사전순으로만 정렬했을 때의 결과와 비교하세요.

# 소스의 정규화 규칙을 읽고 얻을 수 있는 예시
1.9      → 9.0.0
1.10     → 10.0.0
1.20.3   → 20.0.3
26.1     → 26.1.0
unknown  → 9999.0.0

완료 기준: 미확인 값 9999.0.0을 실제 최신 버전이라고 오해하지 않고, 별도 “알 수 없음” 표시로 다룰 방법을 설명합니다.

과제 3 · 중급

가짜 작업 세 개로 진행률과 취소 구현하기 약 2~3시간

읽을 곳: Plain Craft Launcher 2/Modules/Base/ModLoader.vb의 Progress, Failed(), Cancel(), LoaderCombo.Update().

할 일: “검사·준비·마무리” 세 작업을 만들고 가중치를 1·3·1로 정합니다. 네트워크 없이 진행 수치만 바꾸고, 준비 단계가 일부 진행된 상태에서 취소하거나 오류를 발생시킵니다. UI 없이 텍스트 출력으로 구현해도 됩니다.

완료 기준: 세 작업이 모두 끝났을 때만 성공입니다. 실패·취소 상태가 100% 표시와 혼동되지 않아야 하고, 취소 이후 늦게 도착한 결과를 성공으로 덮어쓰지 않아야 합니다. 진행률 0·중간·완료와 실패·취소를 각각 확인하세요.

과제 4 · 중급

두 서비스의 가짜 검색 결과를 한 목록으로 합치기 약 2시간

읽을 곳: Plain Craft Launcher 2/Modules/Resource/ResourceSearcher.vb의 SearchResult, Run(), Plain Craft Launcher 2/Modules/Resource/ResourceProject.vb의 모델 필드.

할 일: 아래처럼 형식이 다른 JSON 두 개를 공통 프로젝트 모델로 바꿉니다. 한쪽은 오류가 났다고 가정하고 나머지 목록과 “일부 결과만 표시” 안내를 함께 만드세요.

# 실습용 가짜 응답. 실제 API의 완전한 응답 형식은 아닙니다.
{"data": [{"id": 101, "name": "Example A"}], "pagination": {"totalCount": 1}}
{"hits": [{"project_id": "abc", "title": "Example B"}], "total_hits": 1}

완료 기준: 도착 순서를 바꿔도 정렬 결과가 같고, 한쪽 실패와 전체 실패를 구분합니다. 이름이 같다는 이유만으로 다른 프로젝트를 지우지 않도록 중복 판정 기준도 문장으로 작성하세요. 실제 외부 API 호출은 필요하지 않습니다.

과제 5 · 고급

로컬 데이터로 파일 복구 시나리오 설계하기 약 반나절

읽을 곳: DlClientJarGet(), NetFile.Merge(), NetFile.GetSource(). FileChecker는 호출 계약만 참고합니다.

할 일: 작은 바이트 배열 두 개를 합쳐 검증하는 독립 예제를 만듭니다. 소스 A는 잘못된 내용을, 소스 B는 정상 내용을 반환하는 가짜 전송기로 두고, 크기 불일치·내용 불일치·취소·저장 실패를 각각 주입합니다.

완료 기준: 틀린 파일을 완료로 공개하지 않고, 재시도 횟수가 무한히 늘지 않으며, 마지막 실패 원인을 보존해야 합니다. 추가 도전으로 임시 파일을 검증한 뒤 최종 파일로 교체하는 설계를 제안해 보세요. 이것은 PCL의 현재 구현이라고 주장하는 내용이 아니라 개선 설계 과제입니다.

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

6주 동안 문법에서 작업 조율과 제품 검증까지

주당 3~5시간을 기준으로 한 예시입니다. 게임 지식이 없어도 작업 조율·파일 검증·UI 이벤트는 충분히 배울 수 있습니다. 매주 읽은 소스에서 하나의 규칙을 꺼내 작은 독립 예제로 설명할 수 있으면 학습이 쌓이고 있다는 뜻입니다.

주차배울 내용PCL에서 읽을 곳남길 결과물
1주차VB.NET 기본 문법, 함수·클래스·이벤트·제네릭McLaunchStart()와 작업 목록함수 호출 지도와 입력·출력 표
2주차WPF XAML, 코드 비하인드, 부착 속성Plain Craft Launcher 2/Pages/PageSetup/SettingService.vb, Plain Craft Launcher 2/Controls/MyCheckBox.xaml.vb설정 하나의 화면 → 저장 → 표시 흐름
3주차상태 머신, UI 스레드, 가중 진행률, 취소Plain Craft Launcher 2/Modules/Base/ModLoader.vb가짜 작업 세 개와 실패·취소 시나리오
4주차HTTP Range, 파일 I/O, 해시, 제한된 재시도Plain Craft Launcher 2/Modules/Base/ModNet.vb, Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb복구 흐름도와 검증 결과표
5주차API 모델 변환, 부분 실패, 안정된 결과 정리Plain Craft Launcher 2/Modules/Resource/ResourceSearcher.vb, Plain Craft Launcher 2/Modules/Resource/ResourceProject.vb가짜 두 서비스의 통합 검색 예제
6주차프로세스 I/O, 진단 규칙, CI의 검증 범위Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb, Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb, .github/workflows/build.yml증상 → 로그 → 원인 후보 보고서

9-1. 관심사에 따른 다음 갈림길

학습 비유

큰 건물을 배우는 가장 좋은 출발은 자재 목록을 외우는 일이 아니라 한 사람이 현관에서 방까지 이동하는 길을 따라가는 것입니다. 실행 요청 하나의 길을 먼저 익힌 뒤, 설정과 다운로드와 진단으로 옆길을 넓히세요.

10핵심 키워드 사전

이름을 외우기보다 소스에서 맡은 역할과 연결하기
용어쉬운 설명
런처다른 프로그램이 실행될 환경을 준비하고 시작시키는 앱. PCL에서는 Java·계정·게임 파일을 조율합니다.
VB.NET.NET 환경의 Visual Basic 언어. Sub는 값을 반환하지 않는 절차, Function은 값을 반환하는 함수입니다.
WPFWindows 화면을 구성하는 UI 기술. PCL의 창·컨트롤·이벤트·렌더링을 담당합니다.
XAML화면의 계층과 속성을 선언하는 XML 기반 표기. 브라우저가 렌더링하는 HTML과는 다른 체계입니다.
코드 비하인드XAML과 짝을 이루며 클릭·변경 등 동작을 처리하는 코드 파일. PCL의 *.xaml.vb가 그 예입니다.
부착 속성다른 컨트롤에 추가 정보를 붙이는 WPF 장치. SettingService.Key는 연결할 설정 이름을 담습니다.
UI 스레드화면 요소를 다루는 실행 흐름. 작업 스레드의 결과는 RunInUi() 등으로 이쪽에 전달합니다.
DispatcherUI 스레드에서 코드를 실행하도록 전달하는 창구. Invoke()는 그 실행이 끝나기를 기다립니다.
제네릭타입만 바꾸어 같은 틀을 쓰는 방법. LoaderTask(Of TIn, TOut)는 입력·출력 타입을 매개변수로 받습니다.
델리게이트호출할 함수에 대한 참조. VB의 AddressOf로 작업 함수를 전달합니다.
복합체 패턴작은 요소와 요소의 묶음을 같은 방식으로 취급하기. 작업 묶음 안에 다른 작업 묶음을 넣을 수 있습니다.
상태 머신대기·진행·성공·실패·취소처럼 현재 상태를 명확히 나누고 다음 행동을 정하는 방식입니다.
취소 토큰작업에 멈춤 요청이 왔음을 알리는 신호. 요청을 받은 코드가 이를 확인하고 정리할 필요가 있습니다.
뮤텍스여러 실행 주체가 한 자원을 동시에 차지하지 못하게 하는 잠금. PCL은 중복 실행 검사에 이름 있는 뮤텍스를 씁니다.
HTTP Range파일의 특정 바이트 위치부터 요청하는 방식. 분할 전송이나 이어받기에 활용하지만 서버의 지원이 필요합니다.
해시파일 내용에서 계산한 비교용 값. 예상 값과 다르면 파일이 기대한 내용과 다르다는 단서가 됩니다.
어댑터서로 다른 입력·출력 양식을 공통 모델과 연결하는 역할. 외부 API의 차이를 내부 화면에서 덜 보게 합니다.
부분 실패여러 요청 중 일부만 실패한 상황. 성공한 결과는 보여 주되 누락 가능성을 함께 안내할 수 있습니다.
정규화다양한 표현을 비교 가능한 같은 형태로 바꾸기. 게임 버전 이름을 숫자 버전으로 바꾸는 것이 예입니다.
지연 초기화실제로 필요해질 때 객체를 만드는 방식. 화면에 처음 들어온 카드만 생성하는 코드에서 볼 수 있습니다.
표준 출력·오류하위 프로세스가 글로 내보내는 두 통로. PCL은 게임 로그와 오류를 읽기 위해 둘을 연결합니다.
네이티브 라이브러리운영체제·아키텍처에 맞는 기계어 라이브러리. Java 게임도 그래픽 등을 위해 이런 파일을 사용할 수 있습니다.
서브모듈다른 Git 저장소를 특정 커밋에 연결하는 장치. 상위 저장소의 파일 목록만으로 내부 코드가 모두 채워지지는 않습니다.
CI·아티팩트CI는 변경 후 빌드·검사 작업을 자동으로 수행하는 체계이고, 아티팩트는 그 결과로 보관한 실행 파일 같은 산출물입니다.
어셈블리 버전.NET DLL을 식별하는 버전. NuGet 패키지 버전과 별도일 수 있어 출처를 구분해서 적어야 합니다.
텔레메트리사용·실패 상황 같은 운영 정보를 수집하는 처리. 존재 여부와 실제 전송 범위는 나누어 확인해야 합니다.
NOASSERTION라이선스를 특정 SPDX 식별자로 확정하지 못했다는 표기. 저작권이 없거나 아무 조건 없이 써도 된다는 뜻이 아닙니다.

11참고 링크

커밋을 고정한 코드 근거와 다음 공부를 위한 공식 문서

11-1. 프로젝트와 코드 근거

11-2. 관련 기술 공식 문서

11-3. 현재 상태 (2026-10-23 확인)

항목확인 내용
저장소Meloong-Git/PCL · Minecraft Java Edition용 Plain Craft Launcher
관심도스타 8,836 · 포크 1,229 · 2026-10-23 GitHub 기준
선정2026-10-23 TrendShift Repositories #4
생성일2022-07-26
주 언어Visual Basic .NET
최신 릴리스2.99.0.0 · 2026-10-20
최근 push2026-10-20
최근 커밋6b9a50df911c9d68b69b24c979efba477fb14b67 · 2026-10-20 14:51:42 +08:00 · 2.99.0.0 정식판
코드 규모VB.NET 43,116줄 + C# 921줄 + XAML 5,625줄 = 49,662줄, 185개 파일
규모 산정주석·공백·자동 생성 코드 포함. 과거 패치·압축 내부·바이너리·서브모듈 내부 제외
빌드.NET Framework 4.8 / Windows / MSBuild. CI는 Debug·Release 빌드와 아티팩트 업로드
버전 상수VersionBaseName="2.99.0.0", Release VersionCode=413. 다른 조건 분기의 값은 414
라이선스GitHub 메타: NOASSERTION. 저장소는 LICENCE와 별도 제한적 배포 허가 문서를 안내
공개 주기README 기준: 모든 실시간 개발 변경을 계속 공개하는 방식이 아니라, PCL 릴리스 때 소스를 동기화
읽고 활용하기 전에 알아둘 한계
공개 코드의 범위와 배포 조건까지 함께 읽어야 합니다

분석 범위: 설명은 커밋 6b9a50d의 정적 소스 독해 기준입니다. 실행 성능·게임 호환성·다운로드 속도를 벤치마크한 결과가 아닙니다. 트렌딩 상승의 원인도 유입·스타 증가 이력 없이 확정하지 않습니다.

외부 경계: README는 “대부분의 소스”라고 표현합니다. MeloongCore는 별도 서브모듈이며 이 글의 코드량과 내부 구현 분석에 포함되지 않습니다. 배포에 쓰는 DLL·JAR, 외부 API, CI 비밀값, 별도 도움말까지 공개 본문만으로 모두 재현된다고 볼 수 없습니다.

버전 고정의 한계: 소스 커밋과 서브모듈 포인터는 특정할 수 있지만, CI의 도움말은 master 브랜치에서 다시 가져오고 실행 환경은 windows-latest입니다. 같은 앱 소스만 고정했다고 빌드 입력 전체가 고정되지는 않습니다.

이용 조건: LICENCE는 별도 제한적 배포 허가를 가리키고, 저장소 이용 안내가 법률 문서나 계약이 아니라고 명시합니다. 이름·표시·출처·재배포와 상당 부분 재사용에 관한 요구도 적혀 있습니다. 공개 저장소라는 이유로 MIT처럼 자유롭게 재배포할 수 있다고 가정하지 말고, 실제 활용 범위에 맞춰 원문 조건을 확인해야 합니다.