NuGet packages
Run the complete package check from the repository root:
bash scripts/verify-packages.shRequires .NET SDK 10.0.100 or later with .NET 10 support, Bash, a Git checkout, and access to nuget.org for third-party dependencies. The C# verification tools use .NET file-based apps and the standard library; no additional tool installation is required. The native rendering example is exercised on Linux in CI.
Packages
Section titled “Packages”All packages target net10.0 and share the version in Directory.Build.props,
managed by release-please. Each package includes its own English README, the
original Moongate logo, XML documentation, and a companion symbol package.
| Package and README | Purpose | Direct Moongate dependencies |
|---|---|---|
| Moongate.Api | Typed MessagePack request/reply over mutual TLS with local authorization | Network |
| Moongate.Core | Shared primitives, geometry, configuration, and utilities | None |
| Moongate.Network | Standalone TCP transport, framing, and pipelines | None |
| Moongate.Network.Packets | UO packet definitions and span-based serialization | Core |
| Moongate.Persistence | Asynchronous PostgreSQL modules, transactions, schema operations, and typed entity access | Core, Persistence.Migrations |
| Moongate.Persistence.Migrations | Versioned SQL catalogs and immutable migration history validation | None |
| Moongate.Scripting | Embedded Lua 5.2 runtime, attribute-bound modules, coroutine scheduling and editor definitions | Core, Server.Core |
| Moongate.Server.Core | Server and plugin contracts, events, and registrations | Api, Core, Network, Network.Packets |
| Moongate.Ultima | UO client data readers and rendering utilities | None |
Moongate.Server, Moongate.Boot, Moongate.MigrationRunner, and Moongate.UoxItemConverter are
executables distributed through release artifacts and container images. They do not produce library
packages. Tests and plugin fixtures are also excluded from packing.
What the command checks
Section titled “What the command checks”- Builds and packs the solution in Release into a new
artifacts/nuget.*directory. - Checks exactly nine
.nupkgand nine.snupkgfiles: metadata, dependencies, README bytes, original logo hash, DLL/XML payload, Portable PDB identity, and SourceLink pointing to the repository commit recorded in the package. - Extracts the marked C# examples from each README into nine temporary console apps outside the repository. Each app references one Moongate package directly; the persistence verifier references Npgsql to provision its isolated database, and the API example references MessagePack to generate its serializers.
- Restores, builds, and runs those apps, checking their output. This exercises geometry, TCP lifecycle, packet encoding/decoding, PostgreSQL persistence, the event bus, typed API registration, embedded Lua module execution, and native SkiaSharp loading. Separate solution tests also start independent .NET processes to verify mutual TLS, local authorization, direct game access with login offline, and no replay after a lost response.
The persistence consumer requires MOONGATE_TEST_POSTGRES_CONNECTION_STRING as
an administrative Npgsql connection. It creates a unique
moongate_test_nuget_<uuid> database, runs the README example there, and drops
only that generated database. Missing configuration fails with an actionable
message; it never silently skips.
The current FreeSql.Provider.PostgreSQL 3.5.311 dependency resolves Npgsql
5.0.18. Keep that acknowledged provider constraint rather than silently
overriding Npgsql to another major. A provider/driver upgrade must pass the real
PostgreSQL package consumer and solution compatibility tests described here.
The solution’s PostgreSQL fixtures use the same contract. Point it only at an isolated test server whose admin role may create/drop databases:
MOONGATE_TEST_POSTGRES_CONNECTION_STRING='Host=127.0.0.1;Port=5432;Database=postgres;Username=postgres;Password=...;Pooling=false' \ dotnet test Moongate.slnx -c ReleaseEach fixture creates a unique moongate_test_<uuid> database and drops only that
database. Never use an operator Accounts or Realm connection for this variable.
Consumer apps use a new temporary NuGet cache for each invocation. Package source
mapping restricts Moongate.* to the generated local feed and resolves external
dependencies from nuget.org. Existing global packages cannot make a broken local
package appear to work. No UO client files, external game servers, or fixed
listening ports are needed.
Output and troubleshooting
Section titled “Output and troubleshooting”Successful runs print a PASS line per library for both archive and consumer
validation, followed by the package output directory. The generated archives remain
in that directory for inspection and are ignored by Git. Consumer workspaces are
removed after success. On failure, the tool prints the failing operation and retains
its temporary workspace for diagnosis.
To rerun a check against an existing output directory, pass its path explicitly:
dotnet run --file scripts/VerifyNuGetPackages.cs -- "$PWD" /path/to/package-directorydotnet run --file scripts/VerifyNuGetConsumers.cs -- "$PWD" /path/to/package-directoryAn empty symbol package indicates missing PDB output. The nine library projects set
Release DebugType=portable in their .csproj files, before MSBuild computes symbol
output items. Setting it later in Directory.Build.targets is insufficient. Shared
README, icon, and symbol-pack metadata are configured in that targets file. The
server retains embedded debug information.
A native rendering failure should be reproduced on the deployment platform with its SkiaSharp native runtime. Linux CI does not certify Windows or macOS execution.
CI and publishing
Section titled “CI and publishing”The Release configuration of .github/workflows/ci.yml runs the same verification
command after the solution tests. The existing third-party notices check remains
enabled. These checks do not publish anything or require a NuGet API key.
Publication is a separate responsibility of the existing release workflow.
Running the verification script does not create a release or push packages to a feed.
Packability is opt-in: the shared default is IsPackable=false, and only the nine
library projects explicitly enable it. Their existing ProjectReference entries
become NuGet dependencies instead of bundled copies of other project assemblies.
When changing an example, keep its nuget-smoke HTML comment directly above the
C# code fence so the consumer check continues to compile the documented code.
