Claude-skill-registry bg3se-macos-ghidra

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/bg3se-macos-ghidra" ~/.claude/skills/majiayu000-claude-skill-registry-bg3se-macos-ghidra && rm -rf "$T"
manifest: skills/data/bg3se-macos-ghidra/SKILL.md
source content

BG3 Script Extender macOS + Ghidra Development

Project Locations

ProjectPath
bg3se-macos
/Users/tomdimino/Desktop/Programming/bg3se-macos
bg3se (Windows ref)
/Users/tomdimino/Desktop/Programming/bg3se

Quick Start

# Build
cd /Users/tomdimino/Desktop/Programming/bg3se-macos/build
cmake .. && cmake --build .

# Test
./scripts/launch_bg3.sh
tail -f ~/Library/Application\ Support/BG3SE/bg3se.log

# Ghidra (headless, optimized)
./ghidra/scripts/run_analysis.sh <script.py>

Key Constraints (macOS)

  1. Cannot hook main binary - Hardened Runtime blocks
    __TEXT
    hooks
  2. CAN hook libOsiris.dylib - 1,013 exported symbols
  3. ARM64 ABI - x8 register for structs >16 bytes
  4. No GetRawComponent - Must traverse ECS manually

See macos-patterns.md for detailed differences.

Module Structure

src/
├── injector/main.c   # Core (~2900 lines): hooks, Osi.*, Lua state
├── entity/           # ECS: guid_lookup, component_lookup, arm64_call
├── lua/              # Ext.* APIs: stats, debug, osiris, json
├── osiris/           # Osiris types, functions, custom_functions
├── stats/            # RPGStats, GlobalStringTable
├── console/          # Socket server, file-based console
└── input/            # CGEventTap keyboard capture

API Surface (v0.22.0)

NamespaceStatusNotes
Osi.*
95%Dynamic metatable, Query/Call/Event
Ext.Osiris
95%RegisterListener, NewCall/Query/Event
Ext.Stats
95%Property read/write
Ext.Entity
50%Get, GetComponent, GetAllEntitiesWithComponent
Ext.Events
75%7 events
Ext.Timer
100%Complete
Ext.Debug
100%Memory introspection

Not implemented:

Ext.Net
,
Ext.UI
,
Ext.Level
, Client Lua State

Key Offsets

SymbolAddress/Offset
esv::EocServer::m_ptr
0x10898e8b8
EntityWorldEocServer+
0x288
RPGStats::m_ptr
base+
0x89c5730
RPGStats.FixedStrings
+
0x348
GlobalStringTablebase+
0x8aeccd8

osgrep Usage

# IMPORTANT: cd into project first
cd /Users/tomdimino/Desktop/Programming/bg3se-macos
osgrep "how does entity lookup work"
osgrep "Ext.Stats property resolution"

# Windows reference
cd /Users/tomdimino/Desktop/Programming/bg3se
osgrep "CustomFunctionManager"

Common Tasks

Add new Ext. API:*

  1. Implement in
    src/lua/lua_*.c
  2. Register in
    lua_*_register()
    function
  3. Test with EntityTest mod

Discover offset:

  1. Search strings in Ghidra
  2. Find XREFs, trace ADRP+LDR pattern
  3. Document in
    ghidra/offsets/*.md

Port Windows feature:

  1. Search Windows BG3SE:
    osgrep "feature" -p /path/to/bg3se
  2. Understand pattern, find ARM64 equivalents
  3. Adapt for macOS constraints

Reference Documentation

Troubleshooting

Crashes on launch: Check dylib signing (

codesign -dv
), verify ARM64 (
file
)

Hooks not called: Only hook libOsiris, not main binary

Entity lookup NULL: EoCServer may not be initialized; verify offset 0x288

osgrep no results: Run from project directory or use

-p
flag