Skip to content

test_coverage

runner edited this page Oct 16, 2026 · 9 revisions

Endfield_FineWine Development Documentation

Arknights: Endfield on Apple Silicon — A set of patches to CrossOver's (LGPL) Wine, plus scripts and documentation to build and deploy them. This project enables Arknights: Endfield to run on Apple Silicon Macs through a custom-patched CrossOver Wine build.


Table of Contents

  1. Project Overview
  2. Development Environment Setup
  3. Project Structure & Architecture
  4. Build Process
  5. Deployment & Installation
  6. Testing Procedures
  7. CI/CD Pipeline
  8. Coding Standards & Guidelines
  9. Code Review Procedures
  10. Debugging & Troubleshooting
  11. Contribution Guidelines
  12. Development Tools & Links
  13. License & Legal

1. Project Overview

What This Is

Endfield_FineWine is a compatibility layer that allows Arknights: Endfield to run on Apple Silicon macOS through a custom-patched CrossOver Wine. It consists of:

  • Patches to CrossOver's Wine (LGPL-2.1-or-later)
  • Build and deployment scripts (Bash, Python)
  • Documentation covering the engineering behind the fix

What This Is NOT

  • It does not contain or redistribute CrossOver, Wine, Apple's Game Porting Toolkit (GPTK), or the game
  • It does not bypass anti-cheat; it adjusts the CrossOver environment to allow Endfield's ACE anti-cheat services to run uninterrupted
  • It is not affiliated with Gryphline/Hypergryph, Tencent, CodeWeavers, or Apple

Scope & Ethics

⚠️ These patches for CrossOver are provided as-is. While the patches allow the Endfield anti-cheat to operate on macOS like it does on Windows, using this tool is your choice, and you take on the risks associated with that.

  • Own the game; this is compatibility work (same category as Valve's Proton on Linux)
  • No in-game advantage, no modified game logic, no DRM circumvention
  • Running the game in an unsupported configuration may violate its Terms of Service; that risk is yours (see LICENSE)

2. Development Environment Setup

Hardware Requirements

Component Requirement
Mac Apple Silicon (M-series) — Intel is not supported
macOS 15 (Sequoia) or newer — tested on 27.0 / 26.5
Cooling Actively cooled Mac required (MacBook Pro, Mac Studio, Mac mini). MacBook Air is OFF-LIMITS (no active cooling)
RAM 16 GB minimum; 24 GB+ recommended

Software Dependencies

Dependency Version Purpose
Rosetta 2 Required softwareupdate --install-rosetta --agree-to-license
CrossOver 26.3 Licensed install from codeweavers.com
Xcode CLT Latest xcode-select --install
Homebrew Latest brew.sh — Apple Silicon (/opt/homebrew)
Disk space ~5 GB For the build tree
Build time ~10–60 min ~10 min on 10-core M4; 1.5–2.5 h cold on 3-vCPU CI runner

Cloning the Repository

git clone <your-fork-url> Endfield_FineWine
cd Endfield_FineWine
```bash

### Initial Environment Verification

```bash

# Verify Rosetta 2 is installed

softwareupdate --install-rosetta --agree-to-license

# Verify CrossOver version

/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin/wine --version

# Verify architecture (must be x86_64 under Rosetta)

file /Applications/CrossOver.app/Contents/SharedSupport/CrossOver/bin/wineserver

# Verify Homebrew is available

brew --version
```text

---

## 3. Project Structure & Architecture

### Repository Layout

```yaml
Endfield_FineWine/
├── .github/
│   ├── scripts/
│   │   ├── generate-wiki.py
│   │   ├── generate-release-notes.py
│   │   └── ...
│   └── workflows/
│       ├── build.yml
│       ├── nightly.yml
│       └── update-wiki.yml
├── patches/
│   ├── README.md
│   ├── stage1-macos/          # Novel Rosetta 2 signal-handling fixes
│   ├── stage2-dwproton/       # dw-proton anti-cheat port
│   │   └── ace-core/          # ACE-CORE driver regression fixes
│   └── moltenvk/              # Patched MoltenVK
├── scripts/
│   ├── build-wine.sh
│   ├── swap-into-crossover.sh
│   ├── create-bottle.sh
│   ├── launch-endfield.sh
│   ├── make-launcher-app.sh
│   ├── 01-capture-failure.sh
│   ├── build-moltenvk.sh
│   ├── package.sh
│   └── apply-modules.sh
├── tests/
│   └── test-msync-waitall.py
├── patcher-app/               # FineWine Patcher.app (SwiftPM GUI)
├── docs/
│   ├── installation.md
│   ├── troubleshooting.md
│   ├── performance.md
│   ├── technical.md
│   ├── graphics-performance.md
│   └── project-information/
└── LICENSE
```text

### Patch Architecture

The project uses a **surgical module swap** approach. Instead of replacing the entire CrossOver application, only three core Wine modules are swapped into a copy of CrossOver:

| Module | Location in CrossOver | Responsibility |
|--------|----------------------|----------------|
| `ntdll.so` | `lib/wine/x86_64-unix/ntdll.so` | Rosetta 2 signal fixes, NOP skip, QPC timing |
| `kernel32.dll` | `lib/wine/x86_64-windows/kernel32.dll` | `KiUser*Dispatcher` int3 spoof |
| `ntoskrnl.exe` | `lib/wine/x86_64-windows/ntoskrnl.exe` | 17 backported NT kernel functions |

#### Patch Sets

| Patch Set | Origin | Purpose |
|-----------|--------|---------|
| `stage1-macos/` | Novel (this project) | Two Rosetta 2 signal-handling fixes in `signal_x86_64.c` |
| `stage2-dwproton/` | dw-proton / Dawn Winery | 17 `ntoskrnl.exe` backports, int3 spoof, QPC timing |
| `ace-core/` | mary-ext / dw-proton | ACE-CORE driver regression fixes (return-address bits, `lsass.exe` stub) |

### The Two Novel Rosetta 2 Fixes

Both fixes reside in `dlls/ntdll/unix/signal_x86_64.c`:

1. **Multi-byte NOP (`0F 1F`) skip:** VMProtect emits `0F 1F` NOPs pervasively. Rosetta 2 erroneously raises illegal-instruction faults on them. The fix decodes the instruction length and advances `RIP` past the NOP.

2. **Privileged instruction (`mov cr3`) classification:** ACE's driver reads `CR3` as an anti-VM probe. Rosetta generates an invalid-opcode fault instead of `#GP`. The fix inspects the opcode with `is_privileged_instr()` and delivers `EXCEPTION_PRIV_INSTRUCTION` matching Linux behavior.

### Graphics Translation Pipeline

```python
Endfield Engine (DirectX 11, via -force-d3d11)
       │
       ▼
DXMT (CrossOver's D3D11-to-Metal translation layer)
       │ (Thin, direct DX11 → Metal API mapping)
       ▼
Metal Framework / Apple Silicon GPU
```json

**Recommended configuration (October 2026):**

| Setting | Value |
|---------|-------|
| CrossOver Backend | `dxmt` (`CX_GRAPHICS_BACKEND=dxmt`) |
| Launch Flag | `-force-d3d11` |
| GPTK Patch | v4 (highly recommended) |
| Upscaling | TAAU or AMD FSR3 on stock DXMT; DLSS via MetalFX with NGX fix |

---

## 4. Build Process

### Build Script: `scripts/build-wine.sh`

The build is intentionally **minimal** (64-bit-only, no bundled fonts/TLS/graphics libs). Only 3 core modules are swapped into CrossOver, which provides everything else.

#### One-Shot Build

```bash
./scripts/build-wine.sh all

# deps -> fetch -> apply -> configure -> build (~20-60 min)

```bash

#### Step-by-Step Build

```bash

# 1. Install Homebrew dependencies

./scripts/build-wine.sh deps

# bison (≥3.0), mingw-w64, meson, pkg-config, ...

# 2. Download CrossOver 26.3 Wine source (~142 MB)

./scripts/build-wine.sh fetch

# 3. Apply all 24 patches

./scripts/build-wine.sh apply

# 4. Configure (64-bit-only, under arch -x86_64)

./scripts/build-wine.sh configure

# 5. Build

./scripts/build-wine.sh build

# make -j

```python

### Important Build Notes

- **No `cx-llvm` / `win32on64` needed.** Endfield is 64-bit only, so this builds a 64-bit-only Wine with the standard toolchain.
- **Build runs under `arch -x86_64`** (Rosetta host). The dw-proton int3 hack is `#ifdef __x86_64__`-guarded and compiles in this configuration.
- **bison version:** Homebrew's `bison` must be ≥ 3.0 and ahead of macOS system bison (2.3) on PATH.
- **Build artifacts** land in `build/wine-build64/`.

### LC_RPATH Fix

After building, `ntdll.so` needs CrossOver's `lib64` rpath so `cxcompatdb.so` can load `libgnutls.30.dylib`:

```bash
install_name_tool -add_rpath "@loader_path/../../../lib64" \
  "$CXR/lib/wine/x86_64-unix/ntdll.so"
codesign --force --sign - "$CXR/lib/wine/x86_64-unix/ntdll.so"
```bash

Without this, `cxcompatdb.so` silently fails to load, falling back to WineD3D and producing error `80004005` (DirectX device creation failure).

---

## 5. Deployment & Installation

### Scripted Deployment (Recommended)

```bash
./scripts/swap-into-crossover.sh
```bash

This:
1. Copies `/Applications/CrossOver.app` into a staging folder
2. Swaps in the patched modules (plus GPTK4's D3DMetal if `GPTK_DIR` is set)
3. Re-seals the bundle with an ad-hoc signature
4. Verifies the bundle
5. Moves it to `/Applications/CrossOver_Endfield_Patch.app`
6. Creates a double-clickable `Arknights Endfield.app` launcher

### Manual Deployment

See `docs/installation.md` for the full manual procedure involving `

Clone this wiki locally