怎样开发一个Minecraft启动器(Java版)
Minecraft 玩了很久,一定用过各种启动器。除了官方启动器之外,还有许多第三方开发的启动器,例如: HMCL 、 MultiMC 、 Prism Launcher 、 ATLauncher 、 GDLauncher
| 启动器 | 适合人群 | 特点 |
|---|---|---|
| HMCL | Mod 玩家 | 中文友好,功能全面 |
| Prism Launcher | 多实例管理 | 轻量、稳定 |
| ATLauncher | 整合包玩家 | 大型 Mod 包支持 |
| GDLauncher | 现代化 UI | 云同步(付费) |
| Lunar Client | PvP 玩家 | 性能优化 |
| Betacraft | 怀旧玩家 | 支持远古版本 |
| TLauncher | 盗版玩家(不推荐) | 风险高 |
你一定好奇,这些启动器是怎么开发出来的,我们是不是可以自己动手开发一个自己的启动器?
答案当然是可以的,而且实现一个启动器其实并不困难。启动器本质上只做两件事:把游戏所需的文件下载好,再拼出一条正确的 Java 命令把它跑起来。本文以 Java 版客户端和服务端为例,把这条流水线一步步拆开。
想了解启动器工作原理,我们首先可以看看官方启动器是怎么运行的。 下载微软官方的启动器 ,安装并启动它。启动游戏客户端,然后在控制台使用命令查看启动器进程:
- Windows:
wmic process where caption="javaw.exe" get caption,commandline /value- Linux/macOS:
ps aux | grep java你会看到一条很长的 java 启动命令,里面带了 classpath、一堆 JVM 参数和游戏参数——启动器的工作就是把这条命令拼出来。下面我们一步步还原它。
启动器的核心:元数据🔗
版本清单 version_manifest.json🔗
所有版本的信息都汇总在一份清单文件里:
https://launchermeta.mojang.com/mc/game/version_manifest.json注意这是 Mojang 的旧域名,现在会 301 跳转到 piston-meta.mojang.com。只要你的 HTTP 客户端跟随重定向(大多数语言默认如此),这个地址就能正常使用。
清单内容分两部分:
{
"latest": {
"release": "26.2",
"snapshot": "26.3-snapshot-9"
},
"versions": [
{
"id": "26.2",
"type": "release",
"url": "https://piston-meta.mojang.com/v1/packages/<sha1>/26.2.json",
"time": "2026-08-17T11:52:59+00:00",
"releaseTime": "2026-08-17T11:46:16+00:00"
}
]
}latest:最新正式版 / 快照版版本号,方便快速定位versions:全部版本条目(约近千条),每条的核心是id、type、url
版本 type 有四种:release(正式版)、snapshot(快照)、old_alpha、old_beta(远古版本)。
这份清单约 243 KB、近千条记录,建议缓存到本地,非必要不重复拉取;需要「检查更新」时再重新下载一次即可。
单版本 JSON🔗
清单里每个版本的 url 字段,指向这个版本的具体配置,形如:
https://piston-meta.mojang.com/v1/packages/<sha1>/<版本号>.json获取元数据的流程就是三个请求:
GET version_manifest.json
→ 在 versions[] 里按 id 匹配目标版本
→ 取该条目的 url
GET <url> // 单版本 JSON,一个版本的全部配置单版本 JSON 长什么样🔗
单版本 JSON 是启动器的「唯一事实来源」,下载什么、怎么启动全看它。关键字段:
| 字段 | 作用 |
|---|---|
mainClass | 主类,客户端如 net.minecraft.client.main.Main |
arguments | 现代格式:jvm(JVM 参数,可带规则)+ game(游戏参数模板) |
downloads | client / server jar 的下载信息(url + sha1 + size) |
libraries | 依赖库列表(Maven 坐标 + 平台规则 + natives) |
assetIndex | 资源索引 JSON 的 id / url / sha1 |
javaVersion | majorVersion,决定用哪个 Java 大版本 |
{
"mainClass": "net.minecraft.client.main.Main",
"javaVersion": { "majorVersion": 21 },
"downloads": {
"client": {
"sha1": "<sha1>",
"size": 39193383,
"url": "https://piston-data.mojang.com/v1/objects/<sha1>/client.jar"
},
"server": {
"sha1": "<sha1>",
"size": 60894273,
"url": "https://piston-data.mojang.com/v1/objects/<sha1>/server.jar"
}
},
"assetIndex": {
"id": "32",
"sha1": "<sha1>",
"url": "https://piston-meta.mojang.com/v1/packages/<sha1>/32.json"
},
"arguments": { "jvm": [...], "game": [...] },
"libraries": [ ... ]
}一个细节:老版本(约 1.13 之前)没有 arguments 字段,用的是字符串模板 minecraftArguments,把参数拼成一行再按空格拆分。新老格式都要兼容。
开发客户端启动器🔗
客户端启动器的流程四步:下载本体 → 下载资源 → 下载依赖 → 组装命令启动。
1. 下载游戏本体🔗
取 downloads.client,下载后按 sha1 校验。校验通过的文件可以留档复用,下次启动跳过:
url = version_json.downloads.client.url
sha1 = version_json.downloads.client.sha1
if 文件不存在 或 SHA-1 不匹配:
下载 url → versions/<id>/client/<id>.jar
校验 SHA-1
else:
跳过2. 下载资源文件🔗
资源文件(贴图、音效等)是另一套系统,由 assetIndex 索引:
- 下载
assetIndex.url到assets/indexes/<id>.json - 该 JSON 的
objects字段列出每个资源的hash和大小 - 从固定基址下载,两字符分片定位:
https://resources.download.minecraft.net/<hash 前两位>/<hash>例如 hash = a1b2c3...,地址就是 https://resources.download.minecraft.net/a1/a1b2c3...,保存到 assets/objects/<hash前两位>/<hash>。
大版本资源文件动辄上千个,适合多线程并发下载。
3. 下载依赖库🔗
libraries 是 Maven 坐标列表,每一项要先解析:
- 坐标 → 路径:
at.yawk.lz4:lz4-java:1.10.1→at/yawk/lz4/lz4-java/1.10.1/lz4-java-1.10.1.jar,基址https://libraries.minecraft.net/ - 规则过滤:很多库带
rules,按当前 OS / 架构决定是否下载(例如 LWJGL 的 macOS 版只有 osx 才需要) - natives:带
natives-linux/natives-osx之类分类器的 jar 是原生库,历史版本需要解压出.dylib/.dll/.so放到natives/目录;较新版本游戏会在运行时自行从 classpath 解压,直接留在 classpath 即可
4. 组装启动命令🔗
所有文件就绪后,拼 Java 命令:
java
-Xms512M -Xmx2G # 内存,启动器自己定
<arguments.jvm 展开后的参数> # 含 -Djava.library.path=<natives目录>
-Dminecraft.launcher.brand=<品牌>
-Dminecraft.launcher.version=<版本>
-cp <classpath> # client.jar + 所有依赖库,用 OS 分隔符(:/;)拼接
net.minecraft.client.main.Main # mainClass
<arguments.game 展开后的游戏参数>两个要点:
JVM 参数与游戏参数都要「展开规则 + 替换 token」。arguments 里的条目可能是纯字符串,也可能是带 rules 的对象——规则匹配当前 OS/特性才包含。例如 macOS 才有 -XstartOnFirstThread:
[
{
"rules": [{ "action": "allow", "os": { "name": "osx" } }],
"value": "-XstartOnFirstThread"
}
]游戏参数里的 ${token} 要替换成实际值:
| Token | 值 |
|---|---|
${auth_player_name} | 玩家名 |
${game_directory} | 游戏目录 |
${assets_root} | assets/ 目录 |
${assets_index_name} | 资源索引 id |
${auth_uuid} | 玩家 UUID |
${auth_access_token} | 登录凭证 |
${user_type} | legacy(离线)或 msa |
离线登录很简单:--accessToken 0、--uuid 给一个随机 UUID、--userType legacy 即可进入游戏(正版验证是另一套流程,见下文进阶)。
组装完成的伪代码:
准备(version):
json = 获取单版本JSON(version)
if not exists(client.jar): 下载(client.jar, sha1 校验)
if not exists(assetIndex): 下载(assetIndex.json)
for obj in assetIndex.objects: 并发下载(基址 + 分片定位, sha1 校验)
for lib in resolve(libraries): 并发下载(按规则过滤, sha1 校验)
解压 natives(如需)
启动(version):
命令 = [java 路径]
命令 += ["-Xms512M", "-Xmx2G"]
命令 += 展开(jvm 参数) # 规则过滤 + token 替换
命令 += ["-cp", classpath 拼接]
命令 += [mainClass]
命令 += 展开(游戏参数) # token 替换 + 补全 --username/--uuid/--accessToken
spawn(命令)
if 进程在几秒内退出: 读取日志, 回显失败原因启动后游戏会在几秒内真正开始渲染。启动器可以做一个「短窗口崩溃检测」:进程刚起就退出,多半是 natives 缺失、classpath 拼错或 JVM 崩溃,此时把日志尾部回显给用户,比一句「启动失败」有用得多。
开发服务端启动器🔗
服务端和客户端共用同一套元数据入口:同样是版本清单 → 单版本 JSON,只是取 downloads.server 下载 server.jar,然后初始化配置并启动。
1. 下载服务端🔗
url = version_json.downloads.server.url
下载 url → server/server.jar
校验 SHA-1不需要额外的服务端清单——官方原版服务端的下载地址就藏在单版本 JSON 里。
2. 初始化配置🔗
原版服务端首次启动前需要两个文件:
eula.txt:接受协议才允许运行,内容一行eula=trueserver.properties:不存在的关键项可以补齐,如online-mode=false(离线登录局域网)、server-ip=
3. 启动🔗
java -Xms512M -Xmx2G -jar server.jar --nogui--nogui 在无图形界面的服务器/容器里去掉 GUI 窗口。生产环境通常用 screen 或 systemd 守护进程托管,让服务端常驻并在崩溃后自动拉起。
服务端启动器伪代码:
准备服务端(version):
json = 获取单版本JSON(version)
下载(downloads.server.url → server.jar, sha1 校验)
写入 eula.txt = "eula=true"
补齐 server.properties(online-mode 等)
启动服务端(version):
spawn(java, -Xms, -Xmx, -jar, server.jar, --nogui)进阶话题🔗
- 下载健壮性:每个文件都做 SHA-1 校验;已存在且校验通过就跳过,实现断点续传的体验;资源与依赖多线程并发下载,把上千个文件的耗时压下来。
- 第三方服务端:Paper 等服务端有自己的
PaperMC API v2
,接口路径是
projects/paper → versions → builds → 具体 build 的 download,可以拿到比 vanilla 更可选的构建产物。 - Mod 加载器:Fabric、Forge、OptiFine 各有自己的安装器或 profile JSON,本质都是在
libraries、classpath、JVM 参数上做叠加。例如 OptiFine 会写一份launcher_profiles.json供安装器识别,Fabric 会解析自己版本清单的附加 JSON。 - 正版认证:离线只需要占位符;正版走 Microsoft OAuth 登录流程,换取 access token 后填进
--accessToken和--uuid,并处理 refresh token 过期。 - Java 版本选择:按
javaVersion.majorVersion匹配对应的大版本 Java;老版本(1.17 之前)需要 Java 8,现代版本需要 Java 17/21,当前 26.x 需要 Java 25。
参考链接:
- client.json — Minecraft Wiki :客户端启动器对应文件
- 如何编写启动器 — Minecraft Wiki
- version_manifest.json :Mojang 版本清单
- PaperMC :第三方服务端下载 API