OPENHOOPS / 2K14Final team archive · November 9, 2026Reference libraryChecksums

Dated source reference. Current release status: handoff state. Full original relative paths are in the developer archive.

Roster metadata connection — development52

Current work70/API55: API70e passes634 Windows tests and retains API70c's unique arena HCParamsID→physical ROS row mapping. Native arena:11 is row10; all102 captured catalog entries match. Start keeps native IDs while companions/C entities use physical rows; missing/ambiguous IDs refuse. Original70liveo and college70liveq now pass strict copied native fields/epoch/hash, phase4 binding and independent immutable final delivery. The college decoder fix is game-verified; both runs restore98 files/DLL50/INI and release. Historical contexts/results remain immutable. Current ledger.

Private API 0.2.0.dev52 / HTTP v1 connects the browser editor's existing version1 companions to independent clients, managed match preparation, opening-scene identity binding and durable results. Snapshot ABI26 (74648 bytes), event ABI4, college profile4, court definition3 and all67 native inputs remain unchanged. The DLL does not parse sidecars or gain a new presentation/rules callback. Public Windows preview packages remain historical API36.

Editor to client

Export the editor's roster ZIP. It contains one ROS and its exact ROS.openhoops.json companion. Client.upload_roster_bundle(path) checks the complete pair before uploading either component. A ROS path with an adjacent companion also works. Keep identities separate: roster:<native SHA256> names game bytes; roster-metadata:<companion SHA256> names optional fields. Multiple immutable companions can belong to the same ROS. No mutable global sidecar is selected implicitly.

All91 standard fields use the editor's exact catalog. Any developer can add scalar fields in a namespace they control. Association/division, conference, rank, high-school/previous-college and other fields remain optional. Missing, explicit null, false, zero and leading-zero text identities remain distinct. Field validation and effective ranking/conference consistency apply before Start. An app decides how to display or consume fields; declaring one does not apply a native rule or expand native conference standings.

pair = client.upload_roster_bundle("EditedRoster.zip")
fields = client.query_roster_metadata(pair["roster_metadata"]["id"], section=10)
# identity_plan supplies explicit external IDs and expected native names.
result = launch_registered_match(
    client, pair["roster"]["id"], preparation_values,
    identity_plan=identity_plan,
    roster_metadata={
        "id": pair["roster_metadata"]["id"],
        "overrides": {"teams": {"home": {"fields": {
            "org.openhoops.ranking.national_status": "ranked",
            "org.openhoops.ranking.national_rank": 12,
        }}}},
    },
)

Import launch_registered_match from openhoops_api.match_launch. Use the normal authenticated client/setup; its loopback and cross-origin restrictions remain. The editor is an authoring website, not an unauthenticated browser-to-game bridge.

The existing version1 match request also accepts roster: {archive_path, sha256}. Its optional roster_metadata selects {id} or {path, sha256}, with optional overrides/player_rows. An overrides-only declaration uses the adjacent/ZIP companion when present; otherwise it creates an empty hash-bound companion. RequestJob freezes validated ROS/metadata into private immutable intake before child startup, so deleting/replacing the original downloads cannot change that request. Existing ROS {path, sha256} and registered {id} requests remain compatible. Shared-writer edits/preparation derive a new checked companion only when every physical table count is preserved; their receipts retain the original companion.

Mapping and per-match values

Resolve against explicit team, uniform and arena selections plus the identity plan before requesting Start. Team IDs here are physical roster row choices; graphics IDs are separate. Unique native names within each selected team's membership can resolve player rows. Ambiguous names require a complete explicit player_rows map. Both paths check membership and native snapshot name limits. This is checked source-row association, not a new authoritative native player-pointer ABI.

An applied Start records those five selections. At the managed zero-stat phase4 boundary, binding rechecks the loaded ROS, selections, instantiated native names and explicit external IDs, then freezes the selected context. One applied Start can bind one metadata match. Metadata binding after opening play is refused. Uninstantiated plan slots retain metadata separately and receive no invented statistics or native status.

Overrides support roster, home/away teams, selected arena, home/away uniforms and identity-plan player slots. Each patch has fields and/or unset; null is explicit unknown, while unset removes a field. Effective merged fields are validated together. Results label each retained field's origin as roster_companion or match_override; source files and immutable companions never change.

Interfaces and persistence

Interface Behavior
GET /v1/roster-metadata/catalog Versioned91-field catalog
PUT /v1/roster-metadata/<sha256> Authenticated raw companion JSON intake, verified SHA and bound ROS
POST /v1/roster-metadata Explicit absolute local JSON path and SHA intake
GET /v1/roster-metadata/<sha256> Immutable descriptor, including bound roster ID and native_effects:false
GET /v1/roster-metadata/<sha256>/content Exact companion bytes with SHA ETag
POST /v1/roster-metadata/query Roster fields and paged section/row fields; limit1–128
POST /v1/roster-metadata/resolve Checked selected context specification before Start
Existing match/snapshot/results Full frozen match context, compact live reference, full durable result context
Client.download_roster_bundle(...) New ZIP containing the exact matching pair; refuses existing outputs

The frozen context carries its own SHA256 over canonical sorted ASCII JSON excluding its own sha256 member. A snapshot only carries the compact reference, avoiding repeated full metadata transmission. Match/result contexts survive restart, independent consumer ACKs and source-companion removal. Original native game saving can change ROS bytes: no automatic sidecar rebind or save reconciliation is promised. The active match keeps its frozen source context (frozen_source_context_no_automatic_rebind). A new native file needs explicit metadata reconciliation before reuse.

Limits:16MiB companion,256 scalar fields per record/scope,32KiB total overrides,512KiB selected frozen context,40 identity-plan player slots. Existing editor and native roster capacities remain finite. Raw companion intake has a separate bounded route; ordinary JSON command limits are unchanged. Assets, code/callback execution, arbitrary rules, authoritative legal possession and custom in-game presentation are not introduced.

Reading fields for a future scorebug

A presentation client reads GET /v1/snapshot for changing scores/clocks and its compact roster_context reference. Fetch GET /v1/matches/<match_id> once for that reference and cache the full roster_context by SHA256. Check that the returned context SHA matches the snapshot reference before combining them. Reset the cache on a different match/reference. The result carries that same full context for postgame displays.

Use context.teams.home.fields["org.openhoops.ranking.national_rank"] with its explicit ranking status; an absent/null rank is not automatically unranked. Developer fields such as com.yourapp.scorebug.logo_key, short_name or accent follow the same path. These example keys describe an app's contract, not built-in OpenHoops rendering behavior. A logo key identifies content the app supplies; it does not download or hot-swap game artwork. Per-player values are under context.players[slot].fields, with the checked physical row and external ID alongside them. Compare that external ID with the current snapshot player before displaying a nameplate. uninstantiated_players has metadata only and must not be treated as a live bench/status/statistics feed.

Fields load into the broker's checked match context while the native game runs. The current DLL does not expose an in-process custom-field lookup or draw them in the native scorebug. An external scorebug can consume the public HTTP data now; an injected/native presentation needs its own future integration. Keep that distinction when describing "in-game loading."

Evidence and limits

Native acceptance61 uses source61a, archive 514069830276cf1df24d611a8225f1fa8ac0389e1ec7f4e96eaf7e36f28a5029, and unchanged52zd DLL 4a4f0affa8e251b536dfcec395eb6f77673548c923083a5cec052099208fd88d. All106 API/code/schema/test inputs and67 native inputs match tested59d; only working docs and the separately tested web grid differ. A separate copy of the actual hosted editor905-team export supplies team rows904/903, uniform rows3777/3774 and arena11. Checked editor companion edits add representative standard rank/high-school fields and developer-owned scalar fields across roster/team/player/arena/uniform scopes, preserving every native ROS byte. This is synthetic metadata, not supplied real-mod artwork.

The real Windows adapter loads/starts natively with zero generated input and binds all24 instantiated players at phase4; six other planned players retain metadata only. A separate public HTTP client reads10 live scorebug data samples with clocks/scores, IDs, custom labels/logo keys and rank. Per-match overrides, unset, field provenance, null/false/zero/leading-zero strings all pass. Two60-second halves finish naturally home4–away3; the finalized player/team totals reconcile. Two independent consumers persist identical frozen context before ACK; repeated ACK and independence pass. Runtime acceptance, native status.

With the original input ZIP withheld after intake and the native child/broker closed, reopening the persisted real-game database over HTTP retains the exact result/context and both prior ACKs; a third consumer receives the same immutable result. No snapshot is generated or ingested for that readback. Persistence/schema checks validate the actual live/final snapshots, match, context/reference and result. Restoration and preservation verify98 isolated baseline files,95 original saves in both games, restored50/stable35/executables, public ZIPs and all four hosting identities. Only the owned game/broker/task were closed. No new native build, shared desktop input, MVP change, presentation renderer or public package.

Source59d, archive 8e89717d9b24a1588a19308341c026722fcf4623babf2f01e6aab48acc6de4bd,265 inputs:539 Windows API tests,98 schemas/16 positive-negative response checks and reference resolution pass. The public SDK/HTTP/core sequence exercises intake, prepared selection, simulated adapter Load/Start, phase4 binding, overrides and durable final context. These are service tests with an explicitly simulated native adapter, not another game run. The actual hosted editor's905-team/13665-player/3779-uniform exported ZIP passes authenticated SDK intake/query/exact-pair download and highest-row/name inspection. Test report, schemas, editor round trip.

59a's missing sanitized catalog.slots packaging export and59c's incomplete simulated arena catalog are retained as failed evidence. The builder now preserves slots; the accepted full suite has zero skips. Existing native startup/control evidence remains scoped to its original exact DLL and scenarios. At checkpoint59 no game, native build, shared desktop input, new public Windows package or deferred presentation/mod campaign was run. Native61 above adds the focused real-game metadata check. Editor feedback60 separately records the deployed spreadsheet/recovery fixes.