Skip to content

sco-core SDK documentation

Public SDK contracts generated from a compiler-validated catalogue. Engineering guides are selected by an explicit public-input allowlist.

Download sdk-catalogue.json

Published release

sdk-v2.3.0

SDK
2.3.0
Game pack
0.6.0
Plugin ABI
1.1
Archives
5 profiles

Immutable approved assets. Release notes

Mainline development preview

This documentation build

Source
e616ed69d8f9f77b0f4827881c86d91e4a7d1689
SDK
2.3.0
Game pack
0.6.0

Not an approved release. Pages describe this source commit.

  1. Start & SDK profiles

    Choose an SDK archive, build and check a first plugin, and learn how plugins are found and loaded.

    5 pages

  2. Language SDKs & cookbooks

    The C++ and C# SDK layers, worked examples and the per-language status of every contract.

    7 pages

  3. Native & service reference

    Service tables, callable contracts, game services and the engine-native index.

    48 pages

  4. Host integration & AI agents

    MCP discovery for agents and IDEs, the host-source kit, release notes and provenance.

    7 pages

Archives published in sdk-v2.3.0. Profiles and versions come from its release-scope declaration.

  • core

    sco-sdk-core-2.3.0.zip

    2.3.0 Standalone

    The game-neutral plugin SDK: the sco_api ABI, the host services, the C, C++, C# and Lua layers, examples and tools.

  • game-sc

    sco-sdk-game-sc-0.6.0.zip

    0.6.0 Requires core

    The optional Star Citizen extension: the game pack's service tables and events, DataCore, their C++ and C# wrappers, game examples and docs.

  • legacy

    sco-sdk-2.3.0.zip

    2.3.0 Includes core, game-sc

    Everything in one zip, as sdk-v1.1.0 shipped.

  • core-source

    sco-sdk-core-source-2.3.0.zip

    2.3.0 Standalone

    Kernel source-development archive: host/runtime, native and Lua loaders, required vendored code, CMake, tools and synthetic tests.

  • host-source-sc

    sco-sdk-host-source-sc-2.3.0.zip

    2.3.0 Includes core-source

    Standalone Star Citizen host source kit in repository layout: neutral kernel plus complete game implementation, DataCore, vendored build dependencies, headers and synthetic tests.

Each archive’s SHA-256 digest is listed in the release’s SHA256SUMS. Download it and the archive into one folder, then check that archive’s line: OK means the bytes match the published list. This checks integrity against the release’s own list; it is not a signature check. On Linux, use sha256sum in place of shasum -a 256.

Terminal window
curl -fLO https://github.com/scubamount/sco-core/releases/download/sdk-v2.3.0/SHA256SUMS
curl -fLO https://github.com/scubamount/sco-core/releases/download/sdk-v2.3.0/sco-sdk-core-2.3.0.zip
awk '$2 == "sco-sdk-core-2.3.0.zip"' SHA256SUMS | shasum -a 256 -c -
Terminal window
curl -fLO https://github.com/scubamount/sco-core/releases/download/sdk-v2.3.0/SHA256SUMS
curl -fLO https://github.com/scubamount/sco-core/releases/download/sdk-v2.3.0/sco-sdk-game-sc-0.6.0.zip
awk '$2 == "sco-sdk-game-sc-0.6.0.zip"' SHA256SUMS | shasum -a 256 -c -
Terminal window
curl -fLO https://github.com/scubamount/sco-core/releases/download/sdk-v2.3.0/SHA256SUMS
curl -fLO https://github.com/scubamount/sco-core/releases/download/sdk-v2.3.0/sco-sdk-2.3.0.zip
awk '$2 == "sco-sdk-2.3.0.zip"' SHA256SUMS | shasum -a 256 -c -
Terminal window
curl -fLO https://github.com/scubamount/sco-core/releases/download/sdk-v2.3.0/SHA256SUMS
curl -fLO https://github.com/scubamount/sco-core/releases/download/sdk-v2.3.0/sco-sdk-core-source-2.3.0.zip
awk '$2 == "sco-sdk-core-source-2.3.0.zip"' SHA256SUMS | shasum -a 256 -c -
Terminal window
curl -fLO https://github.com/scubamount/sco-core/releases/download/sdk-v2.3.0/SHA256SUMS
curl -fLO https://github.com/scubamount/sco-core/releases/download/sdk-v2.3.0/sco-sdk-host-source-sc-2.3.0.zip
awk '$2 == "sco-sdk-host-source-sc-2.3.0.zip"' SHA256SUMS | shasum -a 256 -c -

For any platform, including Windows (download with curl.exe). Set archive to the file you downloaded.

import hashlib
from pathlib import Path
archive = "sco-sdk-core-2.3.0.zip"
sums = dict(line.split()[::-1] for line in Path("SHA256SUMS").read_text().splitlines() if line.strip())
actual = hashlib.sha256(Path(archive).read_bytes()).hexdigest()
print(archive + (": OK" if actual == sums[archive] else ": FAILED"))
raise SystemExit(actual != sums[archive])
  • Result names without the prefix mean the corresponding SCO_* value. Normal success is SCO_OK unless the row describes a Boolean, ID, count, string or void result. Listed failures are known cases, not an exhaustive proof of every fault; unspecified cases and precedence between simultaneous errors remain unspecified.
  • The size / since cell gives the minimum x64 table byte extent that includes the whole function pointer, not just its first byte. Check size >= offsetof(Table, method) + sizeof(table->method) before reading that pointer, then check it is non-NULL. A version match alone does not justify reading an uncovered tail. The historical examples using size > offsetof(...) presume a well-formed complete provider table; current consumers must use the full extent and non-null method check, not that historical shorthand.
  • For service discovery, query_service requires equal version majors and a provider minor at least the requested minor. Missing service: SCO_NOT_FOUND; incompatible/older version: SCO_UNAVAILABLE; output table NULL except on success. No missing pointer or service should be called. Tables may grow only by appending fields; unknown tails are not to be inspected. Host/game-owned tables outlive all plugins and are withdrawn after plugin unload. Third-party tables have the provider’s lifetime, not that of the querying plugin.
  • Caller size-prefixed inputs/outputs use sizeof as built by the caller. An oversized buffer/struct is not a promise that an unknown tail is initialized: tail initialization and preservation are unspecified unless noted. Command argument-definition stride is arg_def_size; sco_arg is frozen at 16 bytes, sco_sql_value at 16 bytes and sc_vehicle_seat at 96 bytes. Padding/reserved input fields are zero. Enums are 4 bytes; do not pass _FORCE32 sentinels.
  • Byte handshake: *inout_size is capacity on entry, bytes written on success, bytes needed with SCO_TOO_MANY; NULL output with zero capacity asks the size. Text is NUL-terminated and the terminator counts. This is not the same as get_peers’ element-count handshake or the truncating fixed-capacity name calls. Required size may change between calls: retry if needed, not an atomic snapshot.
  • Caller buffers stay caller-owned. No returned service pointer, string, mapping, command descriptor, frame or game ID is an allocation the plugin may free. “No allocation transfer” does not mean “no internal allocation” or “real-time safe.” Internal allocation bounds/latency are unspecified unless recorded.
  • Unless a row says inputs are copied, their retention is unspecified beyond the synchronous call. Keep borrowed callback code and ctx alive for its registration or queued lifetime; ctx is not automatically freed. Callback payload pointers are valid during the callback only; copy retained data.
  • Any-thread permission is not a recursive-reentrancy guarantee. Rows explicitly mark known callback-safe operations and otherwise say reentrancy unspecified. Game-thread permission does not permit calls from a game hook or arbitrary worker.
  • “No cancellation entrypoint” records API surface, not guaranteed completion, rollback or an interruptible call. Unload/crash cleanup and callback quiescence are stated separately. Synchronous calls have no cancel token. Cancellation of an operation already in progress is unspecified unless stated.
  • last_error is a diagnostic, not a return-value replacement: scope varies by service and another call may overwrite it. Complete diagnostics for every failure and error-text retention after success are unspecified unless documented.

This is an inventory-complete catalogue, not a claim that the API has a complete behavioral specification. In particular:

  • Recursive reentrancy/depth, lock-acquisition latency, internal allocation bounds and worker-vs-unload quiescence are unspecified for most methods. Any-thread support alone does not establish them.
  • There is no general cancel-token API or promise to interrupt running calls. Queue drop, registration withdrawal, rollback, deferred despawn and a game action’s actual completion are different events; do not conflate them.
  • No universal failure-output, tail-zeroing or diagnostic-isolation rule exists. Some methods zero outputs, some leave them unchanged, some change required sizes and some can fail after producing a game side effect. Buffer-specific conditions above take precedence over broad header prose.
  • DataCore’s allocation-exception translation, concurrent commits/discards on the same patch and ordering of competing saved-file commits are unspecified.
  • spawn.entities failure-reason lifetime is unspecified; copy it during the call’s immediate use and do not free it. Tracking failure may follow a successful spawn.
  • game.vehicles / game.creative do not establish uniform released-self rejection or error-isolation guarantees; their last_error implementations need not enforce handle/service-start checks. Other game diagnostics also have no stopped-service refusal guarantee. Do not use stale handles merely because a table is still mapped.
  • Direct IPC view synchronization with peers/close/unload is unspecified by this service table; a borrowed mapping does not grant safe concurrent unmapping.
  • Watch/query-radius/state reserved behavior remains gated off; event vehicle-seat payload, actor health maximum and camera field of view are not filled from a verified live-game contract. Event payloads are not additional method rows; game services documents delivery and absent capability.

For additions, append a record under sdk/contracts/ and update the corresponding method row and inventory here. Run tools/sdk_catalogue.py check to compare both with compiled header declarations and member extents. A comment, signature or sibling service’s behavior is not evidence for an unstated guarantee on a new method.