gg.grounds:resourcepacks-client for PackSet resolution and resourcepacks-contract for format/policy validation. This client owns metadata fetching and validated snapshots. It does not send resource packs to a player; a platform adapter owns delivery.
Sources
PackSetSource(baseUri, packSet, PackSetChannel.STABLE/EDGE) follows a channel. PackSetSource.release(baseUri, packSet, "v1.1.0") selects an immutable release. requestUri identifies the actual channel or release-manifest request, and cacheKey binds the normalized origin, PackSet, and selection.
Use selection and target for channel/release-aware code. Deprecated source.channel, source.channelUri, and snapshot.channel are channel-only and throw for release selections.
Lifecycle API
RefreshResult.Activated(snapshot) reports newly activated state, Unchanged(snapshot) reports retained validated state, and Failed(reason) reports a refresh failure. Inspect state() for fallback and failure state. Do not block a player-login or instance thread waiting for a refresh.
Configuration defaults
Channels continue refreshing periodically. Release pins resolve an initial immutable snapshot and reuse validated local state without periodic polling. Failed resolution uses retry handling rather than blocking player transitions.
State and snapshots
PackSetClientState contains source, nullable current, nullable degradedFallback, status, and nullable lastError.
PackSetSnapshot contains the selected source, resolved target, validated manifest, immutable ordered packs, and fingerprint. Each ResolvedPack contains order, role, id, uuid, uri, sha1, sha256, size, and required. publication exposes release/build identity independently of selection mode.
Reconfiguration can retain old state for diagnostics, but an adapter must deliver only a snapshot whose source matches the configured source. A previous channel’s fallback is not a fallback for a new release pin or origin.
Cache and integrity
The disk cache is keyed by the exact source. Cached state is revalidated against the contract before use. Metadata byte limits, expected publication roots, channel binding, manifest hashes/sizes, and compatibility prevent silently accepting unrelated data. The client validates distribution metadata. Minecraft clients fetch the referenced ZIPs during delivery; product publication verifies final CDN artifact bytes. Do not claim that readingstate() downloaded each ZIP into the server’s cache.
Contract API
PackSetContractJson.decodeChannel(bytes) uses the Grounds default policy. The overload taking a PackSetValidationPolicy and expected PackSetChannel also verifies the requested channel. decodeManifest(bytes, policy) returns ManifestDecodeResult.Success or structured failure diagnostics. Use library encoders for canonical bytes; handwritten JSON that is semantically similar can still be rejected as noncanonical.
An arbitrary HTTPS origin in a policy/configuration is an operator capability. Keep it inside an authenticated administrative boundary and never accept it from an unauthenticated player input.
