Build, Test, and Publish¶
This document is the practical build/test/publish guide for the repository. For the test design rationale, see TestStrategy.md. For trimming and NativeAOT details, see Trimming.md. For packaging contents, see packaging/README.md.
1. Prerequisites¶
| Requirement | Version / notes |
|---|---|
| .NET SDK | 10.0.301 (pinned by global.json with rollForward: disable). |
| OS | Windows 10+ (validated), current Linux desktop, macOS 12+ (publish outputs only for the latter two in the current release scope). |
| GPU | OpenGL 3.3 desktop or OpenGL ES 3.0/3.1 for the GPU presenter. The CPU fallback runs without one. |
| Audio | No system OpenAL install is required. OpenAL Soft 1.23.1 is bundled by the build. |
| Optional | A legally obtained 3DO BIOS (1 MB) and disc images for real-content validation. Tests do not need them. |
| Optional | jq for the CI allocation-gate command. |
| Optional | PowerShell 7 (pwsh) for packaging and soak scripts. |
The repository does not include BIOS ROMs, game images, or extracted assets.
Check the SDK:
2. Repository layout¶
5DO.sln
Directory.Build.props # net10.0, nullable, warnings-as-errors, version, analyzers
Directory.Build.targets # OpenAL Soft native copy for Windows builds
Directory.Packages.props # central package versions
global.json # SDK pin/roll-forward
src/
FiveDo.Core/ # contracts, value types, constants, state primitives, logging
FiveDo.Cpu/ # ARM60 interpreter and disassembler
FiveDo.Memory/ # RAM/ROM/NVRAM, word-swapped bus
FiveDo.Madam/ # CEL/pixel/matrix engine
FiveDo.Clio/ # timers, FIFOs, DMA, interrupts, XBUS/DSP windows
FiveDo.Dsp/ # audio DSP
FiveDo.Sport/ # VRAM fill/copy engine
FiveDo.Video/ # VDLP, frame assembly, mailbox, CPU presenter
FiveDo.Video.OpenGL/ # OpenGL/GLES presenter, filters, shaders
FiveDo.Video.Vulkan/ # optional Vulkan presenter and probes
FiveDo.Video.Direct3D/ # optional Direct3D 11 presenter (Windows)
FiveDo.Xbus/ # XBUS controller and devices
FiveDo.Cdrom/ # MEI CD-ROM device
FiveDo.Storage/ # ISO/BIN/CUE/CHD, BIOS/NVRAM, game database
FiveDo.Audio/ # WAV/OpenAL/audio analysis/tap
FiveDo.Input/ # controller state, PBUS, profiles, scripts
FiveDo.Tas/ # TAS movie container, record/replay, branching
FiveDo.Diagnostics/ # logging, tracing, PNG/frame dumps, benchmark gates
FiveDo.Machine/ # composition root, frame loop, Quartz
FiveDo.Host/ # core runner, pacing, settings, save slots, library, fixes
FiveDo.Cli/ # headless commands
FiveDo.Frontend.Avalonia/ # desktop shell and GPU probe
tests/FiveDo.Tests/ # xUnit tests, one folder per subsystem
benchmarks/FiveDo.Benchmarks # stopwatch frame benchmark and CI gate
packaging/ # bundle/archive scripts and Linux desktop entry
tools/ # release soak and HQx generation
docs/ # this documentation set
Project dependency rule: arrows point downward only. FiveDo.Core has no project references; chip projects reference only Core; FiveDo.Machine references all chips; FiveDo.Host references Machine plus host services; frontends reference Host. See Architecture.md section 3.
3. Restore, build, test¶
From the repository root:
The current suite is 1,597 tests (verified 2026-11-03) and completes in a few seconds on the development machine. The build treats warnings as errors and runs the .NET analyzers plus Meziantou and Roslynator analyzers.
Debug builds compile the emulator core projects (FiveDo.Core, Cpu, Memory, Machine, Madam, Clio, Dsp, Sport, Video, Xbus, Cdrom, and Host) with JIT optimizations, while the frontend/UI projects stay unoptimized. This keeps IDE gameplay near Release speed; pass -p:FiveDoOptimizeDebug=false to restore fully unoptimized Debug core assemblies. If Visual Studio's debugger is set to suppress JIT optimization on module load, gameplay will still be slow while attached; use Start Without Debugging or disable that debugger option.
Useful variants:
# Debug build and test
dotnet build 5DO.sln
dotnet test tests/FiveDo.Tests/FiveDo.Tests.csproj
# One test class
dotnet test tests/FiveDo.Tests/FiveDo.Tests.csproj --filter "FullyQualifiedName~ArmDataProcessingTests"
# One test by name fragment
dotnet test tests/FiveDo.Tests/FiveDo.Tests.csproj --filter "DisplayName~state_roundtrip"
# List tests without running
dotnet test tests/FiveDo.Tests/FiveDo.Tests.csproj --list-tests
# Formatting check (CI runs this on Linux)
dotnet format 5DO.sln --verify-no-changes --no-restore
# Apply formatting locally
dotnet format 5DO.sln
# Parser and CD command-stream fuzzing (deterministic)
dotnet run --project tools/FiveDo.Fuzz -c Release -- --seconds 30 --target all --json
# Reproduce one reported fuzz case
dotnet run --project tools/FiveDo.Fuzz -c Release -- --target state --seed 397 --iterations 43
Test project layout¶
The suite is one xUnit project with subsystem folders:
| Folder | Covers |
|---|---|
Core/ | state framing/CRC, logging, constants, version |
Cpu/ | ARM data processing, memory, block transfer, multiply/swap, conditions, control flow, modes/banked registers, cycles, disassembler, synthetic boot |
Memory/ | byte order, unaligned access, mirrors, NVRAM |
Madam/ | CEL bit reader, CCB parser, geometry, rasterizers, golden scenes, pixel decode/process, projector |
Clio/ | registers, timers, FIFOs, DMA, interrupts |
Dsp/ | instruction decode, ALU, multiplier, memory, semaphore, sample cadence |
Sport/ | VRAM fill/copy, high-resolution mirroring |
Video/ | VDLP parsing, frame assembly, viewport, uploader, mailbox, HQx, shaders, swap interval, capabilities, allocations |
Xbus/ | device selection, FIFOs, polling |
Cdrom/ | command state machine, status/data, TOC, READ_ID pulse |
Storage/ | ISO/BIN/CUE/CHD, BIOS, NVRAM, volume header, game database, prefetch |
Audio/ | ring buffer, WAV writer/analyzer, statistics, limiter, tap, OpenAL (opt-in) |
Input/ | PBUS encoding/decoding, profiles, binding editor, scripts, gamepad mapper |
Tas/ | movie container, recorder/playback, branch/trim, verification, zero-allocation playback |
Machine/ | composition, frame loop, Quartz, save/load, BIOS UI validation |
Host/ | core runner, pacing, settings, save slots, state inspector, NVRAM, library, compatibility, autopilot |
Diagnostics/ | frame timing, benchmark gate/comparison, diagnostic tools |
Frontend/ | startup arguments, GL backend parsing, probe options, pixel sizing, opt-in GPU probe |
Cli/ | JSON contracts, process-level smoke tests |
TestUtilities/ | ARM test assembler/rig, fake chips/MMIO, PNG writer |
Opt-in test environment variables¶
| Variable | Effect |
|---|---|
FIVEDO_BIOS=<path> | Enables real-BIOS machine/boot validation tests. |
FIVEDO_FRAME_DUMP=<dir> | Writes boot-frame PNGs when a real BIOS is used. |
FIVEDO_GPU_TESTS=1 | Runs the real WGL + ANGLE probe integration test. Requires a desktop GL/ANGLE context and a built frontend. |
FIVEDO_VULKAN_TESTS=1 | Runs the in-process Vulkan parity/source-size and xBR/FSR orientation tests plus the Vulkan probe integration test. Requires a Vulkan device and a built frontend. |
FIVEDO_D3D_TESTS=1 | Runs the opt-in Direct3D 11 parity/source-size, letterbox, and xBR/FSR/HQx orientation tests. Requires Windows and a Direct3D 11 device. |
FIVEDO_UPDATE_CHECK=0 | Disables the CLI/frontend startup GitHub release check (also set automatically in CI/tests). |
FIVEDO_AUDIO_TESTS=1 | Opens a real OpenAL device and plays a short tone. On headless machines set ALSOFT_DRIVERS=null to use OpenAL's null backend. |
FIVEDO_AUDIO_TAP=<prefix> | Not a test switch; enables the live PCM/timing tap for manual audio diagnosis. |
FIVEDO_GAMES=<dir> | Used by tools/release-soak.ps1, not by dotnet test. |
Examples:
$env:FIVEDO_BIOS = "C:\3DO\panafz1.bin"
$env:FIVEDO_FRAME_DUMP = "artifacts\bios-frames"
dotnet test tests/FiveDo.Tests/FiveDo.Tests.csproj -c Release
$env:FIVEDO_GPU_TESTS = "1"
dotnet test tests/FiveDo.Tests/FiveDo.Tests.csproj -c Release --filter "FullyQualifiedName~GpuProbeIntegrationTests"
$env:FIVEDO_AUDIO_TESTS = "1"
$env:ALSOFT_DRIVERS = "null"
dotnet test tests/FiveDo.Tests/FiveDo.Tests.csproj -c Release --filter "FullyQualifiedName~OpenAlAudioOutputTests"
Real-content tests skip cleanly when the required environment variables are absent.
4. Benchmarks¶
The benchmark is a dependency-free stopwatch harness, not BenchmarkDotNet. It runs a synthetic ARM program by default so CI can gate the core without copyrighted content.
dotnet run --project benchmarks/FiveDo.Benchmarks -c Release -- --frames 600
dotnet run --project benchmarks/FiveDo.Benchmarks -c Release -- --frames 600 --json
Real-content variants:
dotnet run --project benchmarks/FiveDo.Benchmarks -c Release -- `
--bios bios/panafz1.bin --disc "game.chd" --frames 600 --label "disc"
dotnet run --project benchmarks/FiveDo.Benchmarks -c Release -- `
--state-in artifacts/compat-current/roadrash-race.state --frames 600 --label "roadrash-race"
Options:
| Option | Default | Meaning |
|---|---|---|
--frames N | 600 | Measured frames after warm-up. |
--warmup N | 60 | Unmeasured warm-up frames (JIT, DSP tables, packers). With --state-in, advances the loaded state into the scene under test. |
--bios <path> | none | Load a real BIOS instead of the synthetic program. |
--disc <path> | none | Insert a disc with --bios. |
--state-in <path> | none | Load a save state instead of booting. |
--prefetch | off | Enable the bounded disc prefetch cache. |
--high-res | off | Enable the opt-in 640x480 mode. |
--label <text> | synthetic / disc / state | Report label. |
--json | off | Emit the JSON result. |
--gate | off | Enforce the CI budgets; exit code 3 on failure. |
--baseline <json> | none | Compare against a previously recorded result. |
--baseline-threshold <fraction> | 0.10 | Allowed regression (10%). Exit code 4 on failure. |
JSON shape (abridged):
{
"ok": true,
"label": "synthetic",
"frames": 600,
"warmupFrames": 60,
"stateWarnings": [],
"core": { "totalMs": 0.0, "msPerFrame": 0.0, "p50Ms": 0.0, "p95Ms": 0.0, "p99Ms": 0.0, "maxMs": 0.0, "fps": 0.0, "millionInstructionsPerSecond": 0.0, "instructionsPerFrame": 0 },
"pack": { "totalMs": 0.0, "microsecondsPerFrame": 0.0 },
"mailbox": { "totalMs": 0.0, "microsecondsPerFrame": 0.0 },
"read": { "totalMs": 0.0, "microsecondsPerFrame": 0.0 },
"total": { "msPerFrame": 0.0, "p50Ms": 0.0, "p95Ms": 0.0, "p99Ms": 0.0, "maxMs": 0.0, "fps": 0.0, "budget60Ms": 16.667, "headroom": 0.0 },
"allocations": { "totalBytes": 0, "bytesPerFrame": 0, "coreBytesPerFrame": 0, "packBytesPerFrame": 0, "mailboxBytesPerFrame": 0, "readBytesPerFrame": 0 },
"machine": { "cyclesPerFrame": 208333, "pc": 0, "frameHash": 0 }
}
The gate (BenchmarkGate) requires:
allocations.bytesPerFrame == 0core.p99Ms <= 8.0total.msPerFrame <= 8.0total.p99Ms <= 16.667
CI runs:
dotnet run --project benchmarks/FiveDo.Benchmarks -c Release --no-build -- \
--frames 120 --label ci --json --gate > artifacts/benchmark.json
jq -e '.allocations.bytesPerFrame == 0' artifacts/benchmark.json
The baseline comparison is same-machine only; do not compare numbers across machines. See Performance.md for the measured baselines and methodology.
4a. Differential harness¶
The reference harness is a separate tool; it is not part of the shipped emulator and is not run by the default test job when the BIOS/disc corpus is absent.
dotnet build tools/FiveDo.DiffHarness -c Release
tools/FiveDo.DiffHarness/bin/Release/net10.0/FiveDo.DiffHarness.exe `
validate benchmarks/diff/smoke.json --strict
tools/FiveDo.DiffHarness/bin/Release/net10.0/FiveDo.DiffHarness.exe `
run benchmarks/diff/smoke.json --out artifacts/diff/smoke
It needs bios/panafz1.bin, the local disc collection, and the bundled References/CPP_SimpleGui/.../OperaCore.dll. The Lemmings smoke is the quick health check; the five-title showcase takes about ten minutes because the reference core runs in real time. See DifferentialHarness.md for the manifest and report contracts.
5. GPU presentation probe¶
The probe opens the real Avalonia OpenGL surface, presents synthetic 320x240 VDL frames at a requested output size, and writes per-frame present/GPU timings, capabilities, allocations, and optional CPU/GPU parity as JSON. It does not load a BIOS or disc.
dotnet run -c Release --project src/FiveDo.Frontend.Avalonia -- `
--gl-probe artifacts/gl-probe/4k-sharp.json `
--gl-probe-size 3840x2160 --gl-probe-frames 120 --gl-probe-warmup 30 `
--gl-probe-filter sharp-bilinear --gl-probe-offscreen
Options:
| Option | Default | Meaning |
|---|---|---|
--gl-probe <path> | required | Output JSON path. |
--gl-probe-size WxH | 3840x2160 | Physical output size, 16x16..16384x16384. |
--gl-probe-frames N | 120 | Measured frames, 1..100000. |
--gl-probe-warmup N | 30 | Unmeasured warm-up frames, 0..10000. |
--gl-probe-filter <name> | sharp-bilinear | accurate, nearest, sharp-bilinear, crt, xbr, hqx, hqx3x, hqx4x, fsr (aliases accepted). |
--gl-probe-vsync | off | Request vsync. |
--gl-probe-offscreen | off | Render to an offscreen FBO at the requested size. |
--gl-probe-capture <path> | none | Write a PNG of the presented frame. |
--gl-probe-timeout N | 30 | Overall timeout in seconds, 1..600. |
--gl-backend auto|wgl|angle|software|vulkan|d3d11 | auto | Renderer backend. --gl-probe-backend is an alias. Direct3D 11 is Windows-only. |
A 1:1 accurate capture at 320x240 triggers an automatic CPU/GPU parity comparison against FrameAssembler; the report includes Parity.Compared, Matches, DifferentPixels, CpuHash, GpuHash, and VerticalFlip.
Vulkan probe¶
The optional Vulkan backend has a headless probe. It does not open an Avalonia window and requires a Vulkan 1.0 device and loader.
dotnet run -c Release --project src/FiveDo.Frontend.Avalonia -- `
--vk-probe artifacts/vk-probe/4k-sharp.json `
--vk-probe-size 3840x2160 --vk-probe-frames 30 --vk-probe-warmup 10 `
--vk-probe-filter sharp-bilinear
| Option | Default | Meaning |
|---|---|---|
--vk-probe <path> | required | Output JSON path. |
--vk-probe-size WxH | 1920x1080 | Output size, 16x16..16384x16384. |
--vk-probe-frames N | 60 | Measured frames, 1..100000. |
--vk-probe-warmup N | 10 | Unmeasured warm-up frames, 0..10000. |
--vk-probe-filter <name> | accurate | accurate, nearest, sharp-bilinear, crt, xbr, fsr, hqx, hqx3x, hqx4x; HQx uses the shared CPU expansion. |
--vk-probe-capture <path> | none | Write a PNG of the rendered frame. |
--vk-probe-timeout N | 30 | Overall timeout in seconds, 1..600. |
Set FIVEDO_VULKAN_TESTS=1 to run the opt-in in-process parity/source-size and xBR/FSR orientation tests plus the probe integration test. See Vulkan.md for the measured results and limitations.
Direct3D 11 probe¶
The optional Direct3D 11 backend has a headless probe and a native Win32 swapchain probe. It requires Windows and Direct3D 11 feature level 11_0.
dotnet run -c Release --project src/FiveDo.Frontend.Avalonia -- `
--d3d-probe artifacts/d3d-probe/4k-sharp.json `
--d3d-probe-size 3840x2160 --d3d-probe-frames 30 --d3d-probe-warmup 10 `
--d3d-probe-filter sharp-bilinear
| Option | Default | Meaning |
|---|---|---|
--d3d-probe <path> | required | Output JSON path. |
--d3d-probe-size WxH | 1920x1080 | Output size, 16x16..16384x16384. |
--d3d-probe-frames N | 60 | Measured frames, 1..100000. |
--d3d-probe-warmup N | 10 | Unmeasured warm-up frames, 0..10000. |
--d3d-probe-filter <name> | accurate | Same filter names as the OpenGL/Vulkan probes. |
--d3d-probe-capture <path> | none | Write a PNG of the rendered frame. |
--d3d-probe-timeout N | 30 | Overall timeout in seconds, 1..600. |
--d3d-window-probe <path> | - | Native Win32 flip-model swapchain probe; accepts the matching --d3d-window-probe-* options. |
Set FIVEDO_D3D_TESTS=1 to run the opt-in parity, size-change, letterbox, and xBR/FSR/HQx orientation tests. The HLSL compile test runs on Windows without an opt-in flag. See Direct3D.md for measured results and limitations.
See Video.md and Performance.md for interpretation.
6. Publish¶
Framework-dependent single file (release shape)¶
dotnet publish src/FiveDo.Cli/FiveDo.Cli.csproj -c Release -r win-x64 `
--self-contained false -p:PublishSingleFile=true -p:PublishTrimmed=false -m:1 `
-o artifacts/cli/win-x64
dotnet publish src/FiveDo.Frontend.Avalonia/FiveDo.Frontend.Avalonia.csproj -c Release -r win-x64 `
--self-contained false -p:PublishSingleFile=true -p:PublishTrimmed=false -m:1 `
-o artifacts/frontend/win-x64
Release bundles are produced for win-x64, win-arm64, linux-x64, linux-arm64, osx-x64, and osx-arm64. They contain no .NET runtime; users must install the .NET 10 runtime on their machine.
Both executables are single-file framework-dependent apphosts. The frontend also ships native Skia/HarfBuzz/ANGLE assets. OpenAL Soft is copied as OpenAL32.dll on Windows by Directory.Build.targets; Linux/macOS use the package's native names. PDB and XML documentation files are removed by packaging/package-bundle.ps1.
NativeAOT (opt-in, win-x64)¶
dotnet publish src/FiveDo.Cli/FiveDo.Cli.csproj -c Release -r win-x64 `
--self-contained true -p:FiveDoNativeAot=true -p:PublishSingleFile=true -m:1 `
-o artifacts/cli-aot
dotnet publish src/FiveDo.Frontend.Avalonia/FiveDo.Frontend.Avalonia.csproj -c Release -r win-x64 `
--self-contained true -p:FiveDoNativeAot=true -m:1 `
-o artifacts/frontend-aot
AOT is not part of the six-RID default matrix. The CLI AOT path opens live OpenAL; the frontend AOT audio path is not validated yet. See Trimming.md.
Smoke tests¶
artifacts/cli/win-x64/FiveDo.Cli.exe --version
artifacts/cli/win-x64/FiveDo.Cli.exe selftest --json
artifacts/cli/win-x64/FiveDo.Cli.exe bench --frames 2 --json
artifacts/frontend/win-x64/FiveDo.Frontend.Avalonia.exe `
--smoke-test --smoke-output artifacts/frontend-smoke.txt
The frontend smoke test opens the real window, runs one UI pass (GL hidden for headless CI), writes FRONTEND SMOKE OK <version>, and exits 0.
Portable bundles¶
pwsh -File packaging/package-bundle.ps1 -Rid win-x64 `
-CliPublishDirectory artifacts/cli/win-x64 `
-FrontendPublishDirectory artifacts/frontend/win-x64 `
-OutputDirectory artifacts/bundles
The bundle contains both framework-dependent apphosts and their native libraries, README.md, LICENSE, THIRD-PARTY-NOTICES.md, whatsnew.md, docs/Licensing.md, docs/ReleaseLegalReview.md, the latest docs/ReleaseNotes-*.md, and a generated PACKAGE.txt with component, RID, version, commit, and build time. Linux bundles also include 5do.desktop. PDB and XML documentation files are removed, and no .NET runtime is copied into the bundle. The archive name includes the product version, for example 5do-1.2.1-win-x64.zip, 5do-1.2.1-win-arm64.zip, or 5do-1.2.1-linux-arm64.tar.gz; the version is read from Directory.Build.props unless -Version is supplied.
7. CI jobs¶
The workflow is .github/workflows/ci.yml.
| Job | Runner | What it does |
|---|---|---|
build-test | Windows, Ubuntu, macOS | Restore, Release build, all tests. Ubuntu also runs format check, benchmark smoke + gate, allocation gate, and uploads the baseline. Windows runs trimmed CLI and frontend publish smoke tests. |
aot-cli | Windows | NativeAOT win-x64 CLI publish, --version/selftest/bench, artifact upload. |
aot-frontend | Windows | NativeAOT win-x64 frontend publish, smoke test, artifact upload. |
bundle | Windows, Ubuntu | Builds the unified Windows/Linux/macOS x64 bundles with framework-dependent single-file apphosts; the .NET 10 runtime is required on the host and not bundled. The macOS x64 bundle is cross-published on Ubuntu and validated as Mach-O x86_64. Runs CLI/frontend smoke tests and uploads the bundle. |
ci-complete | Ubuntu | Aggregate gate that fails if any required CI job fails or is cancelled. |
Separate workflows add:
| Workflow | Trigger | What it does |
|---|---|---|
docs.yml | Push/PR touching docs or the wiki, manual | Strict MkDocs build, GitHub Pages deployment from master, and curated wiki publishing. |
release.yml | Tag push or manual | Builds the six x64/arm64 bundles, writes SHA256SUMS.txt, updates the GitHub release, and removes obsolete per-component assets. |
codeql.yml | Push/PR, weekly, manual | CodeQL analysis for C#, GitHub Actions, and Python. |
dependency-review.yml | Pull request | Blocks high-severity dependency changes and comments on the PR. |
scorecard.yml | Push, weekly, manual | OpenSSF Scorecard analysis, SARIF upload, and published results. |
CI does not download BIOS ROMs or game images. GPU tests and real-audio tests are opt-in and not part of the default matrix. The repository is public; secret scanning with push protection and private vulnerability reporting are enabled in GitHub settings.
7.1 Local Linux VM validation¶
The local Linux validation target is the Hyper-V VM LinuxMint (D:\Hyper-V\VMs\LinuxMint, generation 2, 8 GB assigned). It is a manual validation target, not a CI replacement. The guest is reachable over SSH; machine-specific credentials are in the gitignored AGENTS.local.md.
Suggested flow:
- Start the VM (
Start-VM -Name LinuxMint) and confirm the guest has the .NET 10 SDK, or publishlinux-x64on the host and copy the publish folder into the guest. - Copy the repository or the published CLI/frontend into the guest.
- Run
dotnet test tests/FiveDo.Tests/FiveDo.Tests.csproj -c Release. - Run
dotnet run -c Release --project src/FiveDo.Cli -- selftest --json. - Run the frontend smoke test (
--smoke-test) and, when the VM has a usable GL display, the OpenGL probe (--gl-probe). - Run a reduced compatibility sweep with
-NoFrameCapture; the PNG analysis usesSystem.Drawing.Common, which is Windows-oriented. Record the CLI JSON results. - Record the renderer/vendor/version and any fallback behavior in
Compatibility.mdandKnownIssues.md.
The Linux pass should use the same BIOS/disc set as the Windows pass. Do not commit BIOS or disc images.
8. Build properties and dependencies¶
Key properties in Directory.Build.props:
| Property | Value |
|---|---|
TargetFramework | net10.0 |
LangVersion | latest |
Nullable | enable |
ImplicitUsings | disable |
TreatWarningsAsErrors | true |
Deterministic | true |
Version | 1.2.1 |
InvariantGlobalization | true |
EnableNETAnalyzers | true |
AnalysisLevel | latest-recommended |
FiveDoOpenAlSoftVersion | 1.23.1 |
Central package versions live in Directory.Packages.props. The notable dependencies are Avalonia 12.1.4, CommunityToolkit.Mvvm, Silk.NET.OpenGL/OpenAL, CHDSharp 1.6.0, xUnit, and BenchmarkDotNet (present but the current benchmark harness is custom). The 3DO Opera file-system reader used by 5do fs is first-party (FiveDo.Storage.OperaFileSystem).
9. Build/test troubleshooting¶
| Symptom | Cause / fix |
|---|---|
dotnet not found or wrong SDK | Install .NET 10 SDK 10.0.301; global.json pins that version with rollForward: disable. |
NETSDK1045 | The installed SDK is older than .NET 10. |
| Restore fails behind a proxy | Configure NuGet proxy/credentials; CI uses the standard NuGet feed. |
OpenAL32.dll missing at runtime | Rebuild so Directory.Build.targets copies OpenAL Soft; or copy the package's soft_oal.dll as OpenAL32.dll beside the executable. |
| GPU tests fail on a headless runner | They are opt-in; do not set FIVEDO_GPU_TESTS without a desktop GL/ANGLE context. |
| Audio test fails with no device | Set ALSOFT_DRIVERS=null or skip FIVEDO_AUDIO_TESTS. |
| Frontend smoke test times out | It needs a desktop session; run it interactively or in a CI job with a window station. |
| Benchmark gate fails on a busy machine | Close background work; the gate is wall-clock and intended for a quiet CI runner. |
dotnet format reports changes | Run dotnet format 5DO.sln, then rebuild/test. |
| Long-path errors on Windows | Enable long paths or clone to a shorter path. |
TypeLoadException/MissingMethodException after switching branches or pulling | Stale bin/obj output from an earlier build. Delete bin/obj and rebuild. |
| CHD test fails | CHDSharp reads valid MAME CD CHDs and flat 2048-byte cooked-ISO CHDs; DVD/HDD/raw CHDs with other unit sizes are rejected by design. |
If a failure is emulation-related rather than build-related, see Troubleshooting.md and Diagnostics.md.