tdimino/bg3se-macos

GitHub: tdimino/bg3se-macos

将 Windows 版博德之门 3 脚本扩展器完整移植到 macOS 平台,通过 DYLD 注入和 ARM64 Hook 技术实现约 94% 的 API 功能对等,使依赖脚本扩展的 Mod 能在 Mac 上正常运行。

Stars: 30 | Forks: 5

Symbol of Tanit

# BG3SE-macOS **《博德之门 3》macOS 脚本扩展器** 一款原生的 macOS 版 BG3 Script Extender 实现,致力于全面实现与 Norbyte 的 Windows 版 BG3SE 的功能对等。使需要脚本功能的 Mod 能够在 Mac 上运行——包括随从 Mod、游戏性调整、UI 增强等。 ## 快速入门 ### 系统要求 - macOS 12+(已在 macOS 15.6.1 和 macOS 26.2 Tahoe 上测试) - Apple Silicon Mac(推荐)或 Intel Mac(功能受限) - 《博德之门 3》(Steam 版) - Xcode 命令行工具:`xcode-select --install` - CMake:`brew install cmake` ### 构建与安装 ``` # 使用 submodules 进行 Clone git clone --recursive https://github.com/tdimino/bg3se-macos.git cd bg3se-macos # 如果您已经 clone 但没有使用 --recursive: git submodule update --init --recursive # 使用 CMake 进行 Build mkdir -p build && cd build cmake .. cmake --build . ``` ### 验证构建是否成功 ``` # 检查输出文件是否存在(应该约为 3MB 的 universal binary) ls -la build/lib/libbg3se.dylib # 验证架构(应显示 arm64 和 x86_64) file build/lib/libbg3se.dylib ``` ### 配置 Steam 启动选项 1. 在 Steam 中右键点击 **Baldur's Gate 3** → **属性** 2. 在 **常规** → **启动选项** 下,输入 `bg3w.sh` 的 **完整路径**: /Users/YOUR_USERNAME/bg3se-macos/scripts/bg3w.sh %command% **重要提示:** 请将 `YOUR_USERNAME` 替换为您实际的 macOS 用户名。示例: /Users/john/bg3se-macos/scripts/bg3w.sh %command% 要查找您的路径,请在终端中运行此命令并复制输出: echo "$(cd bg3se-macos && pwd)/scripts/bg3w.sh %command%" ### 构建问题排查 | 问题 | 解决方案 | |---------|----------| | `cmake: command not found` | 安装 CMake:`brew install cmake` | | `CMake Error: could not find compiler` | 安装 Xcode 工具:`xcode-select --install` | | 缺少 Dobby/Lua/lz4 错误 | 初始化子模块:`git submodule update --init --recursive` | | 构建成功但没有 dylib | 检查 `build/lib/` 目录;确保构建已完成 | | `CMake Error: source directory does not exist` | 移动仓库后存在过期的缓存。删除 `build/` 并重新构建:`rm -rf build && mkdir build && cd build && cmake .. && cmake --build .` | | 代码更改未在游戏中生效 | CMake 缓存过期。删除 `build/` 目录并从头开始重新构建 | ### 使用 Script Extender Mod Script Extender (SE) Mod 是需要 BG3SE 才能运行的 Mod——它们使用 Lua 脚本来添加标准 Mod 制作无法实现的功能。安装 BG3SE-macOS 后,这些 Mod 就能像普通 Mod 一样工作: 1. 从 [Nexus Mods](https://www.nexusmods.com/baldursgate3) **下载** Mod 的 `.pak` 文件 2. 将其放入 `~/Documents/Larian Studios/Baldur's Gate 3/Mods/` 进行 **安装** 3. 使用游戏内的 Mod 管理器(或诸如 [BG3 Mod Manager](https://github.com/LaughingLeader/BG3ModManager) 等 Mod 管理工具)**启用** 该 Mod 4. 通过 Steam **启动** 游戏(使用上述配置的启动选项) ### Mod 兼容性 大多数为 Windows 版 Script Extender 设计的 SE Mod 都可以在 macOS 上运行。我们正在积极测试热门 Mod 并追踪其兼容性: | Mod | 作者 | 状态 | 备注 | |-----|--------|--------|-------| | [More Reactive Companions](https://www.nexusmods.com/baldursgate3/mods/5447) | LightningLarryL | ✅ 正常运行 | 队伍闲聊、随从反应 | 这只是一个示例——更多的 Mod 开箱即用。完整兼容性列表、测试说明及已知问题请参阅 **[docs/supported-mods.md](docs/supported-mods.md)**。 **测试过某个 Mod?** 请通过[报告您的结果](https://github.com/tdimino/bg3se-macos/issues/new?template=mod-compatibility.md)来帮助社区!无论它是完美运行还是存在问题,您的反馈都能帮助其他 Mac 玩家。 ## 状态 **版本:** v0.36.50 | **功能对等度:** ~94% | 功能 | 状态 | |---------|--------| | DYLD 注入 | ✅ 已完成 | | Lua 运行时 | ✅ Lua 5.4 及 Ext API | | Mod 加载 | ✅ PAK 文件读取,自动检测 | | Ext.Osiris | ✅ 事件监听器,自定义函数 (NewCall/NewQuery/NewEvent/RaiseEvent/GetCustomFunctions),**服务器上下文守卫** | | Ext.Entity | ✅ GUID 查找,**双 EntityWorld** (客户端 + 服务器),**1,999 个组件已注册** (534 种布局:169 个已验证 + 365 个自动生成),**1,577 个 ARM64 大小** + **702 个 Windows 估算** = **1,730 总计** (87% 覆盖率) | | Ext.Stats | ✅ **100% 对等** — 15,774 项属性,Get/GetAll/Create/Sync,CopyFrom,SetRawAttribute,ExecuteFunctors,TreasureTable/TreasureCategory 桩代码 | | Ext.Events | ✅ 33 个事件 (13 个生命周期 + 17 个引擎 + 2 个函子 + 1 个网络) 及 Prevent 模式,**运行时 Mod 归因** + `!mod_diag` | | Ext.IO | ✅ LoadFile,SaveFile,**AddPathOverride,GetPathOverride** | | Ext.Timer | ✅ WaitFor,WaitForRealtime,Cancel,Pause,Resume,**MicrosecTime,ClockEpoch,ClockTime,GameTime,DeltaTime,Ticks,持久计时器 (6 个函数)** | | Ext.Vars | ✅ PersistentVars + 用户变量 + Mod 变量 | | Ext.Input | ✅ 热键,按键注入 | | Ext.Math | ✅ 向量/矩阵运算,**16 个四元数函数**,标量工具 | | Ext.Enums | ✅ 14 种枚举/位域类型 | | Ext.Types | ✅ 完整反射 API (9 个函数),用于 VS Code IntelliSense 的 **GenerateIdeHelpers** | | Ext.StaticData | ✅ **全部 9 种类型** (专长、种族、背景、起源、神祇、职业、进度、行动资源、专长描述) 通过 ForceCapture 实现 | | Ext.Resource | ✅ Get,GetAll,GetTypes,GetCount (34 种资源类型) | | Ext.Template | ✅ **自动捕获**,迭代 (Cache/LocalCache),GUID 解析 | | Ext.Level | ✅ **9 个函数** - RaycastClosest,RaycastAny,TestBox,TestSphere,GetHeightsAt,单例访问器 | | Ext.Audio | ✅ **13 个函数** - PostEvent,Stop,PauseAll,ResumeAll,SetSwitch,SetState,SetRTPC,GetRTPC,ResetRTPC,LoadEvent,UnloadEvent | | Ext.Net | ✅ **Phase 4I 完成** - 完整的 RakNet 后端,PostMessageToServer/User/Client,BroadcastMessage,IsHost,IsReady,PeerVersion,**请求/回复回调** | | Ext.RegisterNetListener | ✅ 按频道划分的网络消息监听器 (MCM 骨干) | | Net.CreateChannel | ✅ **Phase 4I 完成** - 高层 Channel API,包含 SetHandler、**SetRequestHandler**、SendToServer、**带回调的 RequestToServer**、Broadcast | | Ext.Utils | ✅ Print,PrintWarning,PrintError,Version,MonotonicTime,GetGameState | | Ext.ModEvents | ✅ 按 Mod 划分的跨 Mod 事件系统 (Subscribe,Throw,Unsubscribe) | | Ext.Mod | ✅ IsModLoaded,GetLoadOrder,GetMod,GetBaseMod | | 生命周期作用域 | ✅ 防止过期的对象访问 | | 上下文系统 | ✅ **服务器/客户端上下文感知**,Ext.IsServer/IsClient/GetContext,两阶段引导 | | 调试控制台 | ✅ 套接字 + 文件 + 游戏内覆盖层 | | 崩溃归因 | ✅ **运行时 Mod 追踪** — 按处理程序划分的 Mod 名称,`!mod_diag` 控制台,软禁用,附带 Mod 上下文的增强型崩溃报告 | | 测试 | ✅ `!test` 测试套件 (85 项测试),`!test_ingame` (40 项测试),Debug.* 助手,Frida 脚本 | 详细进展请参见 [ROADMAP.md](ROADMAP.md)。 ## 文档 | 文档 | 描述 | |----------|-------------| | **[docs/supported-mods.md](docs/supported-mods.md)** | 已测试的 Mod 兼容性列表 | | **[docs/getting-started.md](docs/getting-started.md)** | 安装、构建与首次运行 | | **[docs/api-reference.md](docs/api-reference.md)** | 完整的 Ext.* 和 Osi.* API 文档 | | **[docs/architecture.md](docs/architecture.md)** | 技术深潜:注入、Hook、ARM64 | | **[docs/development.md](docs/development.md)** | 贡献、构建功能、调试 | | **[docs/contributor-workflow.md](docs/contributor-workflow.md)** | 端到端指南:研究、Ghidra、实现 | | **[docs/reverse-engineering.md](docs/reverse-engineering.md)** | Ghidra 工作流、偏移量发现 | | **[docs/crash-attribution.md](docs/crash-attribution.md)** | Mod 崩溃归因:三层诊断 | | **[docs/troubleshooting.md](docs/troubleshooting.md)** | 常见问题与解决方案 | | **[docs/arm64/](docs/arm64/)** | ARM64 Hook 模式,预防策略 | | **[docs/solutions/](docs/solutions/)** | 已记录的问题解决方案 | ## 实时控制台 有三种方式可以与 Lua 运行时交互: 1. **游戏内覆盖层** - 按 **Ctrl+`** 切换 2. **套接字控制台** - `./build/bin/bg3se-console` 3. **基于文件的控制台** - 写入至 `~/Library/Application Support/BG3SE/commands.txt` ``` # Socket 控制台(推荐用于开发) ./build/bin/bg3se-console # 或者通过 socat socat - UNIX-CONNECT:/tmp/bg3se.sock ``` ## 文件结构 ``` bg3se-macos/ ├── src/ │ ├── injector/ │ │ └── main.c # Core injection, Dobby hooks, Lua state init │ ├── core/ │ │ ├── logging.c/h # Structured logging (14 modules, 4 levels) │ │ ├── safe_memory.c/h # Safe memory read/write (mach_vm) │ │ └── version.h # Version info, data paths │ ├── lua/ │ │ ├── lua_ext.c/h # Ext.Print, Ext.Utils, Ext.Memory │ │ ├── lua_stats.c/h # Ext.Stats API │ │ ├── lua_events.c/h # Ext.Events system │ │ ├── lua_timer.c/h # Ext.Timer API │ │ ├── lua_osiris.c/h # Osi.* namespace bindings │ │ ├── lua_debug.c/h # Ext.Debug memory introspection │ │ ├── lua_json.c/h # JSON encode/decode │ │ ├── lua_resource.c/h # Ext.Resource bindings │ │ ├── lua_template.c/h # Ext.Template bindings │ │ ├── lua_staticdata.c/h # Ext.StaticData bindings │ │ └── lua_persistentvars.c/h # Ext.Vars persistence │ ├── entity/ │ │ ├── entity_system.c/h # Core ECS, Lua bindings │ │ ├── guid_lookup.c/h # GUID parsing, HashMap ops │ │ ├── arm64_call.c/h # ARM64 ABI wrappers (x8 indirect return) │ │ ├── component_*.c/h # Component registry, lookup, TypeId │ │ ├── generated_typeids.h # Auto-generated 1,999 TypeId addresses │ │ ├── generated_component_registry.c # Auto-registration code │ │ └── entity_storage.h # Storage structures, Ghidra base addr │ ├── stats/ │ │ └── stats_manager.c/h # RPGStats access, property resolution │ ├── strings/ │ │ └── fixed_string.c/h # GlobalStringTable resolution │ ├── osiris/ │ │ ├── osiris_functions.c/h # Osiris function lookup/call │ │ ├── osiris_types.h # FuncDef, OsiArgumentDesc structs │ │ ├── custom_functions.c/h # Custom Osiris function registration │ │ └── pattern_scan.c/h # Memory pattern scanning │ ├── console/ │ │ └── console.c/h # Socket + file-based console │ ├── input/ │ │ ├── input_hooks.m # macOS input event hooks │ │ └── lua_input.c # Ext.Input API │ ├── overlay/ │ │ └── overlay.m/h # In-game debug overlay (NSWindow) │ ├── timer/ │ │ └── timer.c/h # Timer system implementation │ ├── game/ │ │ └── game_state.c/h # Game state tracking │ ├── mod/ │ │ └── mod_loader.c/h # Mod detection, PAK loading │ ├── pak/ │ │ └── pak_reader.c/h # LSPK v18 PAK file parsing │ ├── math/ │ │ └── math_ext.c/h # Ext.Math vector/matrix ops │ ├── resource/ │ │ └── resource_manager.c/h # Ext.Resource (34 resource types) │ ├── staticdata/ │ │ └── staticdata_manager.c/h # Ext.StaticData (Feats, etc.) │ ├── template/ │ │ └── template_manager.c/h # Ext.Template (auto-capture) │ └── hooks/ │ └── osiris_hooks.c/h # Osiris event interception │ ├── ghidra/ │ ├── scripts/ # Ghidra Python analysis scripts │ │ ├── run_analysis.sh # Headless analyzer wrapper │ │ ├── find_rpgstats.py # Discover gRPGStats global │ │ ├── find_entity_offsets.py │ │ └── ... │ └── offsets/ # Discovered offset documentation │ ├── STATS.md # RPGStats, FixedStrings (0x348) │ ├── ENTITY_SYSTEM.md # ECS architecture │ ├── RESOURCE.md # ResourceManager (0x08a8f070) │ ├── TEMPLATE.md # Template managers │ └── ... │ ├── docs/ │ ├── components/ # Component documentation by namespace │ │ ├── README.md # Component reference overview │ │ ├── eoc-components.md # 701 eoc:: components │ │ ├── esv-components.md # 596 esv:: components │ │ ├── ecl-components.md # 429 ecl:: components │ │ └── ls-components.md # 233 ls:: components │ └── ... # Other user-facing documentation │ ├── tools/ │ ├── bg3se-console.c # Standalone readline console client │ ├── extract_pak.py # PAK file extractor │ ├── extract_typeids.py # Generate TypeId header from binary │ └── frida/ # Frida instrumentation scripts │ ├── scripts/ │ ├── build.sh # Build script │ ├── bg3w.sh # Steam launch wrapper (ARM64) │ ├── bg3w-intel.sh # Steam launch wrapper (Intel) │ └── launch_bg3.sh # Direct launch for testing │ ├── lib/ # Third-party libraries │ ├── Dobby/ # Inline hooking framework │ ├── lua/ # Lua 5.4 │ └── lz4/ # Compression for PAK files │ ├── agent_docs/ # Claude Code context docs ├── plans/ # Implementation plans └── test-mods/ # Test mod examples ``` ## 致谢 ### 特别感谢 如果没有 **[Norbyte](https://github.com/Norbyte)** 以及他们在原始 Windows 版 [BG3 Script Extender](https://github.com/Norbyte/bg3se) 上的开创性工作,这个项目是不可能实现的。他们对拉瑞安 Osiris 脚本引擎的逆向工程、全面的 API 设计,以及多年来对 Mod 社区的无私奉献,为这个 macOS 移植版奠定了基础。我们对他们为 BG3 Mod 生态系统所作出的开源贡献表示最深切的感激。 ### 贡献者 - [Norbyte 的 BG3SE](https://github.com/Norbyte/bg3se) - 原始的 Windows 版 Script Extender - [Dobby](https://github.com/jmpews/Dobby) - ARM64/x86_64 内联 Hook 框架 - [fishhook](https://github.com/facebook/fishhook) - 符号重绑定库 - [LZ4](https://github.com/lz4/lz4) - 用于 PAK 文件读取的快速压缩库 - [Dear ImGui](https://github.com/ocornut/imgui) - 调试覆盖层 UI 框架 ## 许可证 MIT 许可证 ## 作者 - Tom di Mino (曾用名 [Pnutmaster](https://wiki.twcenter.net/index.php?title=Blood_Broads_%26_Bastards) / [Nexus](https://next.nexusmods.com/profile/Pnutmaster/mods?gameId=130)) - [Claude Code](https://claude.ai/claude-code) (Anthropic) ### 附言 我还要感谢这篇 BG3SE issue 的发帖人和评论者:**["[Feature Bounty - $350] MacOS Supported Version of BG3 SE"](https://github.com/Norbyte/bg3se/issues/162)**。是你们开启了这项任务 :) ## 题词
标签:Apple Silicon, Baldur's Gate 3, Bash脚本, BG3, C++, CMake, CVE监控, dylib, Intel, Lua, Mod, RPG, Script Extender, Steam, UI增强, 动态链接库, 客户端加密, 开源, 数据擦除, 注入, 游戏修改, 游戏开发, 游戏模组, 游戏辅助工具, 脚本扩展器