# Advanced Custom Overrides

Deep dive into the custom override system for advanced MZ customization.

## Override System Architecture

```
RPGReact Plugin (RPGReact.js)
    ↓
Loads overrides.manifest.json
    ↓
Evaluates each override file in order
    ↓
Promotes exported functions to global scope
    ↓
Injects helpers (event, createEventData, etc.)
    ↓
Overrides execute and modify RMMZ prototypes
```

## Manifest Structure

**File:** `js/plugins/rpgreact/overrides.manifest.json`

```json
{
  "entries": [
    { "file": "override_common.js", "export": "overrideCommon" },
    { "file": "override_game_actor.js", "export": "overrideGameActor" },
    { "file": "override_scene_battle.js", "export": "overrideSceneBattle" },
    { "file": "custom/my_override.js", "export": "myCustomOverride" }
  ]
}
```

**Requirements:**

* `entries` array must be present and non-empty
* Order matters - earlier overrides execute first
* Each entry must have `file` and `export` properties
* `file` path is relative to `js/plugins/rpgreact/`
* `export` must match the function name exported by the file

## Creating Custom Overrides

### Step 1: Create Override File

Create `js/plugins/rpgreact/custom/my_override.js`:

```js
function myCustomOverride(event, createEventData, createExtraData, reactBridge, decorateData) {
  // Override RMMZ prototypes
  const _Scene_Map_update = Scene_Map.prototype.update;
  Scene_Map.prototype.update = function() {
    _Scene_Map_update.call(this);

    // Custom logic
    if (Input.isTriggered('pageup')) {
      event(RPGEventType.CUSTOM_EVENT, 'myEvent', { data: 'value' }, 'MyOverride');
    }
  };

  // Override other prototypes as needed
  Game_Player.prototype.customMethod = function() {
    // Custom player method
  };
}
```

### Step 2: Add to Manifest

Edit `js/plugins/rpgreact/overrides.manifest.json`:

```json
{
  "entries": [
    /* existing entries */,
    { "file": "custom/my_override.js", "export": "myCustomOverride" }
  ]
}
```

### Step 3: Test

1. Playtest in RPG Maker MZ (development mode)
2. Check console for errors
3. Verify override behavior

## Injected Helpers

Each override function receives these parameters:

### event(eventType, eventSpecifier, data, trace)

Emit events to React UI with automatic platform context.

```js
event(
  RPGEventType.BATTLE_ACTION,
  RPGBattleActionSpecifier.START,
  { battler, action },
  'BattleOverride'
);
```

**Parameters:**

* `eventType` - Event category (from `RPGEventType` enum)
* `eventSpecifier` - Event subcategory (string or enum value)
* `data` - Custom payload object
* `trace` - Debug identifier (appears in console)

### createEventData()

Rebuilds complete event data from current game state.

```js
// After major state change (new game, load game)
createEventData();
```

### createExtraData(field?)

Retrieves specific extra data fields.

```js
const mapInfo = createExtraData('map');
const battleInfo = createExtraData('battle');
```

### reactBridge

Access to the React bridge instance.

```js
// Check if React initialized
if (reactBridge.IsInitialized()) {
  // Safe to emit events
}

// Get platform data
const platformData = reactBridge.GetPlatformData();
```

### decorateData(object)

Wrap MZ objects with MobX observables for reactivity.

```js
const actor = decorateData(new Game_Actor(actorId));
// actor properties are now observable by React
```

## Common Override Patterns

### Adding Custom Menu Command

```js
function overrideCustomMenu(event, createEventData, createExtraData, reactBridge) {
  const _Scene_Menu_createCommandWindow = Scene_Menu.prototype.createCommandWindow;
  Scene_Menu.prototype.createCommandWindow = function() {
    _Scene_Menu_createCommandWindow.call(this);

    // Add custom command
    this._commandWindow.setHandler('myCommand', () => {
      // Open custom screen
      event(RPGEventType.SCREEN_OPEN, RPGScreen.CustomScreen, {}, 'CustomMenu');
    });
  };
}
```

### Custom Battle Action

```js
function overrideBattleAction(event, createEventData, createExtraData, reactBridge) {
  const _BattleManager_startAction = BattleManager.startAction;
  BattleManager.startAction = function() {
    const action = this._subject.currentAction();

    // Emit custom event before action
    event(RPGEventType.BATTLE_ACTION, 'CUSTOM_START', {
      subject: this._subject,
      action: action
    }, 'CustomBattle');

    _BattleManager_startAction.call(this);
  };
}
```

### Intercepting Input

```js
function overrideInput(event, createEventData, createExtraData, reactBridge) {
  const _Input_update = Input.update;
  Input.update = function() {
    _Input_update.call(this);

    // Custom hotkey
    if (Input.isTriggered('debug') && Input.isPressed('shift')) {
      event(RPGEventType.CUSTOM_EVENT, 'debugMenu', {}, 'InputOverride');
    }
  };
}
```

## Production Bundling

### Development vs Production

**Development (playtest):**

* Individual files loaded
* Can see which override failed in console
* Fast iteration

**Production (packaged):**

* All overrides concatenated and minified
* Single file: `RPGReact.overrides.min.js`
* Original files removed
* Faster load time

### Build Process

```powershell
./build-package.ps1 -Target windows
```

1. Script reads `overrides.manifest.json`
2. Concatenates files in order
3. Wraps each in IIFE
4. Promotes exports to global scope
5. Minifies with esbuild
6. Removes individual source files

### Troubleshooting Production

**Override doesn't execute:**

* Check export name matches manifest exactly (case-sensitive)
* Verify file exists at specified path
* Look for minification errors in console

**Syntax error in minified bundle:**

* Test each override individually in development
* Check for invalid JavaScript syntax
* Ensure all functions are properly closed

## Best Practices

### 1. Namespace Custom Methods

```js
// ❌ BAD: Pollutes global prototype
Game_Actor.prototype.calculate = function() { /* ... */ };

// ✅ GOOD: Use prefix
Game_Actor.prototype.myGame_calculate = function() { /* ... */ };
```

### 2. Store Original Methods

```js
// ✅ GOOD: Can call original
const _original = Scene_Map.prototype.update;
Scene_Map.prototype.update = function() {
  _original.call(this);
  // Custom logic
};
```

### 3. Guard Event Emissions

```js
// ✅ GOOD: Check if React ready
if (reactBridge.IsInitialized()) {
  event(RPGEventType.CUSTOM_EVENT, 'data', {}, 'Guard');
}
```

### 4. Handle Errors Gracefully

```js
try {
  // Custom logic that might fail
  riskyOperation();
} catch (error) {
  console.error('[MyOverride] Error:', error);
  // Fallback or recovery
}
```

### 5. Document Override Purpose

```js
/**
 * Custom Battle Rewards Override
 * Adds bonus gold based on battle performance
 * Author: YourName
 * Version: 1.0
 */
function overrideBattleRewards(event, createEventData, createExtraData, reactBridge) {
  // Implementation
}
```

## Advanced Techniques

### Conditional Overrides

```js
function overrideConditional(event, createEventData, createExtraData, reactBridge) {
  // Only override if certain plugin is present
  if (typeof PluginManager !== 'undefined' && PluginManager.parameters('OtherPlugin')) {
    Scene_Battle.prototype.customMethod = function() {
      // Custom implementation
    };
  }
}
```

### Cross-Override Communication

```js
// In first override
globalThis.myGameData = { customFlag: false };

// In second override (loaded after first)
if (globalThis.myGameData) {
  globalThis.myGameData.customFlag = true;
}
```

### Dynamic Event Types

```js
function overrideDynamic(event, createEventData, createExtraData, reactBridge) {
  Scene_Map.prototype.emitCustom = function(type, data) {
    event(RPGEventType.CUSTOM_EVENT, type, data, 'Dynamic');
  };
}

// Usage elsewhere
$gameMap.emitCustom('playerMoved', { x: player.x, y: player.y });
```

## See Also

* [Custom Overrides (Basic)](https://rpgreact.rockon.games/plugin/overrides)
* [Plugin Commands](https://rpgreact.rockon.games/plugin/commands)
* [Event Reference](https://rpgreact.rockon.games/ui/events)
* [Packaging Guide](https://rpgreact.rockon.games/tooling/packaging)
