Skip to content

Latest commit

 

History

History
72 lines (49 loc) · 5.5 KB

File metadata and controls

72 lines (49 loc) · 5.5 KB

Generated assets and authoritative import

IGameMediaGenerator produces media. GameGeneratedAssetPipeline turns that output into a persistent, game-owned asset operation without turning media generation into a second agent loop.

Use it for portraits, expressions, item icons, placeable images, audio, video, or other generated resources that must survive a restart and enter authoritative game state. The framework does not define the game's character, item, quest, level, or ability format.

Lifecycle

stable game operation
  -> persist Generating
  -> call IGameMediaGenerator once
  -> materialize and validate bounded resources
  -> persist Generated manifest
  -> persist Importing
  -> game-owned IGameGeneratedAssetImporter
  -> authoritative engine receipt
  -> persist Completed

The job binds its operation ID to the session, actor, game moment, asset type, generator, model, importer, and a fingerprint of the generation request. Reusing an operation ID with different semantics fails closed.

Generated bytes are stored before import. The included in-memory and file stores use SHA-256 content addressing and verify the ID, size, and hash when a resource is read. A custom resource materializer may download provider URLs, but it must enforce origin, redirect, size, MIME, decode, license, quota, and content-policy rules. The default materializer accepts only matching inline data: resources and never fetches a remote URL implicitly.

Job and resource stores intentionally do not guess when an asset is safe to delete. The host owns save references, archival policy, storage quotas, and garbage collection. Request, resource, and import metadata are durable records, so callers must place only persistence-safe, non-secret metadata in them.

Crash semantics

Generation and import are deliberately asymmetric:

Persisted state Meaning Safe next action
Prepared No provider request was recorded Start the operation
Generating or GenerationUncertain The provider may have accepted or charged the request Reconcile through provider-specific evidence, then call ResolveGenerationAsync; never submit blindly
Generated Valid resources and manifest are durable Start import
Importing or ImportUncertain The engine mutation may already have committed Call ResumeImportAsync; the importer must recover by stable operation ID
Completed An authoritative receipt is durable Reuse the completed result
Rejected or Failed Terminal outcome Inspect the bounded error/receipt and create a new operation only if the game chooses

Cancellation does not claim that a side effect did not happen. If cancellation or an exception occurs after dispatch, the pipeline settles to an uncertain state with an independent cancellation token so that the evidence survives the caller.

Authoritative engine import

Implement IGameGeneratedAssetImporter directly, or use GameGeneratedAssetActionImporter to bridge import into DurableGameActionDispatcher. The bridge sends a JSON manifest containing resource IDs, hashes, MIME types, names, and sizes—never the generated binary itself. The handler can read bytes from GameGeneratedAssetImportContext.Resources, validate game-specific rules, execute on the engine's required thread, mutate the save or world, and return a GameActionReceipt.

RecoverAsync is not an alternative execution path. It must query the engine or host receipt registry by ImportOperationId and return the outcome without repeating the mutation. The durable action bridge already applies that rule through its journal.

Minimal offline example

The buildable generated-assets example uses a deterministic one-pixel PNG, in-memory stores, and a durable fake engine importer, so it requires no API key or network connection:

dotnet run --project examples/OpenGameAgent.GeneratedAssets.Example/OpenGameAgent.GeneratedAssets.Example.csproj -c Release

Production local persistence is available through FileGameGeneratedAssetJobStore and FileGameGeneratedAssetResourceStore in OpenGameAgent.Persistence.

GameGeneratedAssetTool.Create exposes the pipeline as an ordinary non-idempotent Agent tool. Its request factory receives the current GameInput, parsed tool arguments, and ToolExecutionContext; the returned request must retain the same session and actor. Completed jobs return the durable manifest and import receipt as JSON. In-flight or uncertain generation/import states set ToolResult.OutcomeUncertain, preventing the tool loop from treating an unresolved write as a normal success.

Game-owned responsibilities

The framework supplies lifecycle coordination, bounds, persistence, integrity checks, and recovery contracts. The host still owns:

  • prompt and reference-data policy;
  • provider selection, credentials, cost limits, and moderation;
  • asset type and schema validation;
  • licensing and provenance records required by the product;
  • image/audio/video decoding and engine import;
  • main-thread scheduling, replication, save revisions, permissions, and quotas;
  • deterministic fallback when generation or import cannot be reconciled.

For an in-process Godot or Unity host, the importer can call engine APIs through the normal main-thread handoff. A sidecar or server deployment implements the same importer against its authenticated engine bridge or durable action exchange. The pipeline remains engine-neutral and never grants authority merely because a model generated an asset.