You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS下Bash脚本启动自定义目录Minecraft Forge遇问题求助

关于macOS终端自动化部署启动Minecraft Forge实例的问题

我尝试完全通过终端在macOS上自动化部署并启动Minecraft Forge实例,不使用官方启动器或CurseForge,目标是:

  • 自动下载并安装Forge
  • 使用独立于.minecraft的自定义游戏目录,存放专属mod和配置文件
  • 直接通过Java启动游戏

编写了对应的Bash脚本,但Forge/Minecraft无法正常启动——要么立即崩溃,要么无任何反应,且没有清晰的错误提示。

当前脚本

#!/bin/bash

# Variables
FORGE_VERSION="1.20.1-47.4.0"
FORGE_INSTALLER="forge-${FORGE_VERSION}-installer.jar"
FORGE_VERSION_NAME="1.20.1-forge-47.4.0"
INSTALL_DIR="$HOME/MinecraftInstances/Forge-1.20.1"
MINECRAFT_DIR="$HOME/Library/Application Support/minecraft"
FORGE_URL="https://maven.minecraftforge.net/net/minecraftforge/forge/${FORGE_VERSION}/${FORGE_INSTALLER}"

mkdir -p "$INSTALL_DIR"

if [ ! -f "$FORGE_INSTALLER" ]; then
  echo "Downloading Forge..."
  curl -O "$FORGE_URL"
fi

cd "$MINECRAFT_DIR" || exit
echo "Installing Forge..."
java -jar "$HOME/Downloads/$FORGE_INSTALLER" --installClient

cp -R "$MINECRAFT_DIR/mods" "$INSTALL_DIR/" 2>/dev/null
cp -R "$MINECRAFT_DIR/config" "$INSTALL_DIR/" 2>/dev/null

FORGE_JAR_PATH="$MINECRAFT_DIR/versions/${FORGE_VERSION_NAME}/${FORGE_VERSION_NAME}.jar"

if [ ! -f "$FORGE_JAR_PATH" ]; then
  echo "Error: Forge JAR not found"
  exit 1
fi

if ! command -v jq &> /dev/null; then
  echo "Error: jq is not installed"
  exit 1
fi

LIB_PATHS=$(jq -r '.libraries[]?.downloads.artifact.path' "$MINECRAFT_DIR/versions/${FORGE_VERSION_NAME}/${FORGE_VERSION_NAME}.json")
CLASSPATH="$FORGE_JAR_PATH"

for path in $LIB_PATHS; do
  FULL_PATH="$MINECRAFT_DIR/libraries/$path"
  if [ -f "$FULL_PATH" ]; then
    CLASSPATH="$CLASSPATH:$FULL_PATH"
  fi
done

echo "Launching Forge..."
java -Xmx4G -Xms2G \
  -Djava.library.path="$MINECRAFT_DIR/versions/${FORGE_VERSION_NAME}/natives" \
  -cp "$CLASSPATH" \
  net.minecraft.client.main.Main \
  --gameDir "$INSTALL_DIR" \
  --version "$FORGE_VERSION_NAME" \
  --assetsDir "$MINECRAFT_DIR/assets" \
  --username "Player"

遇到的问题

  • 游戏无法启动或立即退出
  • 终端无可见错误提示
  • 不确定mod是否被识别

疑问

  1. 是否真的可以不通过官方启动器这样启动Forge?
  2. 我为Forge构建classpath的方式是否正确?
  3. 隔离带mod的自定义实例的正确方法是什么?
  4. 是否有更好的实现方式或可参考的运行示例?

问题解答

1. 是否可以不通过官方启动器启动Forge?

完全可以。官方启动器本质是解析版本JSON文件、构建classpath并调用Java命令启动,手动复刻这个逻辑是可行的。

2. 构建classpath的方式是否正确?

你的方法存在几个核心问题:

  • 缺少原生库处理:Forge版本JSON中部分库包含natives字段,这些原生库需要解压到指定目录才能正常启动,你的脚本未处理这一步,空的natives目录会直接导致启动崩溃。
  • classpath顺序错误:Forge启动依赖严格的classpath加载顺序,直接追加所有库会打乱顺序,引发依赖加载失败。
  • 启动主类错误:Forge 1.13+的启动主类是net.minecraftforge.fml.loading.FMLClientLaunchProvider,而非原版的net.minecraft.client.main.Main,直接调用原版主类会跳过Forge初始化流程,导致启动失败。

3. 隔离自定义实例的正确方法

  • 完全独立的实例目录:除mods和config外,Forge会生成logs、cache、saves等文件夹,这些都应放在自定义INSTALL_DIR下。
  • 隔离版本文件:将Forge的版本目录(versions/<FORGE_VERSION_NAME>)复制到自定义实例目录,或启动时用--versionDir参数指向自定义版本目录,彻底脱离对.minecraft的依赖。
  • 可选的资源文件隔离:如果需要完全隔离,可将assets目录复制到自定义实例并指定--assetsDir,不过共用.minecraft的assets能节省存储空间,是更常用的方案。

4. 修正后的脚本及优化建议

以下是解决核心问题后的脚本:

#!/bin/bash

# 配置参数
FORGE_VERSION="1.20.1-47.4.0"
FORGE_INSTALLER="forge-${FORGE_VERSION}-installer.jar"
FORGE_VERSION_NAME="1.20.1-forge-47.4.0"
INSTALL_DIR="$HOME/MinecraftInstances/Forge-1.20.1"
MINECRAFT_DIR="$HOME/Library/Application Support/minecraft"
FORGE_URL="https://maven.minecraftforge.net/net/minecraftforge/forge/${FORGE_VERSION}/${FORGE_INSTALLER}"

# 创建实例目录结构
mkdir -p "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR/versions/$FORGE_VERSION_NAME"

# 下载Forge安装器(如果不存在)
if [ ! -f "$HOME/Downloads/$FORGE_INSTALLER" ]; then
  echo "Downloading Forge installer..."
  curl -o "$HOME/Downloads/$FORGE_INSTALLER" "$FORGE_URL"
fi

# 安装Forge到自定义实例目录(避免修改默认.mc)
echo "Installing Forge to custom instance..."
java -jar "$HOME/Downloads/$FORGE_INSTALLER" --installClient --target "$INSTALL_DIR"

# 复制默认mod和配置(仅复制不存在的文件)
mkdir -p "$INSTALL_DIR/mods" "$INSTALL_DIR/config"
cp -n "$MINECRAFT_DIR/mods/"* "$INSTALL_DIR/mods/" 2>/dev/null
cp -n "$MINECRAFT_DIR/config/"* "$INSTALL_DIR/config/" 2>/dev/null

# 检查必要文件是否存在
VERSION_JSON="$INSTALL_DIR/versions/$FORGE_VERSION_NAME/$FORGE_VERSION_NAME.json"
FORGE_JAR="$INSTALL_DIR/versions/$FORGE_VERSION_NAME/$FORGE_VERSION_NAME.jar"
if [ ! -f "$VERSION_JSON" ] || [ ! -f "$FORGE_JAR" ]; then
  echo "Error: Forge installation failed, missing version files"
  exit 1
fi

# 检查jq依赖
if ! command -v jq &> /dev/null; then
  echo "Error: jq is required, install with 'brew install jq'"
  exit 1
fi

# 按JSON顺序构建classpath
CLASSPATH="$FORGE_JAR"
LIB_PATHS=$(jq -r '.libraries[]?.downloads.artifact.path' "$VERSION_JSON")
for path in $LIB_PATHS; do
  FULL_PATH="$MINECRAFT_DIR/libraries/$path"
  if [ -f "$FULL_PATH" ]; then
    CLASSPATH="$CLASSPATH:$FULL_PATH"
  fi
done

# 获取Forge的启动主类
MAIN_CLASS=$(jq -r '.mainClass' "$VERSION_JSON")

# 解压原生库(如果未解压)
NATIVES_DIR="$INSTALL_DIR/versions/$FORGE_VERSION_NAME/natives"
if [ ! -d "$NATIVES_DIR" ] || [ -z "$(ls -A "$NATIVES_DIR")" ]; then
  echo "Extracting native libraries..."
  mkdir -p "$NATIVES_DIR"
  # 遍历并解压所有macOS原生库
  jq -r '.libraries[] | select(.natives != null) | .downloads.classifiers["natives-macos"].path' "$VERSION_JSON" | while read -r NAT_PATH; do
    FULL_NAT_PATH="$MINECRAFT_DIR/libraries/$NAT_PATH"
    if [ -f "$FULL_NAT_PATH" ]; then
      unzip -q -o "$FULL_NAT_PATH" -d "$NATIVES_DIR"
    fi
  done
fi

# 启动游戏
echo "Launching Forge instance..."
java -Xmx4G -Xms2G \
  -Djava.library.path="$NATIVES_DIR" \
  -cp "$CLASSPATH" \
  "$MAIN_CLASS" \
  --gameDir "$INSTALL_DIR" \
  --version "$FORGE_VERSION_NAME" \
  --versionDir "$INSTALL_DIR/versions" \
  --assetsDir "$MINECRAFT_DIR/assets" \
  --username "Player"

关键优化点

  • 直接安装到自定义目录:用Forge安装器的--target参数,将Forge安装到自定义实例目录,避免修改默认.minecraft。
  • 正确获取启动主类:从版本JSON中读取mainClass,确保启动Forge的完整初始化流程。
  • 自动解压原生库:处理版本JSON中的原生库,解压到实例的natives目录,解决启动崩溃问题。
  • 严格按JSON顺序构建classpath:保持与官方启动器一致的加载顺序,避免依赖冲突。
  • 增加错误检查:在关键步骤添加文件存在检查,提前定位问题。

调试建议

  • 查看游戏日志:启动后,日志文件会生成在$INSTALL_DIR/logs/latest.log,里面包含详细的启动错误信息,是定位问题的核心依据。
  • 开启调试日志:在启动命令中添加-Dfml.debug=true参数,可获取更详细的Forge初始化日志,便于排查mod加载问题。

内容的提问来源于stack exchange,提问作者E AI Electronic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 02:52:03