Structured Output and JSON Schema in Unreal Engine 5

Structured Output and JSON Schema in Unreal Engine 5

One of the biggest hurdles to using Generative AI in actual gameplay systems (rather than just raw text dialogue) is parsing the response. If you ask an LLM to generate a weapon, it might return a bulleted list, a paragraph, or pseudo-code. Writing regex parsers to handle that unpredictability is a nightmare for game developers.

Structured Output solves this entirely. By providing a JSON Schema to the API, you physically constrain the AI to output valid, perfectly formatted JSON that matches your exact data structures. No missing keys, no hallucinations outside the schema, no broken parsers.

Why Structured Output is Critical for Games

  • Procedural Loot Generation: Generate weapons with guaranteed 'damage', durability, and elemental_type fields.
  • Quest Systems: Generate quests with an array of objectives, a quest_title, and a gold_reward.
  • Character Stats: Roll an NPC with specific strength, intelligence, and an array of inventory_items.
  • Safe Deserialization: You can deserialize the AI's response directly into a UE5 Blueprint Struct or C++ USTRUCT without writing complex string parsing logic.

Implementing Structured Output in Unreal Engine 5

Using the GenAI for Unreal plugin, setting up Structured Output with OpenAI (like gpt-5.1) is straightforward.

1. Defining the JSON Schema

First, you define the "shape" of the data you want. Here is an example schema for an RPG character:

{
  "type": "object",
  "properties": {
    "name": {"type": "string", "description": "The character's name."},
    "level": {"type": "integer", "description": "The character's current level."},
    "health": {"type": "integer", "description": "The character's health points."},
    "skills": {
      "type": "array",
      "items": {"type": "string"},
      "description": "A list of unique skills."
    }
  },
  "required": ["name", "level", "health", "skills"]
}

2. Blueprint Implementation

Game designers can pass this schema directly into the Chat Settings node to enforce the output format.

// Blueprint Pseudocode
Make Gen OpenAI Chat Settings
  Model: gpt-5.1
  Response Format -> Json Object (Paste the Schema String here)

GenAI_ChatCompletion
  Prompt: "Generate a level 5 Goblin boss."
  
  OnCompleted(JSONString) -> 
    Use VaRest or built-in JsonBlueprintUtilities to parse JSONString into a UE5 Struct

3. C++ Implementation

In C++, you pass the schema string into the ResponseFormat property of the FGenOAIChatSettings struct. Once the response returns, you use Unreal's built-in FJsonSerializer to map it to your custom USTRUCT.

FGenOAIChatSettings ChatSettings;
ChatSettings.Model = EOpenAIChatModel::GPT_4o;
ChatSettings.ResponseFormat.JsonObject = JSONSchemaString; // Your schema from above

UGenOAIChat::SendChatRequest(ChatSettings, Messages,
    FOnChatCompletionResponse::CreateLambda([this](const FString& JSONResponse, const FString& Error, bool bSuccess)
    {
        if (bSuccess)
        {
            // Parse JSONResponse using TJsonReader and FJsonSerializer
            // Populate your custom FCharacterStats struct
        }
    })
);

Best Practices

When using Structured Output, keep the following in mind:

  • Provide clear descriptions: The description field in your JSON schema acts as a prompt for the AI. Use it to explain exactly what kind of values you want (e.g., "A number between 1 and 100").
  • Use the right models: OpenAI's gpt-5.1, gpt-5, and newer models natively enforce strict schema adherence.
  • Keep it focused: Don't ask for a massive, heavily nested JSON object if you only need a few variables. Smaller schemas generate faster and cost fewer tokens.