Overview
BedrockAI connects Unreal Engine 4.27 and 5.8 to Amazon Bedrock. Characters keep a memory of what the player said, answer in their own voice, and can ask the game to run actions such as giving an item or opening a door. Requests run on background worker threads with automatic retries; every result arrives on the game thread.
- Send Message and Send Message Stream: whole replies or typewriter-style pieces, remembered by the conversation.
- Tool calls: Add Tool registers a game action with a JSON schema, Submit Tool Results returns what happened.
- Memory limited to the last messages, saved and restored with Get History As JSON and Load History From JSON.
- Ask and Ask Stream for one-shot text, Generate Image for images, Embed Text for vector search, Moderate Text for guardrails, Invoke Model Raw for any model-native API.
- You choose the model: any Bedrock model or inference profile with Converse support, per conversation or in the settings.
- Amazon Cognito identity pools for guests and signed-in players; static keys and the default AWS chain for development and servers.
Requirements
| Requirement | Details |
|---|---|
| Unreal Engine | 4.27 and 5.8 |
| Platforms | Win64, Linux and Android |
| Modules | BedrockAI (Runtime), BedrockAISdk (prebuilt AWS SDK for C++ 1.11.916 in Source/ThirdParty) |
| Dependencies | No other plugins. On Linux and Android the SDK uses the engine's libcurl, OpenSSL and certificate store. |
| AWS | An AWS account with Amazon Bedrock in your region and access enabled for the models you use. Bedrock and Cognito usage is billed by AWS. |
Installation
- Install BedrockAI from Fab into your engine, or copy the
BedrockAIfolder into your project'sPluginsfolder. - Enable BedrockAI in Edit > Plugins and restart the editor.
- Open Project Settings > Plugins > BedrockAI and set Region, Identity Pool Id and Default Model Id.
- C++ only: add
PublicDependencyModuleNames.Add("BedrockAI");to yourBuild.cs.
Setting up AWS
- Enable model access. In the Amazon Bedrock console of your region open Model access and request access to each model you use (for example Amazon Nova Lite, Nova Canvas and Titan Text Embeddings V2). Requests to a model without access fail with
AccessDeniedException. - Pick the model ids. Copy the model id (or, for models that require it, the cross-region inference profile id such as
us.amazon.nova-pro-v1:0) into the settings or a conversation's Model Id. - Create an identity pool. In Amazon Cognito create an identity pool. Enable guest access if players may talk to NPCs before signing in, and add your identity providers.
- Limit the pool's role. Give the IAM role of the pool (authenticated and/or guest) access only to the models and the guardrail your game uses. The Converse and ConverseStream APIs are authorized by
bedrock:InvokeModelandbedrock:InvokeModelWithResponseStream:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BedrockAIModels",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": [
"arn:aws:bedrock:us-east-1::foundation-model/amazon.nova-lite-v1:0",
"arn:aws:bedrock:us-east-1::foundation-model/amazon.nova-canvas-v1:0",
"arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v2:0"
]
},
{
"Sid": "BedrockAIGuardrail",
"Effect": "Allow",
"Action": "bedrock:ApplyGuardrail",
"Resource": "arn:aws:bedrock:us-east-1:123456789012:guardrail/abc123example"
}
]
}
Inference profiles need the profile ARN (arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.amazon.nova-pro-v1:0) plus the foundation-model ARNs of every region the profile routes to.
- Optional guardrail. Create a guardrail in the Bedrock console (content filters, denied topics, word filters, PII masking), publish a version and enter its id and version in the settings. BedrockAI then applies it to every conversation and Ask request, and Moderate Text can check player names and chat.
DefaultGame.ini and in packaged games. Use them only for development and dedicated servers; players should always use the identity pool. Shipping builds refuse settings keys unless Allow Static Keys In Shipping is enabled.Cost and abuse
- Use a guardrail (Guardrail Id in the settings) for every player-facing conversation; check player names and chat with Moderate Text.
- Keep Max Tokens and Max History Messages low, and choose a small model where it is good enough.
- Allow only the models you need in the identity pool role, and set AWS budgets and Bedrock quotas with alarms.
- Rate-limit in your game (for example one message per NPC every few seconds) and never let tool calls do more than the player could do anyway: validate every tool input in game code.
- For public games, prefer routing requests through your own backend (for example a Lambda function behind authenticated API Gateway) where you can enforce per-player limits, instead of giving every client direct model access.
Quick start
One question
- Add Ask to an Event Graph with Prompt
Describe a rusty old key in one sentence. - From On Response, print Text. Usage shows the tokens billed.
- From On Failure, print Error > Message; Error > Code says why.
Images and embeddings
Generate Image returns a texture you can put on a widget brush or material, plus the PNG bytes to save. Embed Text turns text into a vector; store the vectors of your lore entries once, embed the player's question, and pick the entry with the highest Cosine Similarity.
NPC with memory and a tool
- On BeginPlay call Create Conversation with System Prompt
You are Mira, a blacksmith in Oakvale. You may give the player one free item, and only once.Store the result in a variable MiraChat. - Call Add Tool on MiraChat: Name
give_item, DescriptionGives an item to the player. Use only when Mira decides to hand something over., Input Schema Json:
{"type":"object","properties":{"item":{"type":"string","enum":["iron_sword","health_potion"]}},"required":["item"]}
- When the player talks, call Send Message Stream with MiraChat and the player's text; append each On Delta piece to the dialogue box.
- On Tool Use: loop over Tool Calls. For Name
give_item, parse Input Json (for example with your JSON plugin or a string search for the item), check that the player has not received an item yet, add it to the inventory and build a Tool Result with the same Tool Use Id and Result Json{"given":true,"item":"iron_sword"}(or{"given":false,"reason":"already received"}with Is Error off, so Mira can explain). - Call Submit Tool Results with MiraChat and the results. Its On Response carries Mira's in-character answer ("Here, take this sword...").
- On save, store Get History As JSON in the save game; on load, call Load History From JSON.
Latent nodes
All latent nodes run in the background, can be stopped with Cancel on their return value and fire exactly one final pin on the game thread. A conversation runs one request at a time.
| Node | Inputs | Outputs | Description |
|---|---|---|---|
| Send Message | Conversation, Text | On Response (Text, Stop Reason, Usage) / On Tool Use (Tool Calls) / On Failure (Error) | One conversation turn with Converse. The player message and the reply are added to the conversation's memory. On Tool Use fires instead of On Response when the model wants game actions to run. |
| Send Message Stream | Conversation, Text | On Delta (Text Piece), On Tool Use / On Complete (Full Text, Stop Reason, Usage) / On Failure | Same turn with ConverseStream: On Delta fires for every piece of the reply as it is generated (UTF-8 safe), ideal for typewriter dialogue. |
| Submit Tool Results | Conversation, Results | Same pins as Send Message | Sends the outcome of the calls from On Tool Use back to the model and continues the turn. Calls without a matching result are reported to the model as failed. |
| Ask | Prompt, System Prompt, Model Id | On Response / On Failure | One-shot Converse request without a conversation; nothing is remembered. Item descriptions, quest text, names, hints. |
| Ask Stream | Prompt, System Prompt, Model Id | On Delta, On Complete / On Failure | One-shot request whose reply arrives piece by piece. |
| Generate Image | Prompt, Negative Prompt, Width, Height, Seed, Model Id | On Success (Texture, Png Bytes) / On Failure | Text-to-image with the TEXT_IMAGE request body of Amazon Nova Canvas and Titan Image Generator models. The PNG is decoded on a worker thread; the transient texture is created on the game thread. Seed -1 = random. |
| Embed Text | Text, Model Id | On Success (Embedding) / On Failure | Embedding vector with the Amazon Titan Text Embeddings request body. Compare vectors with Cosine Similarity. |
| Moderate Text | Text, Source (Input / Output) | On Success (Blocked, Action, Output Text) / On Failure | ApplyGuardrail with the guardrail from the settings. Output Text is what to show (masked, or the guardrail's blocked message). |
| Invoke Model Raw | Model Id, Body Json | On Success (Response Json) / On Failure | InvokeModel with any model-native JSON body, for models or features the other nodes do not cover. |
| Resolve Identity | Force Refresh | On Success / On Failure (Identity Id, Error) | Fetches the Cognito identity and temporary credentials now, for example right after login. |
Stop Reason is the Bedrock value: end_turn, tool_use, max_tokens, stop_sequence, guardrail_intervened or content_filtered. Exchanges stopped by a guardrail or content filter are not added to the memory.
Conversations
| Node | Inputs | Description |
|---|---|---|
| Create Conversation | Model Id, System Prompt | Creates a conversation (one per NPC) with the settings' default temperature and max tokens. Store it in a variable. |
| Add Tool | Name, Description, Input Schema Json | Registers a game action the model may call. Same name again = replace. Returns false for an invalid name or schema. |
| Clear History | Forgets every message; tools and settings stay. A reply still on its way is not added. | |
| Get History As JSON | The memory as JSON for a save game. | |
| Load History From JSON | Json | Restores the memory; returns false and keeps the old history when the JSON is invalid. |
| Get Last Reply | Text of the model's last message, including text written before a tool call. |
Properties
| Property | Default | Description |
|---|---|---|
| Model Id | (empty) | Model id or inference profile; empty = Default Model Id. |
| System Prompt | (empty) | Who the character is; empty = Default System Prompt. |
| Temperature | settings | 0 = focused, 1 = creative. |
| Max Tokens | settings | Reply length limit. |
| Max History Messages | 20 | Oldest exchanges are dropped first; a tool call always stays with its result. 0 = unlimited. |
Requests copy the conversation on the game thread before they start, and the reply is added on the game thread when it arrives, so a conversation is never touched by a worker thread.
Functions
| Node | Description |
|---|---|
| Cosine Similarity | Similarity of two embedding vectors: 1 = same meaning, 0 = unrelated. |
| Set Region | Switches the AWS region for every following request. |
| Set Credential Mode | Overrides the credential mode from the settings at runtime. |
| Set Login Token | Signs the player in to the identity pool with a provider token (Cognito user pool, Google, Apple, Facebook, OpenID). |
| Clear Login Tokens | Forgets all login tokens and the cached identity; the player becomes a guest. |
| Set Static Credentials | Uses the given keys from now on (Static Keys mode), for example temporary keys handed out by your backend. |
| Get Identity Id | The player's Cognito identity id; empty until credentials were resolved once. |
| Make User Pool Provider Name | Builds the login key of a Cognito user pool: cognito-idp.<region>.amazonaws.com/<pool id>. |
| Is Configured | Returns false and a reason when the settings are incomplete. |
| Cancel | On a latent node's return value: none of its pins fire any more. |
| Is Finished | On a latent node's return value: true after it finished or was cancelled. |
Credentials
| Mode | Use for | How |
|---|---|---|
| Cognito Identity Pool | Game clients | Guests get unauthenticated credentials; after Set Login Token the player gets the authenticated role. Credentials refresh automatically before they expire. |
| Static Keys | Development, dedicated servers, keys from your backend | Settings keys or Set Static Credentials (with an optional session token). |
| Default Credential Chain | Servers and tools | Environment variables, the ~/.aws profile, ECS and EC2 instance roles. |
Signed-in players: for a Cognito user pool call Set Login Token with Provider = Make User Pool Provider Name and Token = the ID token. Other providers use their pool login keys (accounts.google.com, appleid.apple.com, graph.facebook.com).
C++ API
// Build.cs: PublicDependencyModuleNames.Add("BedrockAI");
#include "BedrockAILibrary.h"
UBedrockAILibrary::AskNative(TEXT("Name a cursed sword."), FString(), FString(),
FBedrockAINativeDelegate::CreateLambda([](const FString& Text, const FBedrockAIUsage& Usage, const FBedrockAIError& Error)
{
// runs on the game thread; Error.Code is empty on success
}));
// Latent nodes from C++: create the action, bind its delegates, then Activate().
UBedrockAIChatAction* Action = UBedrockAIChatAction::SendConversationMessage(this, Conversation, TEXT("Hello"));
Action->OnResponse.AddDynamic(this, &AMyNpc::HandleReply);
Action->Activate();
UBedrockAIConversation also offers GetMessages(), GetTools(), IsBusy() and GetPendingToolCalls() for game code.
Types
| Type | Kind | Members |
|---|---|---|
| UBedrockAIConversation | Object | Model Id, System Prompt, Temperature, Max Tokens, Max History Messages; tools and history (internal) |
| FBedrockAIToolCall | Struct | Tool Use Id, Name, Input Json |
| FBedrockAIToolResult | Struct | Tool Use Id, Result Json, Is Error |
| FBedrockAIUsage | Struct | Input Tokens, Output Tokens, Latency Ms |
| FBedrockAIError | Struct | Code, Message, Http Status, Retryable |
| EBedrockAIGuardrailSource | Enum | Input (Player Text), Output (Model Text) |
| EBedrockAICredentialMode | Enum | Cognito Identity Pool, Static Keys, Default Credential Chain |
Settings
Project Settings > Plugins > BedrockAI (saved to DefaultGame.ini). Changes apply to the next request.
| Setting | Default | Description |
|---|---|---|
| Region | us-east-1 | Region of the Bedrock models and the identity pool. |
| Credential Mode | Cognito Identity Pool | Cognito Identity Pool, Static Keys or Default Credential Chain. |
| Identity Pool Id | (empty) | For example us-east-1:01234567-89ab-cdef-0123-456789abcdef. |
| Allow Guest Access | On | Unauthenticated identities before Set Login Token. The pool must allow guest access too. |
| Access Key Id / Secret Access Key | (empty) | Static Keys mode. Saved in DefaultGame.ini - development and servers only. |
| Allow Static Keys In Shipping | Off | Static keys from the settings are refused in Shipping builds unless enabled (dedicated servers). |
| Endpoint Override | (empty) | Custom endpoint, for example a VPC endpoint. |
| Request Timeout Ms / Connect Timeout Ms | 60000 / 5000 | Time limits per request. Long replies and images can take tens of seconds. |
| Max Retries | 3 | Automatic retries with exponential back-off for throttling and transient errors. |
| Worker Threads | 4 | Background threads that run requests. |
| Verify SSL | On | Only disable for a local test endpoint. |
| Log Sdk Warnings | On | Forwards SDK warnings and errors to LogBedrockAI. |
| Default Model Id | amazon.nova-lite-v1:0 | Any model or inference profile with Converse support, for example us.amazon.nova-pro-v1:0. Pick what fits your quality, latency and price needs. |
| Default Image Model Id | amazon.nova-canvas-v1:0 | Used by Generate Image (Nova Canvas / Titan Image Generator request body). |
| Default Embedding Model Id | amazon.titan-embed-text-v2:0 | Used by Embed Text (Titan Text Embeddings request body). |
| Default Max Tokens | 512 | Reply limit for new conversations and Ask. |
| Default Temperature | 0.7 | Randomness for new conversations and Ask. |
| Default System Prompt | a short in-character instruction | Used when a conversation or Ask has no system prompt. |
| Guardrail Id / Guardrail Version | (empty) / DRAFT | Optional Bedrock guardrail applied to every conversation and Ask request (GuardrailConfiguration) and used by Moderate Text. |
Troubleshooting
| Error code | Cause and fix |
|---|---|
NotConfigured | Set Identity Pool Id and Default Model Id in Project Settings > Plugins > BedrockAI (Moderate Text also needs Guardrail Id). |
AccessDeniedException | Model access is not enabled for that model in the Bedrock console, or the identity pool role lacks bedrock:InvokeModel / InvokeModelWithResponseStream on its ARN (see Setting up AWS). |
ValidationException | The model does not support Converse or tool use, a parameter is out of range (image size, max tokens), or the model id is wrong for the region. Some models need an inference profile id such as us.amazon.nova-pro-v1:0. |
ResourceNotFoundException | Unknown model or guardrail id in this region. |
ThrottlingException / ServiceQuotaExceededException | Too many requests or tokens per minute. Error.Retryable is true; slow down or request a quota increase. |
Busy | The conversation still waits for a reply. Wait for the node to finish or use another conversation. |
NoPendingToolUse | Submit Tool Results was called although the model did not ask for a tool call. |
Unavailable | The SDK library could not be loaded or the engine is shutting down. Check the Output Log for LogBedrockAI errors. |
Credits
© 2026 Alpha XP — alphaxp.net · Support: support@alphaxp.net. Includes the AWS SDK for C++ and the AWS Common Runtime (Apache License 2.0). Amazon Bedrock, Amazon Nova, Amazon Titan and Amazon Cognito are services of Amazon Web Services; model use is subject to the AWS terms and each model's own terms. Built for Unreal Engine 4.27 and 5.8.