ANTIGRAVITY LABJP
Articles/App Development
App Development/2026-04-28Advanced

Antigravity × Unreal Engine 5 Plugin Production Guide — Designing Reusable Game Systems with AI for Multiple Titles

A production-grade guide to building UE5 plugins with Antigravity. Covers module design, build configuration, AI-friendly code separation, and distribution patterns for reusing one plugin across multiple titles.

antigravity435unreal-engine-5ue52plugingame-devcpp2production71

Premium Article

After your second or third UE5 project, a pattern starts to repeat. Inventory. Save system. Settings menu. Achievement unlocks. UI frame. The contents differ slightly from game to game, but the structure is almost always the same. You know you should pull these out into a plugin, but every attempt seems to get stuck on .Build.cs dependency graphs or that endless Public/Private split — and you end up pasting the code into the game module again. I've been there more times than I'd like to admit.

Antigravity has changed that loop for me. The agent will happily suggest Build.cs lines and header visibility, which lowers the psychological cost of starting a plugin. But — and this is the catch — accepting AI suggestions blindly will break your build in subtle ways. You need to design your plugin so that the agent has the right context to give good suggestions. That's what this guide is about.

We'll build three reusable systems — inventory, save, and achievements — as a single plugin called CommonGameSystems, then walk through how to ship and version it across multiple titles. The code is complete and drop-in ready, not a sketch.

Why "AI-friendly plugin structure" matters

Antigravity reads AGENTS.md and your file layout to decide what to generate. If you point it at a UE5 project, it tends to treat Source/<GameName>/ as one big module. Plugin headers under Plugins/ get read as separate context, and the agent often loses track of which symbols are exported and which are not.

The biggest casualty is the Public//Private/ split. UE5 only allows other modules to #include headers under Public/. Ask Antigravity to "write code that adds an item to the inventory" without giving it that boundary, and it will happily reach into a Private/ struct from your game module — which compiles in the plugin but fails to link in the consuming module with unresolved external symbol.

The fix is simple: divide the plugin clearly into an "API zone" and an "implementation zone," then write that division down in an AGENTS.md the agent can read. After this one change, my agent suggestions stopped being broken almost overnight.

Plugin skeleton: .uplugin and .Build.cs

Start with the file layout. We'll put the plugin at Plugins/CommonGameSystems/:

Plugins/CommonGameSystems/
├── CommonGameSystems.uplugin
└── Source/
    ├── CommonGameSystemsRuntime/
    │   ├── CommonGameSystemsRuntime.Build.cs
    │   ├── Public/
    │   │   ├── Inventory/InventoryComponent.h
    │   │   ├── SaveSystem/GameSaveSubsystem.h
    │   │   └── Achievements/AchievementSubsystem.h
    │   └── Private/
    │       ├── CommonGameSystemsRuntime.cpp
    │       ├── Inventory/InventoryComponent.cpp
    │       ├── SaveSystem/GameSaveSubsystem.cpp
    │       └── Achievements/AchievementSubsystem.cpp
    └── CommonGameSystemsEditor/
        ├── CommonGameSystemsEditor.Build.cs
        ├── Public/
        └── Private/

The split between Runtime and Editor is non-negotiable for shipping. Editor modules are stripped from packaged builds, so they're the right home for editor-only tools and asset actions. Skip this split early on and you'll spend a frustrating afternoon hunting down "missing Slate" or "unresolved UnrealEd" errors at packaging time.

Here's the CommonGameSystems.uplugin:

{
  "FileVersion": 3,
  "Version": 1,
  "VersionName": "1.0.0",
  "FriendlyName": "Common Game Systems",
  "Description": "Reusable runtime systems (inventory, save, achievements) for UE5 indie titles.",
  "Category": "Gameplay",
  "CreatedBy": "Your Studio",
  "EnabledByDefault": true,
  "CanContainContent": true,
  "Installed": false,
  "Modules": [
    {
      "Name": "CommonGameSystemsRuntime",
      "Type": "Runtime",
      "LoadingPhase": "Default"
    },
    {
      "Name": "CommonGameSystemsEditor",
      "Type": "Editor",
      "LoadingPhase": "PostEngineInit"
    }
  ]
}

The LoadingPhase of Default is intentional. Earlier phases like PreDefault run before subsystems such as UAssetManager are ready, and any AI-generated code that touches them will crash on game start. I've seen this happen on multiple projects — Antigravity sometimes proposes PreDefault because it sounds more "earnest," but it's almost always wrong for gameplay code.

The .Build.cs is the file Antigravity gets wrong most often. Keep this template at the top of the file so you can spot incorrect dependency additions in your diff:

// Copyright (c) Your Studio. All Rights Reserved.
using UnrealBuildTool;
 
public class CommonGameSystemsRuntime : ModuleRules
{
    public CommonGameSystemsRuntime(ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
        bUseUnity = false; // Faster per-file builds during plugin dev — turn on later
 
        PublicIncludePaths.AddRange(new[] { "CommonGameSystemsRuntime/Public" });
        PrivateIncludePaths.AddRange(new[] { "CommonGameSystemsRuntime/Private" });
 
        PublicDependencyModuleNames.AddRange(new[]
        {
            "Core", "CoreUObject", "Engine",
            "GameplayTags",          // identify item types via tags
            "DeveloperSettings",     // data-driven settings
        });
 
        PrivateDependencyModuleNames.AddRange(new[]
        {
            "Json", "JsonUtilities", // save data serialization
            "OnlineSubsystem",       // achievements
        });
    }
}

bUseUnity = false is a stylistic choice for production, but during plugin development it's a quality-of-life win. Single-file builds make it much easier to localize the file that broke when the AI's last suggestion didn't compile. Flip it back to true once the plugin stabilizes.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Structure your UE5 plugin's Public/Private boundary so Antigravity stops generating broken Build.cs files and unresolved external symbols
Walk away with three working systems — inventory, save, and achievements — complete with .uplugin and .Build.cs ready to drop into your project
Design version management, build isolation, and module dependency rules that hold up when you reuse a single plugin across two, three, or more shipped titles
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

App Dev2026-06-28
When Streaming Works Locally but Arrives All at Once in Production — Field Notes on Proxy Buffering and Silent Stalls
Stream Gemini through Antigravity over SSE and it flows token-by-token on localhost, then freezes for seconds and dumps the whole answer in production. Field notes on measuring the stall first, then killing proxy buffering, idle disconnects, and reconnect-driven double generation.
App Dev2026-05-03
Building Idempotency Keys and Dedupe Stores in TypeScript with Antigravity
A production guide to designing idempotency keys and dedupe stores in TypeScript with Antigravity — covering Stripe webhook retries, Temporal replays, and the Cloudflare KV / Redis / Postgres trade-offs you actually need to choose between.
App Dev2026-05-01
Zero-Downtime Database Migrations with Antigravity: The Expand-Contract Pattern in Production
A complete production guide to running breaking schema changes—type swaps, column renames, table splits—with zero user-facing downtime, using the Expand-Contract pattern with Antigravity's AI assistance.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →