Files
Commonwealth-Online-Public/docs/PATCH_MainMenu_Multiplayer.md
T
andrew 9c84c9d4bc Add FFDec docs/tools and server-browser fixes
Add comprehensive FFDec walkthrough and short patch docs for safely adding a Multiplayer item to MainMenu.swf, plus helper scripts to extract the vanilla SWF and restore it (tools/extract_ba2.py, tools/restore-vanilla-mainmenu.ps1). Update exported MainMenu.as with a warning comment and remove an outdated exported PATCH markdown. Patch binary Interface/MainMenu.swf (updated).

Hardening fixes in the plugin: include GFx headers, avoid leaving the PrismaUI overlay focused after menu changes, only call OnBrowserHidden when the browser was actually visible, and add IsMainMenuOnMainPanel() so WatchMainMenuState ignores MainMenu when not on the MAIN_STATE. Ensure events are only dispatched when the browser is valid & visible (CanDispatchToBrowser) and make Scaleform UI hide the browser immediately during transitions. These changes prevent the overlay from staying focused during Settings transitions and stop JS events from being sent to a hidden/invalid view.
2026-06-08 22:26:00 +12:00

160 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MainMenu.swf — Multiplayer button patch guide
> **Full FFDec walkthrough:** see [`FFDEC_MainMenu_Multiplayer_Guide.md`](FFDEC_MainMenu_Multiplayer_Guide.md) for exact search anchors, before/after snippets, and a test checklist.
Add a **Multiplayer** item to the title-screen main menu. Selecting it calls `root.f4se.plugins.commonwealthOnline.openManager()`, which opens the PrismaUI server browser (same as **F9**).
## CRITICAL — edit methods, not the whole script
**Never** paste the full exported `MainMenu.as` into FFDec or use **Import script** on the whole class. That recompiles `RequestOptions` from decompiled source and **breaks Settings → Gameplay / Display / Audio**.
In FFDec, edit **individual methods** (double-click the method under **MainMenu** traits). FFDec then recompiles only that method and leaves vanilla bytecode (including `RequestOptions`) intact.
Restore vanilla any time:
```powershell
.\tools\restore-vanilla-mainmenu.ps1
```
## Prerequisites
- [JPEXS FFDec](https://github.com/jindrapetrik/jpexs-decompiler/releases)
- Game launched via **F4SE** with `CommonwealthOnline.dll` installed
- Loose Interface overrides enabled in `Fallout4Custom.ini`:
```ini
[Archive]
bInvalidateOlderFiles=1
```
## FFDec workflow
1. Copy `Interface/MainMenu.swf.vanilla.bak``Interface/MainMenu.swf` (start from vanilla every time).
2. Open `Interface/MainMenu.swf` in FFDec.
3. In the left tree: **scripts → MainMenu** (class traits list, not “Edit ActionScript” on the whole class).
4. Apply the **four method-level edits** below (double-click each method to open its editor, save after each).
5. **File → Save**.
6. Sanity check: patched SWF should stay **~6263 KB**. If it jumps to **64 KB+**, settings are likely broken — restore vanilla and retry using **method** editors only.
7. Copy to `Fallout 4/Data/Interface/MainMenu.swf`.
8. Test **Settings → Gameplay / Display / Audio** first, then **Multiplayer**.
---
## Edit 1 — Add constant (class body)
Open the **MainMenu** class initializer / constants section (or edit at top of class in trait view). After `INSTALLED_CONTENT_INDEX`:
```actionscript
private const MULTIPLAYER_INDEX:Number = 15;
```
Index `15` is unused in vanilla (highest is `INSTALLED_CONTENT_INDEX = 14`).
---
## Edit 2 — `InitList()` — add menu row
In **`InitList`**, find the `$LOAD` push (after `$NEW` on title screen). Insert **before** the PS5 transfer block:
```actionscript
this.MainPanel_mc.List_mc.entryList.push({
"text":"$LOAD",
"disabled":!this.HasRecentSave || !param6,
"index":this.LOAD_INDEX
});
if(!this.PauseMode)
{
this.MainPanel_mc.List_mc.entryList.push({
"text":"Multiplayer",
"index":this.MULTIPLAYER_INDEX
});
}
if(param8 == true)
```
Use literal `"Multiplayer"` (no `$` prefix) unless you add a row to `Interface/Translate_en.txt`.
---
## Edit 3 — `onMainListItemPress()` — handle click
In the main `switch(this.MainPanel_mc.List_mc.selectedEntry.index)`, add **before** `case this.HELP_INDEX:`:
```actionscript
case this.MULTIPLAYER_INDEX:
this.BGSCodeObj.PlayOKSound();
if(root.f4se != null && root.f4se.plugins != null && root.f4se.plugins.commonwealthOnline != null)
{
root.f4se.plugins.commonwealthOnline.openManager();
}
break;
```
---
## Edit 4 (recommended) — auto-close browser
The plugin also hides the browser when the menu leaves `MAIN_STATE`, but these SWF hooks close it immediately when navigating away.
### 4a — Add new method `CloseMultiplayerBrowser`
In FFDec: **MainMenu → right-click → Add script** / add method:
```actionscript
private function CloseMultiplayerBrowser() : *
{
if(root.f4se != null && root.f4se.plugins != null && root.f4se.plugins.commonwealthOnline != null)
{
root.f4se.plugins.commonwealthOnline.closeManager();
}
}
```
### 4b — Edit `set currentState`
After `this.strCurrentState = param1;`:
```actionscript
this.strCurrentState = param1;
if(param1 != this.MAIN_STATE)
{
this.CloseMultiplayerBrowser();
}
this.UpdateButtons(param1);
```
### 4c — Edit `onMainListItemPress`
After the `while(this.strCurrentState != this.MAIN_STATE)` loop, before the `switch`:
```actionscript
if(this.MainPanel_mc.List_mc.selectedEntry.index != this.MULTIPLAYER_INDEX)
{
this.CloseMultiplayerBrowser();
}
```
---
## Test plan
| Step | Expected |
|------|----------|
| Main menu shows **Multiplayer** between Load and Add-ons | Yes |
| Click **Multiplayer** | Server browser opens |
| Open **Settings → Display** | No crash |
| Open **Settings → Gameplay / Audio** | No crash |
| Select **Continue** while browser open | Browser closes |
| **F9** | Still toggles browser |
---
## Reference
Full decompiled class (do **not** import wholesale): [`scripts/MainMenu.as`](scripts/MainMenu.as)
Plugin API registered in `CommonwealthOnline.dll`:
- `root.f4se.plugins.commonwealthOnline.openManager()`
- `root.f4se.plugins.commonwealthOnline.closeManager()`