XForge - Inventory X – Agnostic UI

The first complete C++ backend-first inventory plugin for Unreal Engine 5.1-5.7 on the marketplace. Grid layouts, equip slots, nested containers, complete multiplayer support with client prediction and server reconciliation — and a built-in cross-inventory system for player-to-chest interactions. No UI forced on you. Bring your own.

Discord | Documentation & Tutorial | Youtube

The Explainer - Interactive Documentation and Tutorials, chat directly with the codebase (link with Order verification)

What's included

Backend-first, UI-agnostic

Pure C++ runtime. No widget dependencies in the core. Build any UI on top using the fully exposed Blueprint API.

Grid, slot & nested containers

N×M items, 90° rotation, equip slots, and nested containers — bags inside bags inside bags.

Server authoritative + prediction

Full client prediction with a 7-phase reconciliation protocol, handle remap table and cascading invalidation.

Tag-driven rules

Acceptance, denial, equip compatibility, stacking and access policies — all driven by GameplayTags and data assets. No hardcoded game logic.

Cross-inventory sessions

Open a trusted server-authoritative session between two inventories. Multi-viewer, single-writer lock. Atomic commits across two components.

Sample UI included

Two complete sample modules — single inventory and dual-panel cross-inventory — built exclusively on the public API.

Two layers, one plugin

All current and future layers are separate modules and can be removed if the feature they provide isn’t needed for your project.

Layer 1 — Core

  • UInventoryComponent with flat registries

  • Grid layout engine (N×M, rotation, first-fit)

  • Rules engine with GameplayTag queries

  • 9 operations: add, remove, move, swap, split, merge, rotate, equip, unequip

  • Atomic batch operations

  • Delta replication via FFastArraySerializer

  • Client prediction & reconciliation

  • Full Blueprint public API

  • 39+ automation tests

Layer 2 — Cross-Inventory

  • Trusted interaction sessions (Open / Suspended / Closed)

  • Multi-view / single-writer lock model

  • Policy-driven security evaluator

  • TransferItem, SplitStack, MergeStack, SwapItems across components, Equip and Unequip

  • Rollback journal for atomic cross-component commits

  • Session prediction with dual RevisionBarrier

  • Scoped handle remap for item & container handles

  • SessionEpoch invalidation on lock change

  • Automation suite

Layer 3 — Crafting System

  • Not yet, it’s being planned.

Architecture at a glance

Definitions layer

Reusable data assets for item definitions, container layouts, stack rules, equip rules and cosmetics. Hard references for gameplay rules, soft references for cosmetics so dedicated servers stay lean.

Runtime state

Flat registries of container, item and fragment records. Typed handles with generation counters. No per-item UObject allocations. Instance fragments for durability, ammo, condition and any custom state you add.

Operation engine

Every mutation follows Validate → Simulate → Commit → Notify. Batches are all-or-nothing. Validation runs against pre-batch state, not cumulative intermediate state.

Networking

Owner-only OwnerTags, delta replication with explicit MarkArrayDirty / MarkItemDirty contracts, initial authoritative state flag, listen server host through the same logical pipeline as remote clients.

Cross-inventory

Session registry in a WorldSubsystem. UInventoryInteractionComponent on the PlayerController as the sole RPC entry point. Server always builds the authority context from the connection, never trusts client-declared identity.

Designed for real projects

Dedicated server safe

Cosmetic assets are soft-referenced and never loaded by the runtime core.

Extend without forking

Fragment system, open tag rules and data-asset pipeline let you add game-specific logic without touching the core.

Save/load ready

Stable handles, flat registries and FInventoryDefinitionId are designed to make persistence a natural addition.

No framework lock-in

No GAS, no CommonUI, no external dependencies beyond GameplayTags and NetCore.

1 Like

:package: Inventory_X Update! — v1.1

Major Architecture Update

A ground-up refresh of the fragment data model, replication boundary, and client prediction system. Focused on performance and stronger anti-cheat guarantees.

:bullseye: Highlights

:building_construction: New fragment data model

single source of truth (FragmentEntries asset-or-inline)

:high_voltage: Runtime vs Static fragment lifecycle

new introduced static fragments now live on the definition only, eliminating per-item replication for read-only data and reducing network bandwidth on heavy inventories.

:shield: Hardened anti-cheat boundary

Closed an item-duplication attack vector.

:video_game: Handle-preserving rollback

chained predicted operations no longer drop dependent ops during reconcile. Fixes a long-standing prediction edge case in cross-inventory transfers.

:test_tube: +22 new automation tests across registry, prediction, rollback journal, and Layer2 transfer paths.

:package: Cleaner public API

explicit GetRuntime*, GetStatic*, GetEffective* family. Old generalist API removed.

Changelog (UE 5.1 - 5.7)

:package: Data Model

New

- FInventoryItemFragmentEntry — a single entry that is either an asset reference (reusable fragment definition) or inline data (one-off, completely defined in the item).

- EInventoryFragmentLifecycle enum on every fragment, with two values:
    - RuntimePerItem — creates a per-item record, replicates, participates in snapshots/merge     (legacy default behavior).
    - StaticDefinition — definition-side only, never replicated, never per-item — perfect for     read-only data shared across all instances of an item type.

- UInventoryItemFragmentDefinition extended with Lifecycle (defaults to RuntimePerItem for backward-compatible behavior).

Removed

- TArray<TObjectPtr<UInventoryItemFragmentDefinition>> FragmentDefinitions on UInventoryItemDefinition.

Why it matters
Static fragments (e.g., ammo type, weapon category, item rarity) no longer pay replication cost or per-item allocation cost. Runtime fragments (e.g., durability, current ammo, condition) keep their existing per-item replicated semantics.

:electric_plug: API

Old names have been removed in favor of explicit Runtime/Static/Effective families:

- GetItemFragments -> GetRuntimeItemFragments, GetStaticItemFragments, GetEffectiveItemFragments

- GetFragmentByTag -> GetRuntimeFragmentByTag, GetStaticFragmentByTag, GetEffectiveFragmentByTag

- HasFragment -Z HasRuntimeFragment, HasStaticFragment, HasEffectiveFragment

- TryGetDurabilityFragment -> TryGetRuntimeDurabilityFragment, TryGetStaticDurabilityFragment, TryGetEffectiveDurabilityFragment

- TryGetAmmoFragment -> Same Runtime/Static/Effective split

- TryGetConditionFragment -> Same Runtime/Static/Effective split

- GetFragmentsForItem -> GetRuntimeFragmentHandlesForItem

- Internal_CreateFragment -> Internal_CreateRuntimeFragment


New view types

- FInventoryStaticFragmentView — static fragment data, no handle (handles are runtime-only).

- FInventoryEffectiveFragmentView — unified view with Source = RuntimeRecord | StaticDefinition discriminator and a bIsMutableRuntime flag.

FInventoryFragmentHandle remains valid only for runtime fragments. No fake handles are ever generated for static fragments.

:counterclockwise_arrows_button: Replication, Snapshot, Drop/Pickup

- Trusted snapshot (ExportItemSubtreeSnapshot/ImportItemSubtreeTrusted) carries only runtime fragments. Static fragment data is derived server-side and client-side from DefinitionId.

- Drop actor PickupableItemComponent replicates only PresentationFragments (runtime-only). UI consumers should query GetEffective* to render full per-item state including static contributions.

- Layer2 cross-inventory bridge snapshots are runtime-only; static data is resolved per-endpoint from the resolved definition.

- Snapshot import now rejects any fragment payload whose FragmentTypeTag does not correspond to a RuntimePerItem spec on the resolved definition (defense against client-crafted snapshots).

:balance_scale: Stack Rules & Validation

- InventoryStackValidator::ValidateMerge (Layer1) and InventoryInteractionStackValidator::ValidateMerge (Layer2) compare only runtime fragments when bRequireMatchingFragmentsForMerge is true.

- Two stacks of the same definition with only static fragments always merge cleanly — static fragments are equal by construction.

- Layer2 merge no longer requires both endpoints to resolve the definition: as long as one endpoint resolves and DefinitionId matches, the merge proceeds. Fixes spurious rejections under asset streaming / hot-reload scenarios.

:shield: Security & Anti-Cheat

- AddItem and RemoveItem are strictly server-authoritative. The validation gate enforces bServerInitiated == true, and Server_SubmitOperation_Implementation deliberately does not propagate that flag from client RPCs. Client autonomous proxies cannot directly create or destroy items via RPC.

- Closed an item-duplication attack vector. A bypass flag introduced during an early version was identified as a regression and removed. The flag had allowed client-side validation to accept arbitrary AddItem predictions; it has been fully eliminated, and explicit anti-pattern documentation has been added to the architecture guide.

- New security tests confirm that RequestOperation(AddItem) and RequestOperation(RemoveItem) from ROLE_AutonomousProxy:
    - return Rejected immediately at local validation;
    - never enqueue a pending prediction;
    - never emit a Server_SubmitOperation RPC.

:video_game: Client Prediction

Predicted operations now:

- create only runtime fragment records (static specs do not allocate);
- rollback removes only the runtime records they created (handle-preserving);
- replay correctly preserves source item identity through chained operation reconciliation.


Handle-Preserving Rollback (new in this version)

A subtle bug in Layer2 chained predictions has been fixed. Previously, when a client predicted two transfers in a fast sequence (e.g., move backpack to other inventory, then move weapon into backpack's child container), the authoritative reconciliation of the first operation would re-import the destroyed source items with new handles, breaking the second operation's source resolution and silently invalidating it.


The fix:

- New CreateRecordWithExistingHandle registry primitive that re-uses original handle + generation across destroy/restore cycles.

- Trusted seam variants (ImportItemSubtreePredictedPreservingHandles, ImportItemSubtreeTrustedPreservingHandles) that preserve identity through rollback.

- Symmetric application to both predicted rollback and trusted (server-side transaction failure) rollback for architectural consistency.

- Atomic prevalidation prevents partial registry mutations.


Idempotency Hardening

The rollback idempotency check has been upgraded from a presence-only check to a full tri-state structural verification:

- NotPresent -> proceed with handle-preserving import.
- PresentEquivalent -> idempotent skip (handles + structure match snapshot exactly).
- PresentMismatch -> fail loudly with audit log instead of silent success.

Conservative fallback for runtime fragments: if any item in the snapshot carries fragment data, the idempotency shortcut is bypassed

:high_voltage: Performance

- Definition-side fragment cache is array-first: contiguous TArray<FInventoryResolvedFragmentSpec> with linear-scan helpers. No TMap for tag lookup — small fragment counts make linear scan cache-friendlier than hash maps with allocations and pointer chasing.

- Cache prepared in PostLoad and PostEditChangeProperty, not re-resolved on every query.

- Repeated GetEffectiveFragmentSpecs() calls return stable storage (verified by automation test) — zero re-resolution cost on hot paths like tooltip rendering.

- Static-heavy inventories (e.g., shops, world containers with read-only items) see significantly reduced FragmentFastArray size on both server and client.

- Network bandwidth reduction: items with only StaticDefinition fragments replicate zero fragment records.

:test_tube: Test Coverage

Significant suite expansion:

- +11 prediction tests covering Move/Split/Merge/Equip rollback, runtime fragment preservation, and security boundaries.

- +9 rollback journal tests including all 4 structural drift detection cases (Quantity, Placement, ParentContainer, ChildContainerLink), runtime fragment fallback, and idempotency happy path.

- +6 trusted seam tests for handle-preserving import/export.

- +3 registry tests for CreateRecordWithExistingHandle (revive after release, duplicate id rejection, generation preservation).

- Reconciliation suite cleaned: removed orphan tests and updated old tests

Final test status: 117/117 broad Layer2 tests + 9/9 rollback journal + 4/4 handle preserve regression — all green

:bug: Bug Fixes

- Chained Layer2 predictions silently invalidated — fixed via handle-preserving rollback re-import.

- Idempotent rollback could mask state corruption — replaced presence-only check with structural verification + audit logging.

- Partial subtree presence treated as success — now correctly classified as PresentMismatch and fails with explicit log.

- Layer2 merge spurious rejection under asset streaming — fallback resolution path uses whichever endpoint resolves the definition (both items must already share DefinitionId).

:wrench: Internal Improvements

- Internal_CreateFragment renamed to Internal_CreateRuntimeFragment for consistency with the runtime-only contract.

- LookupCache.ItemToFragments is documented and enforced as runtime-only.

- New FInventoryResolvedFragmentSpec cache type unifies runtime, static, and effective spec views on the definition.

- Editor UX: when BaseFragmentAsset is set, inline fields are hidden via EditCondition/EditConditionHides to make the asset-or-inline contract visually unambiguous.

- PostEditChangeProperty clears inline fields when an asset is assigned to prevent zombie data.

:package: Inventory_X Update! — v1.2

Fragment Mutation Pipeline – changelog


A new server-authoritative pipeline for mutating runtime fragment data, with client-side prediction, zero-allocation hot paths on modern UE versions, and an extensible mutation verb system.
Built around a clean public API and validated under 100-player, high-frequency mutation scenarios. This is an additive update: no breaking changes, no asset migration required.


:bullseye: Highlights

  • :high_voltage: Production-grade mutation pipeline — server-side validation, client prediction with rollback, compact prediction snapshots, no heap allocations on the hot path in supported engine versions.
  • :puzzle_piece: Extensible mutation verbs — register custom semantic verbs and payloads from Project Settings, without modifying the plugin core or recompiling the engine.
  • :shield: Anti-cheat focused — generic “replace” calls from clients are deny-by-default, and semantic verbs are gated by server-side policies with payload size limits.
  • :globe_with_meridians: Scale-tested — stress-tested with 100 autonomous-proxy clients × 10 mutations/sec each, p95 server overhead 0.641 ms , owner-only replication topology.
  • :test_tube: +200 automation tests across prediction, rollback, anti-cheat negative paths, serialization, Blueprint nodes, and editor tooling.


:package: Inventory_X — 1.2 Changelog (UE 5.3 – 5.7)

Fragment Mutation Pipeline – Announcement


:building_construction: The Fragment Mutation Pipeline

The core of this release: a single, coherent path to mutate runtime fragment data — built-in or custom — with prediction, replication, and policy enforcement, all through a public API on UInventoryComponent.

New capabilities on UInventoryComponent (high level):

  • Generic semantic mutation entry point driven by registered verbs.
  • Controlled “replace” APIs for fragment data by tag or handle.
  • Built-in helpers for common ammo/durability/condition flows, ready to use in gameplay code and Blueprints.

Three prediction modes:

  • Auto — lets the policy decide when prediction is safe, otherwise falls back to server roundtrip.
  • NoPredict — purely authoritative, no client-side prediction.
  • ServerOnly — callable from server only; client calls are rejected.

Support for optimistic concurrency and revision-based acks to avoid confirming predicted operations against stale state.


:puzzle_piece: Extensible Verb Registry

Project Settings now expose a registry where you can define your own mutation verbs.

  • Each verb binds a gameplay tag and a payload struct (C++ or Blueprint).
  • Per-verb bandwidth caps and client-origin flags are configurable in editor.
  • Built-in verbs (ammo, durability, condition) are registered through the same mechanism, so your custom verbs behave like first-class citizens.

The wire format is compact and schema-backed, but all of that is handled internally; you only work with tags and strongly-typed payloads.


:electric_plug: Public API

New public functions on UInventoryComponent exposed to both C++ and Blueprint:

  • A generic semantic mutation function driven by verbs.
  • Controlled “replace” functions for fragment data.
  • A small set of built-in helpers for ammo, durability, and condition flows.

New supporting types include request/response structs, a compact prediction snapshot, and a richer fragment change view for events, all Blueprint-accessible.


:shield: Anti-Cheat & Security

The mutation pipeline is server-authoritative end-to-end: there are no client write paths that bypass policy validation.

  • Generic “replace” calls from clients are rejected unless explicitly allowed by policy.
  • Semantic verbs are validated server-side against current state before any mutation is committed.
  • Payloads are bound by size limits and validated before allocation to close bandwidth-flood vectors.
  • Revision checks prevent confirming predictions against outdated baselines.

Example: a cheater trying to force abnormal ammo changes is blocked either by policy or by the generic gate, not by client-side conventions.


:video_game: Client Prediction

Predictable through the new pipeline:

  • All semantic verbs whose policy explicitly marks them as safe to predict.
  • Built-in helpers (fire/reload/durability/condition) can be predicted locally and reconciled on the server response.

The prediction layer uses compact snapshots to capture pre-mutation state and roll back on reject, with zero allocations on the hot path when using compatible payload layouts.
Blueprint helpers are available to pack/unpack lightweight snapshot data for custom fragment types.


:high_voltage: Performance

  • Fragment record replication uses a native serialization path backed by a schema, replacing the previous reflection-based approach for better performance.
  • Inline payload storage is used for common payload sizes, avoiding heap allocations on hot paths; dynamic or large payloads fall back to a general path suitable for non-hot usage.
  • The pipeline has been profiled under 100-player, high-frequency mutation scenarios and kept well within acceptable frame budgets.

:dna: Custom Fragment Authoring

Blueprint-only:

  • Define your fragment as a User Defined Struct.
  • Register it in Project Settings with the corresponding fragment tag and policy.
  • The full pipeline (prediction, replication, events, K2 nodes) is available out of the box.

C++:

  • Define a USTRUCT fragment data type and register it in the same settings panel.
  • Suitable layouts automatically benefit from the zero-allocation hot path.

Editor validation catches mismatches between tags and structs and offers tools to realign assets when you change mappings.


:balance_scale: Policy Framework

All mutation business logic lives in UInventoryFragmentMutationPolicy subclasses.

  • C++ subclasses for maximum performance.
  • Blueprint subclasses with K2 hooks for validation, mutation, and post-commit logic.
  • A data-driven mode for simple rules (numbers, tags, booleans, vectors) without any code.

Policies are resolved via a global registry optimized for small and large projects and rebuilt only when settings change or modules reload, not per component.


:hammer_and_wrench: Editor Module & K2 Nodes

New Inventory_XEditor module with typed K2 nodes to remove manual struct handling from Blueprint graphs:

  • Get Runtime Fragment Data
  • Modify Runtime Fragment Data
  • Apply Runtime Fragment Mutation

Discovery caches update automatically on asset rename/hot reload, and there is an asset factory for UInventoryItemFragmentDefinition to streamline authoring.


:satellite_antenna: Event System

New typed delegate for fragment changes, exposing handles, owning item, fragment tag, change type, and whether the change is predicted or authoritative.

  • The legacy event remains available and unchanged.
  • Predicted vs authoritative events are clearly distinguishable, and a specific change type is used when predictions are reverted.
  • The revert event fires only on terminal reject/timeout/invalidation — not on intermediate rebases, so your UI won’t get spurious events.

:bullseye: Sample Weapon

Example weapon in the Inventory_XSample module:

  • C++ base class plus a Blueprint child for designers.
  • Fire/Reload use the new mutation helpers with prediction.
  • A HUD widget binds to the new fragment change event for responsive UI updates.
  • No direct client-side writes to runtime ammo data; all networking paths are validated under SP, listen server, and dedicated server.

:test_tube: Test Coverage

+200 automation tests covering:

  • Primitive serialization and payload bounds.
  • Policy resolution and validation phases.
  • Public API behaviors and prediction modes.
  • Custom authoring flows, Blueprint nodes, events, and sample weapon scenarios.
  • Zero-allocation hot paths and multi-client scale scenarios.

You can run the full suite via the Automation framework to verify integration in your environment.


:warning: Known Limits

  • Data-driven policies target numeric/tag/bool/vector fields; complex or dynamic data still require C++ or Blueprint policies.
  • Zero-allocation inline payloads apply to compact, POD-like payloads; larger or dynamic payloads use the general path (fine for non-hot usage).
  • Built-in helpers are wired to the built-in fragments; for custom fragments, wrap the generic mutation entry point in your own helper.

Some AI/LLM sometimes over-engineer solutions and make it harder for humans to extend a system manually. I was curious which one was leveraged in the creation of this?

1 Like

Hi, sorry for the very late reply. I never got any interactions on this thread, and I only came back here to post release notes for major versions. My apologies.

Regarding your question, I’ll walk you through my workflow instead of just listing models. That way it might help both you and any future visitors wondering the same thing.

Both Stats_X and Inventory_X were created without LLMs, and so was a good part of their later update cycles. Unfortunately, even at the beginning of this year, LLMs made too many mistakes or suggested approaches I didn’t like.

Recently, given their upgrades, I’ve integrated them into my development flow, but I dont use just one model. I write the full plan myself, then have all the top-tier models check my spec for bugs. Once the plan for the whole update is frozen, I implement some parts myself and use cheaper models for other. Thanks to the planning, which can take weeks or months, even the cheaper models rarely make mistakes. Every commit is manually reviewed before being pushed.

The final phase is going back to the top-tier models and asking them to break the system by posing as malicious clients. This leads to another round of planning to fix issues, uncover regressions, and implement the changes.

I use multiple models because no single one is best at everything, even within the same benchmark. Each AI has different training data. In my personal experience, the latest GPT models are better at spotting bugs, while the latest Claude models are better at fixing them while keeping performance requirements intact. If I had used only Claude, there would be more bugs. If I had used only GPT, more bugs would have been fixed, but with less performant code that’s riskier to refactor in the future.

Regarding over-engineering, I dont generally consider it over-engineered. I may have gone overboard in a few places, and if you feel like pointing them out to me on Discord when you spot them, I’d be happy to hear them. But most of that complexity exists to ensure security and performance for your game.

With v1.3, that is in Fab review, the code is far better commented. The Google NotebookLM submitted during the order verification can also help a lot in understanding what the code does

Sorry again for the late reply

@everyone

:package: Inventory_X Update! — v1.3

Runtime Fragments, Derived Tags, Configurable Nesting & Multiplayer Reliability – changelog

—————————————————————————————————————————————————
Inventory_X v1.3 is a major update to how items evolve during gameplay, how their state drives gameplay tags, how deep your container hierarchies can go, and how multiplayer operations become visible to the client.

Add and remove runtime fragments on individual items, build item and character tag contributions from their actual state, and define exactly what happens to fragment data when a stack is split. Choose your project’s nesting depth in Project Settings and narrow it per container. A deeper revision of prediction and reconciliation keeps operation completion aligned with the authoritative data the client has actually received, and tells you when that data is complete.

Available through C++ and Blueprint, with stronger server validation, clearer authoring tools, and substantial improvements to prediction costs in large inventories.

This release includes behavior changes. Review the upgrade notes, especially rotation permissions, fragment split policies, container access, operation-confirmation callbacks, client/server build compatibility, and batch or cross-inventory requests that use items still awaiting server confirmation.
—————————————————————————————————————————————————

:bullseye: Highlights

  • :puzzle_piece: Runtime fragment lifecycle — add and remove per-item fragments during gameplay, with typed Blueprint inputs, server validation, and optional client prediction. Build attachments, temporary effects, enchantments, and other item-specific state.
  • :label: Derived item and character tags — tags follow active fragments and equipment state. Normal and additive contributions support exact source counts, equipment-set logic, and possession effects; storage containers can exclude their contents from character contributions.
  • :balance_scale: Configurable stack splitting — Copy, KeepAtSource, or custom C++/Blueprint policies, shared by local and cross-inventory operations. A deterministic integer-partition helper makes shared-resource splits easier to implement correctly.
  • :triangular_ruler: Configurable nesting depth — set a Global Nesting Cap in Project Settings (default 3) and narrow it per container: a project cap of 12 can become 8 inside a backpack, 3 inside a bag, and 0 inside a pocket. The server always enforces its own value, and every hierarchy traversal is iterative and bounded by the records actually present.
  • :globe_with_meridians: More reliable multiplayer completion — confirmation waits for authoritative effects, including operations submitted without prediction. Clients can check whether the inventory data they hold is complete, so an inventory that is still arriving is no longer mistaken for an empty one. Predicted creation handles remain stable through rollback and replay.
  • :high_voltage: Lower prediction costs in large inventories — a measured 1,000-item reconciliation scenario dropped from 9.81 ms to 0.95 ms median.
  • :hammer_and_wrench: Better Blueprint authoring — a typed Get Semantic Payload node, readable batch results, clearer policy overrides, configuration and data-readiness queries with events, and expanded public API documentation.
  • :lady_beetle: 40+ bug fixes across placement, splitting, tags, prediction, networking, and security.
  • :test_tube: Expanded regression coverage — 1,250+ automation tests, covering runtime fragments, derived tags, split behavior, deep hierarchies, networking and data readiness, security boundaries, and authoring tools.

—————————————————————————————————————————————————

:warning: Upgrade Notes and Limits

Review these changes in existing integrations:

  1. Rotation flags are now enforced by the rotation command. Check bSupportsRotation, bAllowRotation, and the placement rule’s bCanBeRotated. Returning to the unrotated orientation is permitted by the rotation flags, but still must satisfy placement checks.
  2. Split no longer resets every new Layer 1 fragment to its defaults. Copy is the default. Configure Custom behavior for shared reserves that must be conserved.
  3. Placement and access checks are stricter. Equip, Split, and cross-inventory placement may reject requests that previously bypassed filters or nesting rules. Fragment mutations also respect container access.
  4. Item tags are derived state. Supported live import recalculates them from definitions, fragments, and placement. Represent temporary item markers through fragment contributions instead of treating copied tag sets as independent authoritative state.
  5. Confirmation timing changes. Use OnOperationConfirmed when subsequent logic requires locally applied authoritative effects. Use OnAuthoritativeResultReceived to observe the server’s response. A submission result is not a replication-completion signal.
  6. Custom Replace policies must opt in to client requests. An override cannot bypass the common deny-by-default permission gate.
  7. Data-driven configurations may now be rejected. Remove invalid arithmetic and conflicting same-verb rules. Numeric operations on 64-bit integers are limited to the exact-integer range supported by their calculation path; snapshot restoration itself preserves full signed 64-bit values.
  8. Nesting depth is now a project setting. The default Global Nesting Cap is 3, so existing projects keep their limit. Clients and server must use the same value; decide it before shipping, because changing it between sessions that reuse the same inventories is not supported.
  9. Client and server must run the same v1.3 build. The replication format of inventory records changed; builds of different versions cannot play together.
  10. Batch and Layer 2 requests no longer use unconfirmed predicted items. After a split, transfer, or other creating operation, wait for confirmation before using the new item in a batch or cross-inventory request, then retry with the confirmed handle. Single Layer 1 requests still wait automatically.
  11. New result codes. Handle RuntimeConfigurationPending, RuntimeConfigurationMismatch, RuntimeConfigurationInvalid, and the Layer 2 AuthoritativeDataPending in switch statements and UI messages; they are not nesting-limit failures.
  12. Changes during a subtree removal are rejected. Post-commit hooks and payload destructors that modify the same inventory while a removal is applied must schedule that work from the events dispatched afterwards. A batch that removes an item and changes something inside it is rejected as a whole.
  13. On clients, OnInventoryChanged is coalesced into one broadcast per network update.

Current limits:

  • Runtime lifecycle remains limited to RuntimePerItem
  • Custom split prediction is opt-in and requires deterministic, side-effect-free policy logic.
  • The Global Nesting Cap limits depth, not the size of a hierarchy: very deep or very wide inventories cost in proportion to the records they contain.
  • Extremely large batch or Layer 2 acknowledgements can exceed the default 64 KB network-message limit. Avoid combining many large subtree operations into one batch; a dedicated aggregate-message fix is outside v1.3.
  • Very large inventories still incur linear cleanup/replay costs. The measured reconciliation improvement does not establish a universal sub-millisecond guarantee.
  • The data-readiness protocol adds 33 bits to each replicated inventory delta. A dedicated performance update will follow.
  • On UE 5.3 and 5.4, older engine FInstancedStruct behavior keeps three zero-allocation contracts of the fragment mutation hot path from being met; behavior is unaffected.
  • Pickup observer notifications require an active actor channel; dormant actors may miss the notification. Use the collecting player’s operation result and inventory events to track collection independently.
  • A persistent SaveGame system and save-file migration API are not included in this update but will follow. Trusted live snapshots used for transfers and pickups are not a persistent save format.

—————————————————————————————————————————————————