The 0.28 GameReader C++ API is a compile-time interface. C++ standard library
types, exceptions, virtual tables, and compiler runtime choices cross that
interface, so it is not a binary compatibility promise. The experimental
AmoosedWebGameReaderC shared library proves a separate C boundary with a
plain-C caller. Its amw_preview_* symbols may change before 1.0.
The detailed 1.0 C ABI design proposal defines the
versioning, ownership, cancellation, and error decisions still to be implemented.
The proposed 1.x evolution checker now has tests for additive minor releases
and breaking edits. It reads candidate declarations from a future public C
header; it does not turn this preview into a
stable ABI. The first 1.0 release still needs its actual header, binary, and
immutable baseline before the checker becomes a package gate.
The native compiler has a separate owner-side
proposed C header for static-site build and offline
verification. It has C/C++ compile checks but no implementation, binary, or
stability promise. Its amwc1_ namespace and freeze gate are independent of
the general Reader's amw1_ work.
The separate amwc_preview_* revision-8 library exercises local site
verification and hosted, member, and external-index builds through a plain-C
caller. Its header and binary are owner-side. Bundle and WAV work now observes
the cancel flag within their long loops, with a threaded WAV test on both OSes.
A C build fixture now cancels hosted, member, and external editions after
observing site staging and checks cleanup on Windows and Linux. Late external
credential publication is now covered by a deterministic internal C++ fixture:
an observer cancels immediately after the private directory is published,
and neither destination nor staging directory survives on Windows or Linux.
A revision-8 C build-progress callback lets a caller cancel at that same
checkpoint. Its direct C API fixture verifies site, credentials, and stages are
removed on Windows and Linux. The remaining build status taxonomy,
clean-package consumers, and broader command parity
remain before a compiler 1.0 release or a complete authoring SDK.
The same threaded fixture creates a competing site destination after staging
starts. Hosted, member, and external builds return OUTPUT_EXISTS, retain the
other process's marker, remove their stage, and publish no external credentials
on Windows and Linux.
An external build also faces a competing private credential destination after
site staging starts. It returns OUTPUT_EXISTS, preserves that marker, removes
its stages, and publishes no site on both hosts.
Revision 5 reports existing output, malformed configuration, missing input,
verified-site failure, and output I/O through structured categories. Plain-C
fixtures exercise existing output, malformed configuration, missing input,
and a regular file blocking the output parent on Windows and Linux. Site and
private credential destination collisions are also covered. Staged-site
verification failure is now covered by a C fixture that damages a carrier
after staging, gets VERIFICATION_FAILED, and sees no site or stage on Windows
and Linux. The wider failure matrix remains before the categories can freeze.
Revision 6 adds a query for the compiled compiler capabilities and zeroes its
caller-owned outputs on invalid arguments. Its bits are preview-only; the
amwc1_ assignments remain a proposal until the 1.0 freeze gate.
Revision 6 introduced a checked client contract snapshot for
the Windows calling convention, opaque handle, numeric statuses, capability
bits, and function declarations. Developer-site and native parity builds reject
a changed contract at the same revision. Binary export and plain-C behavior
gates remain separate; this is not an immutable 1.0 baseline.
Revision 7 adds a build-progress callback, two phase constants, and a capability
bit. Its client snapshot captures the callback declaration as well as the
existing signatures and numeric values.
Revision 8 adds a SITE_STAGED notification before verification and a new
checked snapshot. This phase says bytes are ready to inspect, not yet trusted.
The revision-8 compiler C fixture now confirms that build and verify calls
consume a non-null operation even when a required output or error buffer is
missing. The preview implementation follows that documented single-use rule on
Windows and Linux; the 1.0 compiler contract still needs its own package gate.
Current prototype
include/AmoosedWeb/PreviewC.h exports catalogue parsing and enumeration,
plus Windows and Linux hosted/external index opening, full resource metadata enumeration,
member edition ID query, game session refresh and item fetch, and verified resource download for byte-addressable carriers, Windows PNG
low-bit carriers, AWF1/AWF2 sparse-frame carriers, and WAV tone carriers.
Callers pass bytes with explicit lengths, receive opaque catalogue, site, or game
handles, query fixed-width integer values, and copy strings into caller-owned
buffers. No C++ object or allocation crosses the boundary. The DLL catches
parser and download exceptions and reports a status and optional bounded error
text. A site handle keeps the verified index and HTTP origin together; its
cancel entry point may be called from another thread. The caller must wait
for in-flight operations to finish before releasing a handle. Revision 7
adds site_prepare plus hosted/external site_load calls: prepare performs no
network I/O, so the caller can share the handle and cancel an active index
load. It returns a distinct CANCELLED status for cancelled index loading,
download, game refresh, and game fetch. The older convenience open calls remain
but cannot cancel until they return a handle. Delayed local fixtures exercise
in-flight .NET index-opening and download cancellation; the download leaves
neither a final file nor a staging file.
tests/PreviewCTests.c compiles as C and exercises parse failure, ownership,
revision, item enumeration, size queries, and a too-small buffer. The
developer-site/examples/dotnet-abi/ program exercises the same DLL through
.NET 10 P/Invoke, including UTF-8 copying and error handling. The CMake
tests/PreviewSiteTests.c and the .NET example also open local hosted and
external sites, check resource metadata, and download a verified entry resource. The CMake package
exports AmoosedWeb::GameReaderC separately from the C++ target.
The opt-in Unreal Win64 subsystem calls revision 14 through the same prebuilt
DLL. An editor automation test refreshes the hosted catalogue and compares a
fetched item's output bytes with its source file. This proves that path on a
local fixture, not packaged-game or other-platform support.
A separate source-free Unreal preview ZIP passes a clean editor and shipping
consumer build and an editor module-load check. It is a local review package,
not a promise of ABI stability or a tested packaged game.
On Windows, npm run test:game-abi rebuilds and installs the package, runs
the plain-C test, and runs the .NET example against the installed DLL.
This is still a preview ABI, not a complete replacement for the published
Reader. Revision 9 includes a Windows game session handle that stages hosted or
external catalogue refreshes, retains the previous verified snapshot on
failure, and fetches a catalogue item through the same verified C++ core.
Preview revision 12 added a 64 MiB caller-owned memory read with a verified-index
size query, short-buffer result, private plaintext staging, and an operation
variant for cancellation. Windows and Linux plain-C fixtures compare exact
bytes with file output and check pre-dispatch and in-flight cancellation. The
in-flight fixtures assert that cancellation reports zero output length, leaves
the entire caller buffer untouched, and permits a successful read on the same
site handle afterward. Linux also checks that a damaged carrier leaves the
caller buffer unchanged. Windows and Linux plain-C fixtures now open a
checksummed index advertising a resource one byte above the 64 MiB memory
limit; both the size query and operation read return UNSUPPORTED, report zero
output length, and leave caller memory unchanged. The locally packaged .NET
preview also lists that oversized entry and raises its numeric and named
UNSUPPORTED result on Windows and Linux without allocating the resource.
Other language-package parity and the wider package matrix remain 1.0 gates.
The C boundary exposes the verified member edition ID but does not parse
member credential files or provide structured progress callbacks. Windows and
Linux decoders now cover the website carrier modes, but other platforms still
need adapters. The .NET Reader and Unreal plugin must retain their current
behavior until parity and target-platform tests prove a replacement. The
owner-side SDK packaging script now builds a local, DLL-only Windows x64
NuGet review package and verifies installation with an isolated consumer.
That package is not in the public release or a claim of 1.0 ABI stability.
Revision 8 adds a distinct ALREADY_EXISTS result when a download target
exists before staging or appears before publish. Other output errors retain
OUTPUT_ERROR; key, verification, and network failures still shared a broad
read status at that revision. A delayed carrier fixture creates a destination
while the C download is in flight and verifies the new status, preserved bytes,
and staging cleanup.
Revision 9 passes typed Reader failure categories through hosted and external
index loading, game refresh, resource download, and game item fetch. It reports
bad format, failed authentication, failed verification, transport failure, and
unsupported decoding separately from diagnostic text. Some provider failures
and malformed host responses still share broad categories; the numeric values
remain preview-only until the 1.0 failure matrix is tested across platforms.
Part hashing, complete-resource hash finalization, and hosted or external-index
digest checks now report an internal provider failure separately from a digest
mismatch. Focused Windows and Linux fixtures inject both outcomes; resource
failures leave output unpublished. Hosted-index responses with an unsafe origin,
invalid footer or payload range, changed ETag, or incomplete whole-body
fallback now report Verification instead of BadFormat. The focused fixture
covers those five response paths on Windows and Linux. Other provider and host
responses still need classification and wrapper parity before 1.0.
The built-in Windows and OpenSSL crypto hosts now expose a classified AES-GCM
open result to the C++ Reader. A rejected authentication tag remains
Authentication; a provider setup or processing failure becomes Internal
for external-index and member-part reads. Windows and Linux vector tests check
the rejected-tag result, and mock-host fixtures inject both categories through
the index and resource readers. Existing custom C++ crypto hosts retain the
older boolean method and its conservative authentication classification.
This does not change the preview C signatures or numeric status values.
.NET package replacement gate
The portable C++ core and full preview C ABI now build on Ubuntu 22.04. An
OpenSSL-backed non-Windows crypto host passes fixed SHA-256, AES-256-CTR, and
authenticated AES-256-GCM vectors there. A libcurl host verifies bounded
range, suffix, whole-body, redirect, and cancellation behavior on a local
server. Together they open a generated hosted index and recover exact
byte-addressable, PNG low-bit, sparse-frame, and WAV tone public resources
through a POSIX output adapter and libpng-backed media decoder, including
existing-target, output-race, symlinked-parent, and abort cleanup cases. Run
npm run test:game-linux for that gate. A plain-C Linux fixture opens a hosted
index, downloads exact bytes, rejects overwrite, and exercises pre-dispatch
cancellation. It also opens an externally keyed game starter, recovers a public
resource, rejects member data with an absent or incorrect key, and recovers exact member bytes
with the matching key. The ELF exports exactly the 43 symbols declared in the public
header. A source-free Linux x64 review ZIP now passes archive inventory and
digest checks, an extracted CMake consumer build, and exact-byte generated-site
download. Wider parity fixtures and target-platform checks remain before
publication. The output directory is caller-trusted; arbitrary
directory rename rights during publication are outside the current guarantee.
The Linux plain-C fixture also cancels a download after the server starts a
slow carrier response, verifies that no final or staging file remains, and
then downloads the resource through the same site handle. A finished operation
clears its transport cancellation state so the next serialized operation is
usable. This loopback fixture does not replace target-host cancellation tests.
The Linux plain-C gate also changes a byte in a hosted resource part while
keeping the verified index intact. The preview ABI must return the typed
VERIFICATION_FAILED status, clear the byte count, and leave neither a final
file nor a staging file. This covers one corrupt byte carrier; the wider
failure-category matrix and real HTTPS hosts remain 1.0 gates.
The portable Reader core now returns Cancelled when cancellation arrives
during a failing media decode, instead of retaining the decoder's
Verification category. A deterministic mock-host fixture checks the two
status paths on Windows and Linux; timely interruption of every real media
decoder remains unproven.
The published AmoosedReader exposes ListAsync, DownloadAsync, and
DownloadAllAsync, supports hosted and external indexes, accepts a separate
member key file, preserves an explicit executable-path constructor, and uses
CancellationToken. A smaller native-backed implementation must preserve
those public behaviors, including the constructor contract or a documented
major-version migration. It must copy key bytes from files into bounded native
calls without placing them in process arguments, zero temporary key buffers,
serialize operations on a site handle, map cancellation to site_cancel, and
dispose the handle only after active calls complete. DownloadAllAsync needs
the same path validation, directory containment, no-overwrite semantics, and
per-resource results as the CLI path. AmoosedNativePreviewReader now exercises
those operations side by side on Windows using a separately installed preview
DLL. Its local fixtures cover hosted and external indexes, all Windows media
codecs, member credential edition matching, cancellation before start, full
pull, and no overwrite. A delayed-carrier fixture confirms in-flight
cancellation through both the raw C ABI and high-level .NET wrapper leaves no
final or staging file. Hostile filesystem races and production target hosts
still need testing. A production NuGet package must include the matching native
library for each claimed runtime identifier; a platform-limited preview must not silently
replace the cross-platform explicit-CLI path.
The npm run test:game-http gate with AMW_TEST_READER_PARITY=1 requires a
matching locally built AmoosedWeb.Native NuGet package. It extracts that
package's CLI and compares the published CLI-backed .NET facade with the C++
interop facade on hosted, external, member, PNG low-bit, AWF1/AWF2, and WAV
fixtures. Resource metadata, downloaded bytes, and a full hosted pull match
on the local fixtures. Failure categories, cancellation behavior relative to
the CLI facade, hostile filesystem races, and production hosts still need
parity testing before changing the default constructor or dropping the large
CLI dependency.
tools/package-game-sdks.ps1 now requires a matching local owner release,
WSL Ubuntu (or AMW_WSL_DISTRO) for the Linux build, and .NET 10. It packages
both Windows x64 and Linux x64 C libraries in one local NuGet review artifact. It runs the CLI
parity gate plus clean packaged Reader consumers on both platforms before it
reports a review SDK ready. The Linux self-contained .NET consumer lists and
downloads exact hosted, externally indexed, and member resources. It rejects
missing and incorrect member keys without publishing output. The packaged
Linux .NET consumer also recovers exact PNG low-bit, sparse-frame, and WAV tone
resources. Its clean-package gate checks that a damaged hosted carrier
raises AmoosedNativePreviewException with numeric status 11 and named
VerificationFailed, without leaving output or a staging file. The Windows
clean NuGet consumer now checks the same typed status for both file and memory
reads after WAV data, AWF2 payload, and AWF2 marker damage. The packaged CLI
and source-level native facade remain the cross-language references for those
local fixtures.
The same flags remain available for a standalone
test run. The parity fixture also checks that existing output is preserved and
that malformed, wrong-edition, and wrong-key member credentials fail in the
same IOException family. The native preview gives malformed local files a
BadFormat status and edition/key mismatches an AuthenticationFailed status.
The parity gate also mutates WAV data and both the AWF2 payload and marker, then checks that the packaged CLI and native .NET Readers reject each carrier without publishing output. Exact marker comparison matters: decoding a binary marker with Node.js ascii masked a flipped high bit and was corrected. These local fixtures do not prove behavior on production hosts.
An opt-in AmoosedWeb.Reader.NativePreview .NET 10 review package now links
the matching AmoosedWeb.GameReader.Native binary package. It contains a separate
namespace, public Reader facade, and result records, but no amw.exe or
embedded JavaScript runtime. Clean Windows and Linux consumers verify the exact
ABI revision and packaged library. With AMW_TEST_PACKAGED_NATIVE_READER=1 and
AMW_GAME_SDK_NUGET_FEED set to the local review package directory,
npm run test:game-http also restores the package from an isolated cache and
checks exact hosted, member, external, PNG low-bit, sparse-frame, and WAV
fixture bytes through its public .NET facade. This does not replace the
published AmoosedWeb.Reader; parity and platform coverage remain the
migration gate. Its API signatures are documented publicly at
dev.amoosed.com/reader-reference.html#preview.
Version 0.28.13-preview of the .NET facade exposes the C status number through
AmoosedNativePreviewException.StatusCode and a named status enum, preserving
the numeric result for unknown future codes. The underlying C DLL remains
0.28.11-preview at ABI revision 14. The preview now reports per-binary
capabilities, which the native .NET and Unreal consumers check before using
Windows site or game features. Cancellation keeps its .NET exception type.
The standalone 0.28.13-preview .NET facade also exposes ReadBytesAsync for
resources up to 64 MiB. Its clean Windows and Linux consumers compare returned
bytes against hosted, externally indexed, member, and media fixtures; they
reject wrong keys and damaged carriers, and the delayed-carrier fixture
cancels an in-flight memory read without returning bytes. At that review
point the published CLI-backed AmoosedWeb.Reader API remained unchanged. The
later local Windows release build selects the C/C++ Reader for the same default
API and retains the explicit CLI constructor. Its clean NuGet consumer checks
an actual generated-site read; this is not yet a registry release or evidence
of complete target-host parity.
The same preview facade now exposes synchronous DecodeStandaloneWav through
the revision-14 C audio function. A clean Windows consumer and a self-contained
Linux consumer compare exact bytes and reject wrong keys and damaged WAVs.
It is separate from website resource reads and is not a stable 1.0 operation.
Revision 10 adds a single-use operation handle prepared before worker dispatch.
Its cancel entry point is safe to call from another thread; the worker owns the
handle until it returns. Operation variants cover hosted and external index
load, resource download, game refresh, and item fetch. A cancelled operation
does not poison the site or game transport for the next serialized operation.
The previous site/game cancellation calls remain for preview compatibility.
The 0.28.11-preview C boundary validates strict UTF-8 and rejects embedded NUL
in length-delimited origin, game ID/version, resource, item ID, and output-path
text before passing it to platform adapters. Credential and member-key bytes
remain binary. Malformed direct text returns INVALID_ARGUMENT; malformed
catalogue JSON returns BAD_FORMAT in revision 13. Revision 13 also reports
NOT_FOUND, INVALID_STATE, and STALE_REVISION for the corresponding
verified-index, handle-lifetime, and game rollback outcomes.
Rules proposed for a 1.0 ABI
- Freeze a versioned C header and exported symbol set only after the full
general Reader operations pass parity tests. Prefix 1.x Reader symbols
with
amw1_; keep the preview namespace separate. Game and engine calls remain optional preview layers until their own parity gate passes. Give a future native compiler ABI a separateamwc1_namespace and version. - Use explicit
uint32_t/uint64_twidths and opaque handles. Do not expose STL, C++ exceptions, compiler-specific classes, or ownership of memory allocated by the opposite side. Specify the calling convention on Windows. - Make every returned string and byte array a caller-owned copy. Provide a length query and an exact buffer-too-small result. Never return pointers into a handle that can be invalidated by a refresh. The 1.0 resource read will support a bounded 64 MiB caller-owned memory buffer in addition to transactional file output. Its size query uses the verified index; the read stages plaintext privately and changes caller memory only after complete verification. Larger resources use file output.
- Freeze numeric status codes, define unknown-code behavior, and return diagnostic text in an optional bounded caller buffer. Never include keys or protected content in diagnostics.
- Add new operations without changing existing signatures or struct layout.
Callback tables, if needed for HTTP, crypto, cancellation, and output, must
carry a
struct_sizeand version; ignore known trailing fields and reject a table smaller than the required prefix. Define thread and callback lifetime rules before accepting callbacks. - Keep the AMW wire-format version, package version, and ABI major/minor separate. A newer library may read old AMW media while preserving the same ABI. An incompatible ABI gets a new major symbol namespace and can coexist.
- Test the actual shared Reader library in C and C# consumers. Test Unreal
before advertising a stable game or engine capability. On Windows,
test x64 DLL loading with a clean install; then build and test each other
claimed platform.
tools/package-game-sdks.ps1now checks that the packaged DLL is PE32+ x64 and exports exactly the declarations inPreviewC.h. Repeat this check for each future platform binary and freeze the 1.0 symbol inventory as a compatibility gate.
1.0 release gate
The general Reader gate is hosted and external index open, resource metadata, public and member reads and downloads, all carrier codecs claimed by each platform package, cancellation, transactional output, and precise error states. Run the same fixtures through Node, C ABI, and C# with valid, corrupt, truncated, wrong-key, redirected, and stale-carrier cases. Revision 14 has typed status paths, but their wrapper coverage and exact stable values remain part of the 1.0 freeze. Game catalogue refresh, item fetch, and Unreal require their own parity gate before stable game capability claims; they do not delay a fully proven general Reader 1.0. Ship only public headers, library binaries, import files, runtime dependencies, samples, and versioned documentation for each supported platform. The public SDK terms and the protocol license permit use without a fee when both user and product remain below EUR 1 trillion in annual revenue; if either reaches the threshold, an enterprise agreement is required. The standard price absent a different negotiated price is EUR 133,700,000 per year per product. These terms cover AmoosedWeb code and protocol implementations. Implementation source belongs in a separately encrypted member edition issued to paying licensees under their agreement. The preview draft license still requires owner review before public SDK publication.