This page explains how .proto data types map to Blueprint types, and the settings needed to operate a game or app.
For the basic workflow, see the Quick Start.
Data type mapping
The data types in a .proto file are converted to the following Blueprint data types during import.
.proto type | Type created in Blueprint |
|---|---|
double | double |
float | float |
int32 / sint32 / sfixed32 | int32 |
int64 / sint64 / sfixed64 | int64 |
uint32 / fixed32 | int64 |
uint64 / fixed64 | int64. Very large values are limited |
bool | bool |
string | FString |
bytes | Byte array (TArray<uint8>) |
enum | User Defined Enum |
message | User Defined Struct |
repeated T | TArray<T> |
map<K,V> | An array of Structs with a Key and a Value |
uint32 is converted to int64 so Blueprint can handle the value without losing it. You can use the generated Struct as-is, so no additional conversion is required.
Numeric and Enum limitations
| Type or location | Range and notes |
|---|---|
uint32 / fixed32 | 0 to 2^32 - 1, stored as int64 |
uint64 / fixed64 | 0 to 2^63 - 1. Values of 2^63 and above cannot be stored in Blueprint’s int64 |
| Enum fields in generated Structs | 0 to 255 because of Blueprint’s Byte representation. Negative values and values of 256 or above cannot be stored |
Even if the Enum asset itself holds a value, passing it through a generated Struct field limits it to the Byte range. If the server-side definition uses values outside that range, adjust the schema or the way data is passed.
oneof
oneof lets you choose exactly one of several fields to send. The generated Struct contains a <oneof_name>_case field that indicates the selected field, plus fields for each value. When case is 0, nothing is selected.
When sending, choose the field to use in case and set a value in that field too. Fields that are not selected are not sent.
proto3 optional
optional distinguishes the state where a value is “not set”. The generated Struct contains a Boolean named bHas_<field> alongside the value. Set this Boolean to true when you want to send the value.
For example, even when the number is 0, a true Boolean means “0 was set”, while false means “nothing was set”.
| Value | bHas_<field> | What is sent to the server |
|---|---|---|
0 | true | Sends the value 0 as set |
0 | false | Does not send the field |
42 | true | Sends the value 42 |
42 | false | Does not send the field |
map
A .proto map becomes an array of Structs with a Key and a Value in Blueprint. Note that it is not a TMap.
If the same Key appears multiple times, the last Value is used. If you need to preserve array order or duplicate Keys, the server-side .proto design must use a regular array instead.
Special protobuf types
Timestamp and Duration can be treated as ordinary Structs, but they are not converted automatically to Blueprint date/time types. Convert seconds or nanoseconds to a date/time as needed.
google.protobuf.Any, FieldMask, and Struct/Value/ListValue do not have Blueprint-specific conversions. If you connect to a server that uses them, decide how to handle the data with the server owner or a programmer.
TLS and mTLS
TLS encrypts the data sent and received. Use TLS in games and apps that you publish. mTLS is a stricter connection method in which the connecting app, not just the server, presents a certificate.
General TLS connections
Use Make TLS Channel Config. Set Host to the server domain name registered in the certificate. If you do not know the correct Host name, ask the server administrator.
Using internal or self-signed certificates
Use Make TLS Custom Root Channel Config and set the PEM-format root certificate provided by the server administrator in RootCertificatePem. Ask the server administrator about the certificate to use.
mTLS
In addition to the TLS settings, set ClientCertificatePem and ClientPrivateKeyPem. Do not store private keys in Content Browser assets, Blueprint defaults, logs, or screenshots. Decide on a secure storage method with your project’s server or security owner.
Image coming soon: TLS/mTLS Channel Config
Image replacement marker
Expand Make OmniGrpc Channel Config and show the locations of Security, Root Certificate, Client Certificate, Client Private Key, and Authority Override. Use dummy or masked values for certificate bodies and private keys.
- Recommended filename
images/OmniGRPC/production-tls-config.png- Alt text
- OmniGRPC Channel Config for TLS and mTLS in Blueprint
Metadata
Metadata is additional information passed to the server separately from the normal Request. It is used for credentials, request identifiers, and similar data. You do not need to set it unless the server requires it.
To send a string, set a Key and a Value. To send a byte array, end the Key with -bin, set bIsBinary to true, and put the value in Binary Value.
You can send the same Key multiple times. To inspect all Metadata returned by the server, use InitialMetadataEntries and TrailerMetadataEntries.
An empty Key cannot be used. If you are sending an access token, the easiest approach is to set it in the Channel Config or Call Options Access Token instead of entering it manually in Metadata.
Timeouts, waiting for connections, and cancellation
| Setting or operation | Target | Behavior |
|---|---|---|
Timeout on the Call node | The entire single RPC | Sets the deadline in seconds. 0 or below means no time limit |
bWaitForReady = false | When the RPC starts | If the connection is temporarily failing, return an error without waiting for recovery |
bWaitForReady = true | When the RPC starts | Wait for recovery from a temporary connection failure. The RPC deadline still applies |
Wait for gRPC Channel Connected | Connection check before an RPC | Wait until Ready. Specify a positive Timeout Seconds |
Cancel | The running Action | Requests that the RPC be aborted |
Timeouts remain active even when waiting for a connection is enabled. To avoid waiting forever when the server cannot be reached, set a Timeout for calls started from button actions and similar user interactions.
Branch on the Success output of On Connected for the connection wait node. On failure, both On Timeout and On Connected(false) are called, so do not duplicate the failure handling.
Data compression and size limits
In the Channel settings, you can choose no compression, Deflate, or Gzip. This is useful for sending large data such as images, audio, or long text. Compression can add overhead for small data, so enable it only when needed.
MaxReceiveMessageBytes and MaxSendMessageBytes are the maximum sizes of data that can be received and sent at one time. Check them if you get a ResourceExhausted error with large data. Setting the limits too high uses more memory, so tune them together with the server-side settings.
| Item | Default | Meaning |
|---|---|---|
CompressionAlgorithm | None | No compression |
MaxReceiveMessageBytes | -1 | Use the standard gRPC receive limit (4 MiB) |
MaxSendMessageBytes | -1 | Use the standard gRPC send setting |
In this plugin, -1 means “do not change the gRPC setting”. To specify an explicit size, set the number of bytes.
Automatic retries and load balancing
Configuring a Retry Policy lets the plugin automatically retry communication when the server is temporarily unreachable. Set RetryPolicyServiceName to the fully qualified Service name including the package, such as acme.user.UserService.
| Item | Default or example | Meaning |
|---|---|---|
MaxAttempts | Default 1 | Number of attempts including the first. 1 disables retries |
InitialBackoff | 0.1s | Initial wait time. Specify a string with a unit |
MaxBackoff | 1s | Maximum wait time |
BackoffMultiplier | 2.0 | Factor that increases the wait time |
RetryableStatusCodes | Example: Unavailable | Error types to retry. Default is empty |
RetryPolicyServiceName | Example: acme.user.UserService | Required when MaxAttempts > 1 |
If you set a value in ServiceConfigJson, the JSON configuration takes precedence over the Struct’s Retry Policy.
Do not enable automatic retries without understanding how they work for calls where running the same operation twice causes problems, such as purchases or item grants.
Round Robin is an advanced setting that distributes communication across multiple servers in turn. It has no effect when Host contains only one IP address. If you use it, confirm the configuration with the server administrator.
Channel management
Reuse a Channel for communication with the same server. Creating a new Channel for every call increases the load from connection handling.
If you use the Channel across multiple Levels, save it in a variable that lives as long as needed, such as in the GameInstance. Close it when the game ends or when the destination changes. Also keep Client and Bidi Streaming Actions in variables while the call is active.
flowchart TD
Create[Create a Channel and save it to a variable] --> RPC[Run RPCs on the same Channel]
RPC --> More{"Continue communicating?"}
More -->|Yes| RPC
More -->|No| Active{"Any RPCs in progress?"}
Active -->|Cancel them| Cancel[Cancel each Action]
Active -->|Wait for normal completion| Wait[Wait for end events]
Active -->|None| Close[Close Channel]
Cancel --> Close
Wait --> Close
Close Channel does not abort RPCs that are in progress. The RPC keeps its internal connection until it finishes. If you no longer need the result after closing a screen, call Cancel on each Action.
Asynchronous Actions are kept alive automatically while they run. However, to call Send Message, Close Send, or Cancel later, you must save the Action to a variable. Clearing the Action variable alone does not cancel the call.
Supported platforms and notes
Support for all five platforms is a Full Edition feature. In the Full Edition, you can use the same .proto files, generated assets, and Call gRPC nodes to deploy to PC and mobile. The Free Edition supports only Windows (Win64).
| Platform | Support | Main checks |
|---|---|---|
| Windows | Win64 | Firewall and certificates |
| Linux | x86-64 (Full Edition) | Compatibility with the Linux environment you use |
| macOS | arm64 / x86_64 (Full Edition) | Supports Apple Silicon and Intel Macs. No per-CPU TargetArchitecture setting is required |
| Android | Supported (Full Edition) | Internet permission, route from the device to the destination, TLS |
| iOS | Supported (Full Edition) | ATS, app signing, route from the device to the destination, TLS |
Supported Unreal Engine versions are 5.6, 5.7, and 5.8. Choose the Fab package that matches the Engine version you use.
Troubleshooting
| Symptom or Code | What to check |
|---|---|
Unavailable | Host/Port, whether the server is running, firewall, VPN |
DeadlineExceeded | Whether the Timeout is too short, or whether the server operation is taking too long |
Unauthenticated | Whether a Token is set, or whether it has expired |
PermissionDenied | Whether the logged-in user has permission for the operation |
ResourceExhausted | Whether the data being sent or received exceeds the size limit |
| TLS connection failure | Host name, certificate expiration, configured root certificate, device date and time |
| Method not found | Service and Method selection, regeneration after changing the .proto file |
| Method candidates are empty | Select the node and check Method Name in Details. Check whether the Service can be resolved at edit time and whether the node matches the RPC type |
| Connection failure handling runs twice | Whether the same logic is connected to both On Timeout and On Connected(false) |
| RPC results still arrive after Close | Close Channel does not abort RPCs. Did you use the Action’s Cancel? |
| Request/Response pin types differ | Reselect the Service and Method, then Refresh or Compile the Blueprint |
| Client Streaming never completes | Was Close Send called at the end? |
| Reflection Import fails | Whether the server supports Reflection, the Service name, TLS, Timeout |
When a problem occurs, check the Code and Message in On Error, the Channel State, Host/Port, and the selected Service and Method. Do not include access tokens, passwords, or private keys in logs or screenshots.
Security checklist
- Use TLS instead of
Insecurein games and apps that you publish - Do not store access tokens, passwords, or private keys in logs or assets
- Set an appropriate Timeout for each call
- Design operations so automatic retries do not run the same work twice
- Do not set the send and receive size limits too high
- Test Android and iOS connections on real devices, not only in the Editor