Plugin Documentation

AthenaQuery
SQL on your game data, inside the editor

Run Amazon Athena queries on the analytics data your game writes to Amazon S3, straight from the Unreal Editor: a query tab with a results grid, 80 Editor Utility nodes, and results to CSV, JSON or DataTable assets.

v1.0
UE 4.27 & 5.8
Windows editor (Win64)
Editor-only
80 Blueprint nodes
Alpha XP

Overview

Most games already send telemetry, economy events and match results to S3 (for example through Amazon Data Firehose). Amazon Athena queries those files with standard SQL, without servers. AthenaQuery puts Athena into the editor so the people who balance the game can look at real player data and turn it into game data.

  • Athena Query tab (Window > Tools > Alpha XP > Athena Query): SQL editor, Run / Stop, workgroup and database pickers, results grid, Export CSV, Save As DataTable.
  • Run Query And Wait: start, poll with back-off, download every page; Cancel stops the query on Athena.
  • Run Query To Data Table and Create DataTable From Results: columns mapped to row-struct fields by name.
  • Catalog browsing, query history, named queries, prepared statements.
  • Result helpers (typed cells, filter, sort, aggregate, CSV / JSON) and SQL helpers (escaping, query builders, partition filters).
  • Named AWS profiles including IAM Identity Center (SSO), the default chain, static keys or Cognito; Get Caller Identity.

Requirements

RequirementDetails
Unreal Engine4.27 and 5.8
PlatformsWindows editor (Win64). Editor-only: nothing is added to packaged games.
ModulesAthenaQuery (Editor), AthenaQuerySdk (prebuilt AWS SDK for C++ 1.11.916 in Source/ThirdParty)
DependenciesNo other plugins.
AWSAn AWS account with data in S3 and a table in the AWS Glue Data Catalog. Athena bills per TB scanned (10 MB minimum per query); results are stored in S3.

Installation

  1. Install AthenaQuery from Fab into your engine, or copy the AthenaQuery folder into your project's Plugins folder.
  2. Enable AthenaQuery in Edit > Plugins and restart the editor.
  3. Open Project Settings > Plugins > AthenaQuery: set Region, Credential Mode (Named Profile with a Profile Name, or Default Credential Chain), Default Database and, unless your workgroup defines one, Default Output Location (s3://my-athena-results/editor/).
  4. C++ only: add PrivateDependencyModuleNames.Add("AthenaQuery"); to an editor module's Build.cs.
Several AWS plugins in one projectEach Alpha XP cloud plugin carries its own copy of the SDK under a plugin-specific name, so they install side by side without conflicts.

Setting up AWS

  1. Have your game data in S3 (JSON, Parquet or CSV), ideally partitioned by date, for example s3://my-game-telemetry/events/year=2026/month=10/day=28/.
  2. Create the table: run a Glue crawler, or a CREATE EXTERNAL TABLE ... PARTITIONED BY (year string, month string, day string) statement in the Athena Query tab.
  3. Create an S3 bucket (or prefix) for query results and set it as the workgroup's result location or as Default Output Location.
  4. Give the IAM user or role of your AWS profile a least-privilege policy like this one (replace region, account, buckets and database):
{
  "Version": "2012-10-17",
  "Statement": [
    { "Sid": "Athena", "Effect": "Allow",
      "Action": ["athena:StartQueryExecution", "athena:GetQueryExecution", "athena:GetQueryResults", "athena:StopQueryExecution",
                 "athena:ListQueryExecutions", "athena:BatchGetQueryExecution", "athena:GetWorkGroup", "athena:ListWorkGroups",
                 "athena:ListDataCatalogs", "athena:ListDatabases", "athena:GetDatabase", "athena:ListTableMetadata", "athena:GetTableMetadata",
                 "athena:CreateNamedQuery", "athena:GetNamedQuery", "athena:ListNamedQueries", "athena:BatchGetNamedQuery",
                 "athena:UpdateNamedQuery", "athena:DeleteNamedQuery",
                 "athena:CreatePreparedStatement", "athena:GetPreparedStatement", "athena:ListPreparedStatements",
                 "athena:BatchGetPreparedStatement", "athena:UpdatePreparedStatement", "athena:DeletePreparedStatement"],
      "Resource": ["arn:aws:athena:us-east-1:123456789012:workgroup/primary",
                   "arn:aws:athena:us-east-1:123456789012:datacatalog/AwsDataCatalog"] },
    { "Sid": "ListWorkGroups", "Effect": "Allow", "Action": ["athena:ListWorkGroups", "athena:ListDataCatalogs"], "Resource": "*" },
    { "Sid": "Glue", "Effect": "Allow",
      "Action": ["glue:GetDatabase", "glue:GetDatabases", "glue:GetTable", "glue:GetTables", "glue:GetPartition", "glue:GetPartitions"],
      "Resource": ["arn:aws:glue:us-east-1:123456789012:catalog",
                   "arn:aws:glue:us-east-1:123456789012:database/game_analytics",
                   "arn:aws:glue:us-east-1:123456789012:table/game_analytics/*"] },
    { "Sid": "ReadGameData", "Effect": "Allow", "Action": ["s3:GetObject", "s3:ListBucket", "s3:GetBucketLocation"],
      "Resource": ["arn:aws:s3:::my-game-telemetry", "arn:aws:s3:::my-game-telemetry/*"] },
    { "Sid": "WriteResults", "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket", "s3:GetBucketLocation", "s3:AbortMultipartUpload", "s3:ListMultipartUploadParts"],
      "Resource": ["arn:aws:s3:::my-athena-results", "arn:aws:s3:::my-athena-results/*"] }
  ]
}

Read-only analysts can drop the Create / Update / Delete actions. DDL statements (CREATE TABLE, ALTER TABLE ADD PARTITION, MSCK REPAIR) additionally need glue:CreateTable, glue:UpdateTable, glue:BatchCreatePartition and similar. Get Caller Identity needs no permission.

Cost controlAthena bills the data each query scans. Filter on partition columns (Make Partition Filter), prefer columnar formats (Parquet), set a per-query data limit on the workgroup and enable Result Reuse Max Age Minutes while you iterate.

Quick start

In the tab

  1. Window > Tools > Alpha XP > Athena Query. Press Refresh Lists, pick the workgroup and database.
  2. Enter SELECT event_name, count(*) AS events FROM game_events WHERE year = '2026' AND month = '10' GROUP BY 1 ORDER BY 2 DESC LIMIT 20 and press Run.
  3. The status line shows the state, rows, data scanned, estimated cost and time. Export CSV... saves the grid; Save As DataTable writes it into a DataTable asset.

In an Editor Utility Widget

  1. Add Run Query And Wait; Sql = your query, Options = Get Default Query Options (or a Make struct with Database set).
  2. From On Succeeded, read values with Get Cell As Float / Get Column Values, or show them with Results To CSV.
  3. From On Failed, print Error > Message (for a failed query: the Athena error, for example a syntax error with its line and column).
  4. For a "Refresh balance data" button use Run Query To Data Table with your row struct and /Game/Data/Balance + DT_WeaponStats.

Athena Query tab

  • Workgroup / Database: start with the settings defaults; Refresh Lists loads the enabled workgroups and the databases of the default catalog.
  • Run: several statements separated by ; run one after another; the grid shows the last result. Comments are removed before sending. Statements that are not read-only ask for confirmation first (setting Confirm Non Read Only Queries).
  • Stop: stops the query on Athena. Closing the tab stops a running query too.
  • Results grid: one column per result column (hover the header for its type); NULL cells show as grey NULL. Up to Max Result Rows rows are downloaded.
  • Export CSV...: RFC 4180 CSV, UTF-8. Save As DataTable: enter the row struct path (/Script/MyGame.WeaponRow for C++, /Game/Data/S_WeaponRow.S_WeaponRow for a Blueprint struct), the asset path and optionally the row name column.
  • Blueprints can drive the tab: Open Query Editor, Set Query Editor Sql (optionally run), Get Query Editor Sql, Get Last Editor Results.

DataTables from results

Create DataTable From Results and Run Query To Data Table fill a DataTable whose rows use any struct derived from FTableRowBase (C++ or a Blueprint struct):

  • Columns map to fields by name, ignoring case, spaces, dashes and underscores: player_id fills PlayerId, damage per second fills DamagePerSecond.
  • Strings, names and texts are copied; numbers, bools, enums (value names), date times (Athena date / timestamp) and other types are converted from text. NULL cells keep the struct default.
  • The row name comes from Row Name Column (duplicates get _2, _3...) or is Row_0, Row_1...
  • An existing table is updated: all rows are replaced and the row struct is set. A new asset is created and registered. With Save the package is saved to disk.
  • Report lists mapped columns, columns without a field and fields without a column.

Node reference (80 nodes)

Latent nodes run in the background and fire exactly one final pin on the game thread; stop them with Cancel on their return value. Empty Workgroup / Catalog / Database inputs use the settings defaults.

Queries

NodeKindInputsOutputsPurpose
Run Query And WaitLatentSql, Options, Timeout SecondsOn Progress (Execution), On Succeeded / On Failed (Execution, Results, Error)Start, poll with back-off, download all pages up to Max Rows; Cancel or a timeout stops the query.
Start Query ExecutionLatentSql, OptionsOn Success / On Failure (Id, Error)Starts a query and returns its Query Execution Id at once.
Wait For QueryLatentQuery Execution Id, Fetch Results, Max Rows, Timeout Seconds, Stop On CancelOn Progress, On Succeeded / On Failed (Execution, Results, Error)Follows an already started query until it ends.
Get Query ExecutionLatentQuery Execution IdOn Success / On Failure (Execution, Error)State, failure reason, data scanned, engine / queue / planning time, output location.
Stop Query ExecutionLatentQuery Execution IdOn Success / On Failure (Error)Cancels a queued or running query.
Get Query ResultsLatentQuery Execution Id, Next Token, Max ResultsOn Success / On Failure (Results, Next Token, Error)One page (up to 1000 rows) with typed column info; the header row is removed.
List Query ExecutionsLatentWork Group, Max Results, Next Token, Include DetailsOn Success / On Failure (Executions, Unprocessed Ids, Next Token, Error)Query history of a workgroup, newest first.
Batch Get Query ExecutionLatentQuery Execution IdsOn Success / On Failure (Executions, Unprocessed Ids, Next Token, Error)Details of many executions (batches of 50).

Catalog

NodeKindInputsOutputsPurpose
List Data CatalogsLatentWork Group, All Pages, Next Token, Max ResultsCatalogs, Next Token, ErrorGlue, federated, Lambda and Hive catalogs.
List DatabasesLatentCatalog, Work Group, All Pages, Next Token, Max ResultsDatabases, Next Token, ErrorDatabases (schemas) of a catalog.
Get DatabaseLatentDatabase, Catalog, Work GroupDatabase, ErrorDescription and parameters of one database.
List Table MetadataLatentDatabase, Expression, Catalog, Work Group, All Pages, Next Token, Max ResultsTables, Next Token, ErrorTables and views with columns and partition keys; Expression filters names (events_*).
Get Table MetadataLatentTable, Database, Catalog, Work GroupTable, ErrorColumns, partition keys, types and table properties.
List Work GroupsLatentAll Pages, Next Token, Max ResultsWork Groups, Next Token, ErrorWorkgroups of the account in the region.
Get Work GroupLatentWork GroupWork Group, ErrorOutput location, enforcement, per-query scan limit, engine version.

Named queries and prepared statements

NodeKindInputsOutputsPurpose
Create Named QueryLatentName, Sql, Database, Description, Work GroupId, ErrorSaves a query (console "Saved queries").
Get Named QueryLatentNamed Query IdNamed Query, ErrorName, description, database and SQL.
List Named QueriesLatentWork Group, Include DetailsNamed Queries, ErrorAll saved queries of a workgroup.
Update Named QueryLatentNamed Query Id, Name, Sql, DescriptionErrorRenames and replaces the SQL.
Delete Named QueryLatentNamed Query Id, ConfirmErrorDeletes; does nothing unless Confirm is true.
Create Prepared StatementLatentStatement Name, Sql, Work Group, DescriptionErrorSQL with ? placeholders, stored in the workgroup.
Get Prepared StatementLatentStatement Name, Work GroupStatement, ErrorSQL, description, last change.
List Prepared StatementsLatentWork Group, Include DetailsStatements, ErrorAll prepared statements of a workgroup.
Update Prepared StatementLatentStatement Name, Sql, Work Group, DescriptionErrorReplaces the SQL.
Delete Prepared StatementLatentStatement Name, Work Group, ConfirmErrorDeletes; does nothing unless Confirm is true.
Execute Prepared StatementLatentStatement Name, Parameters, Options, Timeout SecondsOn Progress, On Succeeded / On Failed (Execution, Results, Error)Runs EXECUTE name with values for the placeholders and waits for the results.

Results

NodeKindInputsOutputsPurpose
Run Query To Data TableLatentSql, Row Struct, Package Path, Asset Name, Row Name Column, Options, Save, Timeout SecondsOn Progress, On Succeeded / On Failed (Data Table, Execution, Report, Error)Query and DataTable in one node.
Create DataTable From ResultsCallableResults, Row Struct, Package Path, Asset Name, Row Name Column, SaveData Table, ReportCreates or updates a DataTable asset (see DataTables).
Results To CSVPureResults, Include HeaderCSV textRFC 4180 CSV.
Save Results As CSVCallableResults, File Path, Include HeaderSaved Path, successWrites a UTF-8 CSV; empty File Path opens a Save dialog.
Load Results From CSVCallableFile PathResults, successReads a CSV (first line = column names); empty path opens a dialog.
Results To JSONPureResults, Typed, PrettyJSON textArray of row objects; typed numbers / bools / null.
Get Column NamesPureResultsNamesColumn names in order.
Get Column IndexPureResults, Column NameIndexCase-insensitive lookup, -1 when missing.
Get Column ValuesPureResults, Column NameValuesOne column as a string array.
Get CellPureResults, Row Index, Column NameValue, successCell text.
Get Cell As FloatPureResults, Row Index, Column NameValue, successNumeric cell.
Get Cell As Integer64PureResults, Row Index, Column NameValue, successbigint / integer cell.
Get Cell As BoolPureResults, Row Index, Column NameValue, successtrue/false, 1/0, yes/no.
Get Cell As Date TimePureResults, Row Index, Column NameValue, successdate / timestamp cell (UTC).
Is Cell NullPureResults, Row Index, Column NameboolSQL NULL check.
Get Row As MapPureResults, Row IndexMapColumn name to value (NULLs left out).
Find Rows WherePureResults, Column Name, Compare, ValueResultsLocal filter: equals, contains, greater than, is null...
Sort Results By ColumnPureResults, Column Name, DescendingResultsNumbers numerically, text case-insensitively, NULL last.
Select ColumnsPureResults, Column NamesResultsSubset and reorder columns.
Append ResultsPureA, BResultsRows of B after A, columns matched by name.
Aggregate ColumnPureResults, Column Name, AggregatefloatSum, average, min, max, count, count distinct.
Estimate Query CostPureData Scanned Bytes, Price Per Terabyte UsdUSDWhole MB, 10 MB minimum, times the price per TB.
Format BytesPureBytesText"3.4 MB".
Format DurationPureMillisecondsText"12.4 s", "3 min 05 s".
Is Terminal StatePureStateboolSucceeded, Failed or Cancelled.

SQL helpers

NodeKindInputsOutputsPurpose
Escape SQL StringPureValueLiteralO'Brien to 'O''Brien'.
Quote IdentifierPureNameIdentifier"player id"; dots split db.table.
Make Select QueryPureTable, Columns, Where, Order By, LimitSQLSELECT builder.
Make Aggregate QueryPureTable, Group By Columns, Aggregates, Where, Order By, LimitSQLGROUP BY builder.
Make Partition FilterPureFrom, To, Date Column, Year / Month / Day Column, String Partitions, Max DaysSQL predicateDate range on year/month/day partitions (or one date column) so Athena scans only those days.
Make In ListPureColumn, Values, NumericSQL predicatecol IN ('a', 'b'), escaped.
Make Timestamp LiteralPureTimeSQL literalTIMESTAMP '2026-10-28 14:05:00.000'.
Is Read Only QueryPureSqlboolSELECT / WITH / SHOW / DESCRIBE / EXPLAIN / VALUES.
Split SQL StatementsPureSqlStatementsSplits at ; outside quotes; comments removed.
Make S3 LocationPureBucket, PrefixTexts3://bucket/prefix/.

Config, identity and editor

NodeKindInputsOutputsPurpose
Set RegionCallableRegion-Region for every following request.
Set Credential ModeCallableMode-Overrides the settings for this session.
Set ProfileCallableProfile Name-Uses a named AWS profile; empty = default chain.
List ProfilesCallable-NamesProfiles in ~/.aws/credentials and ~/.aws/config.
Set Login TokenCallableProvider, Token-Cognito identity pool sign-in.
Clear Login TokensCallable--Forgets login tokens and the cached identity.
Set Static CredentialsCallableAccess Key Id, Secret Access Key, Session Token-Temporary keys for this session (not saved).
Get Identity IdPure-Identity IdCognito identity (Cognito mode).
Make User Pool Provider NamePureRegion, User Pool IdProvidercognito-idp.<region>.amazonaws.com/<pool id>.
Is ConfiguredPure-bool, ProblemFalse with a reason when the settings are incomplete.
Get Default Query OptionsPure-OptionsThe defaults empty fields resolve to.
Resolve IdentityLatentForce RefreshIdentity Id, ErrorResolves the credentials now (errors show up early).
Get Caller IdentityLatent-Identity (Account, Arn, User Id), ErrorAWS STS Get Caller Identity: which account and principal the editor uses.
Open Query EditorCallable--Opens the Athena Query tab.
Set Query Editor SqlCallableSql, Run Now-Puts SQL into the tab (opening it), optionally runs it.
Get Query Editor SqlPure-SqlThe SQL in the tab.
Get Last Editor ResultsCallable-Results, Execution, successThe results last shown in the tab.
CancelCallable(latent node)-None of its pins fire any more; wait nodes stop their query on Athena.
Is FinishedPure(latent node)boolTrue after it finished or was cancelled.

Credentials

ModeUse forHow
Default Credential Chain (default)Most teamsEnvironment variables, the default (or AWS_PROFILE) profile, SSO, credential_process, container / instance roles.
Named ProfileSeveral AWS accountsProfile Name in the settings or Set Profile. Works with static-key, IAM Identity Center (SSO; run aws sso login --profile name first), assume-role and credential_process profiles.
Static KeysQuick testsSettings keys (stored in your per-user editor settings) or Set Static Credentials.
Cognito Identity PoolShared tool accountsIdentity Pool Id plus Set Login Token.

C++ API

// Build.cs (editor module): PrivateDependencyModuleNames.Add("AthenaQuery");
#include "AthenaQueryLibrary.h"

FAthenaQueryOptions Options;
Options.Database = TEXT("game_analytics");
UAthenaQueryLibrary::RunQueryNative(TEXT("SELECT count(*) AS players FROM sessions"), Options,
    FAthenaQueryNativeDelegate::CreateLambda([](const FAthenaQueryExecution& Execution, const FAthenaQueryResults& Results, const FAthenaQueryError& Error)
    {
        // runs on the game thread
    }));

The latent node classes can also be created from C++ through their static factory functions; bind the delegates, then call Activate(). UAthenaQueryResultsLibrary and UAthenaQuerySqlLibrary are plain static functions.

Types

TypeKindMembers
FAthenaQueryOptionsStructDatabase, Catalog, Work Group, Output Location, Execution Parameters, Result Reuse Max Age Minutes (0 = settings, -1 = never), Max Rows
FAthenaQueryExecutionStructQuery Execution Id, Query, State, Statement Type, State Change Reason, Error Message / Category / Type, Submission / Completion Time, Data Scanned Bytes, Engine / Queue / Planning / Total Time Ms, Reused Previous Result, Output Location, Database, Catalog, Work Group, Engine Version, Execution Parameters
FAthenaQueryResultsStructQuery Execution Id, Columns (Name, Label, Type, Nullable, Precision, Scale), Rows (Values, Null Columns), Update Count, Truncated
FAthenaQueryTableStructName, Table Type, Create / Last Access Time, Columns, Partition Keys, Parameters
FAthenaQueryWorkGroupStructName, Description, Enabled, Creation Time, Engine Version, Output Location, Enforce Configuration, Bytes Scanned Cutoff Per Query, Publish CloudWatch Metrics, Requester Pays
FAthenaQueryDataCatalog / Database / NamedQuery / PreparedStatement / CallerIdentityStructAs listed by the matching nodes
FAthenaQueryErrorStructCode, Message, Http Status, Retryable
EAthenaQueryStateEnumUnknown, Queued, Running, Succeeded, Failed, Cancelled
EAthenaQueryCompare / EAthenaQueryAggregate / EAthenaQueryCredentialModeEnumFind Rows Where comparisons, Aggregate Column functions, credential modes

Settings

Project Settings > Plugins > AthenaQuery, saved per user (Saved/Config/.../EditorPerProjectUserSettings.ini), never in the shared project config. Changes apply to the next request.

SettingDefaultDescription
Regionus-east-1Region of your workgroup and data.
Credential ModeDefault Credential ChainDefault chain, Named Profile, Static Keys or Cognito Identity Pool.
Profile Name(empty)Named Profile mode.
Identity Pool Id / Allow Guest Access(empty) / OnCognito mode.
Access Key Id / Secret Access Key(empty)Static Keys mode.
Endpoint Override(empty)VPC endpoint or emulator.
Request Timeout Ms / Connect Timeout Ms / Max Retries / Worker Threads30000 / 5000 / 3 / 4Per API call (queries are polled and may run longer).
Verify SSL / Log Sdk WarningsOn / OnTLS checks; SDK warnings to LogAthenaQuery.
Default Work Group / Catalog / Databaseprimary / AwsDataCatalog / (empty)Used when a node or the tab leaves them empty.
Default Output Location(empty)S3 folder for results; empty = the workgroup's location.
Result Reuse Max Age Minutes0 (off)Reuse results of identical recent queries (saves cost while iterating).
Poll Interval Seconds / Max Poll Interval Seconds1 / 5Status checks start at the first value and grow by 1.5x up to the second.
Max Result Rows100000Rows downloaded at most (more = Truncated).
Query Timeout Seconds0 (none)Stop waiting and stop the query after this time.
Price Per Terabyte Usd5.00Used by Estimate Query Cost and the tab.
Confirm Non Read Only QueriesOnThe tab asks before CREATE, DROP, INSERT and similar.
Default Data Table Folder/Game/Data/AthenaSuggested folder for Save As DataTable.

Troubleshooting

Error codeCause and fix
NoCredentialsThe profile or chain gave no credentials. Check the profile name, run aws sso login for SSO profiles, or call Get Caller Identity to test.
InvalidRequestExceptionUsually no output location: set Default Output Location or configure one on the workgroup. Also returned for an unknown workgroup.
QueryFailedAthena ran the query and it failed; the message holds the reason (syntax error with line:column, table not found, permission on S3).
AccessDeniedExceptionThe IAM policy lacks an Athena, Glue or S3 permission (see Setting up AWS).
Timeout / CancelledThe query hit the timeout or was cancelled; it was stopped on Athena.
NotConfirmedDelete nodes need Confirm = true.
DataTableFailedSee the Report: the row struct must derive from Table Row Base and the path must be under /Game (or a plugin content root).
UnavailableThe SDK library could not be loaded or the editor is shutting down. Check the Output Log for LogAthenaQuery 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). Built for Unreal Engine 4.27 and 5.8.