Skip to content

Library packages and releases

GES libraries share one release version and Git tag. There are no independently versioned Swift module repositories.

The repository’s release badges show the latest non-prerelease NuGet package and GitHub release. Swift Package Index badges report its observed Swift-version and platform build compatibility, not shared Conformance acceptance. Consult the release notes for migration guidance and the changelog for unreleased changes. See the version policy for compatible updates and contract changes. The platform support matrix separates package requirements, Conformance coverage and native distribution checks.

Since: 0.2.0 — package icons

NuGet packages embed the Pixel-Duo logo as icon.png; no external image URL is required. The release package check verifies both the manifest reference and the embedded image against the checked-in brand asset. Existing published versions retain their original package contents; icons are included starting with 0.2.0.

Distribution Public products
NuGet GameEventScript.Runtime, GameEventScript.Compiler, GameEventScript.CSharpBridge, GameEventScript.SyntaxHighlighter
NuGet tools (since 0.3.0) GameEventScript.Tool, GameEventScript.Tool.Aot (plus RID implementation packages)
SwiftPM libraries GameEventScriptRuntime, GameEventScriptCompiler, GameEventScriptSwiftBridge, GameEventScriptSyntaxHighlighter

SwiftPM also exposes the ges executable starting with 0.3.0.

Compiler and each native Bridge depend on their Runtime. An application can use Runtime alone. SyntaxHighlighter is optional and depends on no other GES module. Conformance stays in the repository for development and CI. The SwiftPM CLI product is optional and is not compiled when consuming only the libraries. Homebrew and local installers remain available. See standalone CLI downloads for installation and release verification. Deferred distribution work is tracked in BACKLOG.md.

Version policy

GES uses MAJOR.MINOR.PATCH release numbers. This section owns the release numbering policy; language, API and binary behavior remain defined by their owning specifications.

Before 1.0

Release Allowed changes Example
Patch Compatible corrections to the existing contract; no new language or API features and no incompatible contract changes 0.2.0 → 0.2.1
Minor New features, compatible improvements, or deliberate contract changes with migration guidance 0.2.1 → 0.3.0

A 0.x release is a usable development release, not automatically a release candidate for 1.0. There is no general compatibility guarantee between 0.x minor versions. Consumers should pin an exact version or constrain updates to the selected minor line and review migration notes before changing that line.

A correction may change behavior that violated the documented contract. It must not silently redefine that contract under the label of a bug fix. If a fix requires an incompatible contract change, it belongs in the next minor release. Document observable corrections in the changelog, including any impact on users who relied on the incorrect behavior.

From 1.0 onward

GES follows Semantic Versioning 2.0.0 for its declared compatibility surface:

Release Allowed changes Example
Patch Backward-compatible fixes 1.0.0 → 1.0.1
Minor Backward-compatible additions and deprecations 1.0.1 → 1.1.0
Major Incompatible changes to the declared contracts 1.1.0 → 2.0.0

The owning specifications define source compatibility, recompilation and determinism, and binary acceptance. The language baseline is recorded in the scope review. The API review records the selected embedding surface. The pre-1.0 bytecode redesign decision remains open and may require a follow-up review of public Program and codec types. These future guarantees do not freeze today’s 0.x API; pre-1.0 binaries have no guaranteed support in 1.0. Retain source for recompilation.

Language scope review for 1.0

The current immutable, event-driven language is the 1.0 baseline. Reviewing the remaining language backlog against the owning specifications and the reported C# and Swift application integrations identified no additional language feature required for 1.0. This is a scope decision, not a declaration that all release verification, public API or bytecode work is complete.

Area 1.0 baseline and review result
Expressions and control flow Existing bindings, conditions, functions/predicates, iteration and collection selectors, including conditional bindings and fold/reduce. No missing construct has been identified as an integration blocker.
Messaging Existing emit/publish, delayed sends, ordered arguments and the documented host lifecycle. Applications supply entry messages and native integration.
Portable data literals Scalars, units/percentages, Vector/Point, stored Dice results, recursive Lists/Maps, Range, built-in Series, Handler signatures, Messages and Record data already have defined forms. No remaining portable data kind requires a new literal for this baseline.
Text reconstruction Existing parse recognition/fallback and Record-constructor rules remain as specified. Top-level Text is intentionally not an exact typed roundtrip; Handler data does not reconstruct executable code.
Product transport Existing JSON transports data and external Record snapshots. It does not reconstruct native object identity, callbacks or host bindings.

The literal and transport rules remain owned by Language, Text and Message format. Existing portable evidence is indexed by Conformance coverage, including C# ↔ Swift product JSON exchange. Application integration experience supports the scope choice but does not replace those executable contracts.

Series are the built-in Fibonacci and factorial sequences, represented by their kind and offset. No native Series registration API is part of the language scope. Reconstruction of executable host-bound values is explicitly not required for 1.0. Applications install native bindings themselves; extensions can supply application-specific behavior through the existing boundary. A portable standard-extension library is also not required for the language baseline. Both topics remain deferred in BACKLOG.md; there is no commitment to a particular later release.

Additional language ports, the shared Conformance orchestrator, editor tooling, compression/signing and optimizer improvements are separate engineering topics, not missing language constructs. This review does not decide their release priority or close the independent constant-pool/instruction-layout decision. New application evidence may justify reopening the language scope before 1.0; otherwise no additional syntax or value kinds are required by this review.

Public API review for 1.0

The current C# and Swift Runtime, Compiler and Bridge workflows form the selected embedding API baseline. Reported integrations cover Swift compilation/editor reload and external types, and Unity C# compilation and native handlers on iOS (IL2CPP) and Android. No integration blocker requiring a new public abstraction was reported. Runtime-only consumption is covered by automated distribution checks rather than a separate application trial. This is an API scope decision, not a claim of identical native spelling or a completed 1.0 release.

Reviewed workflow C# Swift Decision
Compile source GameEventScriptBuilder.Create() → AddScript → Compile GameEventScriptBuilder.create() → addScript → compile Keep source-in-memory builders, repeatable compilation and separate declarative external catalogs.
Configure hosts GameEventScriptHost.CreateBuilder() → With… → Build GameEventScriptHost.createBuilder() → with… → build Same configuration responsibilities, including clock, limits, randomness and registries; every build creates an independent host.
Start and dispatch Load, Subscribe, Start, Receive, ExecuteFrame, RunToCompletion Corresponding lower-camel-case operations Preserve the explicit initial loading phase, structured startup/execution results, later-instance results and delayed-work reporting.
Precompiled programs Runtime Reader/Writer/Validator/Dumper Runtime Reader/Writer/Validator/Dumper No Compiler or Bridge dependency is required for codecs or execution.
Native integration Interfaces, delegate adapters and reflection attributes Protocols, closure adapters, macros and manual descriptors Keep portable catalogs separate from executable registries; native conversions retain their strict guarantees.
Automatic pumping Runner methods serialize access to instance/subscription handles; Dispose ends use sending ownership transfer and runner-owned registration handles; close ends use Different handle shapes serve native concurrency conventions. Both expose startup status, serialized lifecycle and automatic wakeups.
Diagnostics and values Exceptions/results, readonly views and fixed-width numeric types throws, optionals/results and copy-on-write values Preserve structured codes, ordered arguments and immutable data semantics, rather than exception text or native representation.

Direct Swift initializers remain idiomatic alternatives to factories. Swift’s throws, ownership annotations and registration wrapper do not require matching C# overloads. C# reflection attributes and Swift compile-time macros likewise need not share a mechanism; they describe equivalent native binding concepts. The API review does not add convenience methods solely to equalize spelling.

The review uses the C# public surface/XML documentation and portable-boundary gates, the Swift symbol-graph/snapshot/documentation gate, and executable C#/Swift embedding and bridge examples. The current declared surfaces match their approved snapshots; no signature change or snapshot regeneration is needed for this review.

The normative API compatibility rule is in Public API. Future constant-pool or instruction-layout changes remain a separate decision: if they alter public Program/codec types, update this baseline, both language mappings, native documentation and snapshots together before 1.0. No compatibility shim is required solely to preserve a pre-1.0 API.

Mutation and persistence review for 1.0

The review found no known requirement for a breaking change arising from application-owned mutation and persistence. The existing native integration boundaries support this model. The owning rule is state ownership. This conclusion does not settle the separate source, API or binary compatibility reviews.

Boundary reviewed Result and remaining responsibility
Immutable Program and script data Application state stays outside the reusable Program and .gesb; no storage handles or persistence schema are added to them.
Native handlers and extensions Existing synchronous callbacks can perform game-state changes. The application defines their effects and error recovery.
External values Field access must preserve the logical-value stability required during a handler. An extension changing the game does not authorize changing the same exposed logical value underneath a running or paused handler.
Startup and failures Initialization stages GES outputs; it does not undo external effects already performed by callbacks. Applications needing all-or-nothing changes must provide their own staging or compensation.
Frames and multiple hosts Pausing a script does not create an application transaction. Separate hosts do not establish a global order over shared mutable application state; the embedding supplies synchronization and ordering.
Persistence and replay Product JSON transports data snapshots, not a saved VM or restored native binding. Application schema migration, recovery, duplicate-action handling and reproduction of native inputs remain application concerns.

The remaining risks are integration responsibilities: partially completed native operations, changing external observations, and concurrent access to shared game state. GES does not resolve them by adding mutable language state. Revisit this review if the project later proposes script-owned storage, transactional native calls, or persistence of live execution state.

See Host runtime, External-type API, Determinism and Message format for the existing contracts.

Shared versions, formats and prereleases

  • Public library packages and CLI artifacts for a release use the same GES version and source tag. Upgrade an application’s GES libraries together. A future language implementation joins the current release line; it does not restart at 1.0 or imply that earlier versions existed for that implementation.
  • The package version, .gesb format version and application-owned ProgramVersion are separate identifiers. A package release does not automatically increment the binary format version. Binary compatibility and rejection rules belong to Binary format and Bytecode, not to an inference from package numbers.
  • Prerelease suffixes such as 0.3.0-rc.1 identify candidates for the named release. They are optional; a verified development release can be published directly as 0.3.0. Candidates precede the corresponding final version and may change before that final release.
  • Published versions and tags are immutable. Corrections require a new version; never replace an existing release’s package contents or move its tag.
  • Record user-visible changes under Unreleased, then publish them with the release. Contract changes require migration notes explaining the affected behavior and the action consumers need to take. Documentation availability notes describe the current behavior’s release, not a full compatibility matrix.

SwiftPM and Xcode

The repository-root Package.swift is the public entry point. It declares four library products using the existing source directories; it does not depend on the sibling development packages or expose Conformance. Since 0.3.0 it also exposes the ges executable; library consumers build only their selected products.

Since: 0.2.0 — root-package native tests

The root package also declares three test targets that reuse the existing SwiftBridge, bridge-macro and SyntaxHighlighter test sources. They are not library products and are not compiled when an application consumes the libraries. Run them from a repository checkout with:

Terminal window
swift test --scratch-path artifacts/swift/root-tests --disable-build-manifest-caching --configuration release

The highlighter tests read the shared Markdown fixture under conformance/highlighting; no Conformance library dependency is added.

In Xcode, select File → Add Package Dependencies, enter https://github.com/schloepke/GameEventScript.git, select a published version, and add the desired products to your app target. SwiftPM downloads the repository, but a Runtime-only dependency does not build or link Compiler or SwiftBridge.

For a consuming Swift package, after the corresponding version has been released:

platforms: [.macOS("10.15.4")],
dependencies: [
.package(url: "https://github.com/schloepke/GameEventScript.git", from: "0.1.0")
],
targets: [
.target(name: "MyApp", dependencies: [
.product(name: "GameEventScriptRuntime", package: "GameEventScript")
])
]

For a prerelease, select that exact version, for example .package(url: "https://github.com/schloepke/GameEventScript.git", exact: "0.1.0-rc1"). These version numbers are examples, not a claim that they have been published. Use import GameEventScriptRuntime and optionally the Compiler/SwiftBridge imports.

Swift 6.0 or newer is required. macOS is the currently CI-verified platform; other platform support must be verified before being advertised. The root package requires macOS 10.15.4 for CLI Foundation I/O; the local SwiftBridge package requires macOS 10.15 for its SwiftSyntax macro dependency. Consuming packages must declare this or a newer macOS target. This is a macOS deployment minimum, not an Apple-only restriction. The CLI/Conformance tools separately require macOS 10.15.4.

There is no upload to Apple or a Swift registry in this flow. Publishing a Git version tag makes the root package available to SwiftPM; it does not itself create a GitHub release or publish NuGet packages. The individual packages under implementation/swift remain local development and verification entry points.

Verify a release without publishing

Use the platform qualification checklist to collect matching CI evidence for the exact release revision. A package build alone does not qualify all platforms or toolchains. Collect the separate performance and allocation evidence on the qualified measurement host without extending ordinary Swift PR CI.

Release preparation also requires the release consumer upgrade checks. The C# Release Candidate workflow runs the separate C#/Swift upgrade workflow before preparation; it does not extend normal Swift PR CI. The selected 0.3.0 baseline is tested against the checked-out candidate commit without publication.

Terminal window
./scripts/release-csharp-dry-run.sh 0.1.0-rc1
./scripts/verify-csharp-reproducibility.sh 0.1.0-rc1
python3 scripts/test-publish-csharp-packages.py
python3 scripts/test-swift-package.py

The C# dry run creates four canonical NuGet packages, matching symbols and DLL sets, then compiles and executes independent consumers. See C# distribution. The publication-selection tests substitute a fake dotnet; they never contact NuGet. They verify that stale/internal packages cannot enter the upload list and that missing artifacts stop the entire upload before its first request. Tool packages have a separate explicit allowlist and complete-set validation.

The SwiftPM check copies the current root manifest, library/test sources and required Markdown fixture into an isolated Git repository under artifacts/swift-package, creates a local test tag, and resolves that version from two independent consumers. It checks all four products, the dependency graph and the explicit macOS minimum in both macro manifests, compiles/serializes/executes a Program, and runs that Program with Runtime alone. It also rejects builds of Compiler or Bridge in the Runtime-only consumer and compilation of test targets/support in either consuming application. It executes the three root test targets in the isolated checkout. No tag or commit is added to the working repository and nothing is published; SwiftPM may fetch the official SwiftSyntax dependency.

The manually dispatched C# Release Candidate workflow runs the C# tests and dry run, the portable and six native NuGet tool checks, plus the SwiftPM consumer gate on macOS. With publish=false, it only uploads GitHub workflow artifacts. Their access follows repository visibility. Ordinary PR CI also verifies packaging, consumers and publication selection.

One-time NuGet and GitHub setup

  1. Choose the NuGet package owner (user or organization) and confirm the four library package IDs can be published by that owner. Package Authors metadata does not determine NuGet ownership.
  2. On nuget.org, create a Trusted Publishing policy for repository owner schloepke, repository GameEventScript, workflow filename csharp-release-candidate.yml, and environment nuget. Update these values if repository ownership changes. Scope the policy to GameEventScript.*, permitting both new packages and new versions.
  3. In GitHub, create the nuget environment with the required release reviewer and restrict deployment to the intended version tags. Merely naming an environment in YAML does not configure approval rules.
  4. Add NUGET_USER as a repository or nuget environment secret. Its value is the NuGet login username, not an email address or API key. The official NuGet/login action obtains a short-lived key through GitHub OIDC.
  5. Keep the repository variable NUGET_PUBLISH_ENABLED absent/false until ready to enable publication. Set it to true when this setup is complete.

See the official Trusted Publishing instructions. Neither a website/domain nor author-signing the NuGet archives is required by this workflow. Canonical packaging must precede any optional signing.

Publish a shared version

Select the release number using the version policy.

Update applicable Since: Unreleased notes in specifications and guides to the selected release version. Retain only the version of the currently described behavior; do not add previous definitions to the specification.

Before the release preparation PR is merged, move the applicable Unreleased entries in CHANGELOG.md into a section named for the selected version and release date, leaving an empty Unreleased section for future changes. Review migration guidance alongside the implementation. Use that versioned section as the basis for the GitHub Release description; generated PR lists may supplement it.

  1. Merge the reviewed changes and complete the platform qualification checklist for the selected commit. Run the release workflow with publish=false and the intended version.
  2. Once the release is approved, create and push a Git tag such as 0.1.0-rc1 (or v0.1.0-rc1) on that same commit. This is already the SwiftPM publication step; do not create public version tags merely to test packaging.
  3. Dispatch C# Release Candidate against that tag, enter version 0.1.0-rc1 without the optional v, and select publish=true. Publication from a branch or a different version tag is rejected. The workflow must exist on the default branch before it can be dispatched normally through GitHub Actions.
  4. After both preparation jobs succeed, approve deployment to nuget. The upload job downloads the verified artifacts from the same run and submits only the four selected-version library packages and their symbols.
  5. Verify NuGet validation/indexing and consumption through Xcode/NuGet. A GitHub Release can then document the version and link to the packages.

Swift tags and NuGet uploads are separate publication operations, not a transaction. A failed NuGet upload does not withdraw a Swift tag, and some NuGet packages may already have been accepted. Inspect the outcome before retrying; the script deliberately does not silently skip duplicate versions. Never move a published version tag or overwrite its intended release contents.