# Tdimino Bg3se Macos Bg3se Macos Ghidra

> BG3 Script Extender macOS + Ghidra Development

- Skill: `tomevault-io/tdimino-bg3se-macos-bg3se-macos-ghidra` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/tdimino-bg3se-macos-bg3se-macos-ghidra`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/tdimino-bg3se-macos-bg3se-macos-ghidra/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/tdimino-bg3se-macos-bg3se-macos-ghidra

---


# BG3 Script Extender macOS + Ghidra Development

## Project Locations

| Project | Path |
|---------|------|
| **bg3se-macos** | `/Users/tomdimino/Desktop/Programming/bg3se-macos` |
| **bg3se** (Windows ref) | `/Users/tomdimino/Desktop/Programming/bg3se` |

## Quick Start

```bash
# 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](references/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)

| Namespace | Status | Notes |
|-----------|--------|-------|
| `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

| Symbol | Address/Offset |
|--------|----------------|
| `esv::EocServer::m_ptr` | `0x10898e8b8` |
| EntityWorld | EocServer+`0x288` |
| `RPGStats::m_ptr` | base+`0x89c5730` |
| `RPGStats.FixedStrings` | +`0x348` |
| GlobalStringTable | base+`0x8aeccd8` |

## osgrep Usage

```bash
# 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

- **[macos-patterns.md](references/macos-patterns.md)** - macOS vs Windows, GUID byte order, component traversal
- **[bg3se-architecture.md](references/bg3se-architecture.md)** - Windows BG3SE structure
- **[arm64-patterns.md](references/arm64-patterns.md)** - x8 register, calling conventions
- **[ghidra-workflows.md](references/ghidra-workflows.md)** - Script usage, analysis patterns
- **[offset-discovery.md](references/offset-discovery.md)** - Finding game addresses

## 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

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/tdimino) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-11 -->

