Native control, inspection, UI automation and evidence capture for a running Witcher 3 process.
3.9 kB · 69 lines
Markdown
at main

Native adapters #

These components run inside the Windows game process under Proton. They are build-specific; they do not install or qualify another Witcher 3 version.

WitcherScript bridgeWitcherNativeBridgeregistrationPathInput.asiOriginal game inputhandlersXInput readHuman: original XInputfunctionAgent: bounded virtual padstateLab-onlyPathBackground.asiWindow focus handling
File Role
PathInput.cpp Native input-action values, XInput pass-through/virtual state, wall-clock lease, loopback-only debugger bind, JSON quoting.
PathBackground.cpp Optional lab-window focus handling; not an input or gameplay policy engine.
build.py Builds against a pinned WitcherNativeBridge source and local llvm-mingw toolchain.

Human control calls the original XInput function without the devkit pad lock, sleep or added polls. This does not quantify physical latency. Agent input requires an explicit control change; expiry/release do not guarantee that a game action has completed. See control and operation semantics and installation boundaries.

install-native updates an already-owned installation only with the game closed. Do not copy native binaries or receipts between installations; inspect the current adapter hashes with w3dev verify. The native API and relevant upstream licenses are recorded in ../licenses/.

Pinned upstream build adaptation #

python3 native/build.py still produces WitcherNativeBridge.asi, PathInput.asi and the bridge import library under ignored native/build/; it does not install them. It requires SDK commit 415e1c1e79a9d5ab78629c70cd3a76131ad98941, a clean tracked index and exact tracked file bytes/modes, not just a matching HEAD. Untracked files are excluded. Verified bytes are copied to a private temporary source directory, patched there and removed after building; the downloaded SDK is never patched in place.

The LogChannel patch retains the original string-helper pattern and offsets. Only zero original matches permits a fallback for the helper without the nine-byte stack fifth-argument zero store. Either pattern must match exactly once; ambiguous original matches never fall back. The search region, opcode-table discovery, registration resolver and four-register BufferAllocFn ABI remain unchanged.

Provenance: Steam build 26238013, executable SHA-256 05948d7238e1c9620a1cb9b3125520f1c143ce04a8e5718a3735120c37d7bae0, LogChannel RVA 0x2743580, helper anchor +0x40. The updated relative-resolution offsets are allocator 24, empty-string pointer 37, copy 49; the empty-length displacement remains offset 2, instruction length 6 at the anchor. Disassembly of this call site supplies RCX=0, EDX=length, R8D=1 and R9D=14, consistent with the existing four-argument call. This is a checked pattern adaptation, not full ABI proof or live qualification of the current game build; compatibility, native lifecycle and string behavior still need their own checks before deployment.

The build probes the configured compiler/linker for --no-insert-timestamp and uses it for both binaries when supported; otherwise it warns that output may vary. native/build/manifest.json records the actual linker flags, upstream revision, patch SHA-256, before/after source SHA-256 and output SHA-256 values. Reproducibility is scoped to the same source and toolchain, not implied across compiler versions. Offline coverage is in tests/test_native_build.py; its optional host-C++ check executes the patched resolver branch logic with scanner doubles, not the game ABI.