Zurück zum Blog

Fixing the UEFN AddItem Far Distance Bug: Spatial Replication Desyncs beheben

Veröffentlicht am 11. Juni 2026
Fixing the UEFN AddItem Far Distance Bug: Spatial Replication Desyncs beheben

Kurz und knapp

Dieser Leitfaden analysiert den UEFN AddItem Far Distance Bug, bei dem weit entfernt gespawnte Custom Items aufgrund von World Partition und Network Relevancy nicht im Spielerinventar gerendert werden. Er beschreibt den fehlerhaften Lifecycle und das UI-Binding auf Clientseite sowie das Phänomen der Re-Replication am World-Origin `{0.0, 0.0, 0.0}`. Abschließend werden drei native Workarounds wie das lokale Spawnen und delayed State Allocation sowie die Entkopplung von Inventar-States über ein externes Backend wie horizOn vorgestellt.

Du spawnst ein Custom-Item-Prefab in Verse, fügst es der Hotbar des Spielers hinzu und... nichts. Das Inventar des Spielers bleibt leer oder das Item-Icon wird als fehlerhaftes, weißes Quadrat angezeigt. Doch sobald der Spieler zum Map-Origin bei {0.0, 0.0, 0.0} zurückkehrt, erscheint das Item wie von Zauberhand. Wenn du dich mit dem uefn additem far distance bug herumschlägst, kämpfst du mit dem grundlegenden Network-Replication-Design der Unreal Engine, das mit den Spatial-Streaming-Regeln von UEFN kollidiert.

Spatial Streaming in Fortnite Creative verstehen

Fortnite-Maps sind riesige Umgebungen, die dynamische Komponenten on the fly laden und entladen müssen, um Speicher zu sparen. Um die Server-Ticks stabil und die Client-Frameraten hoch zu halten, nutzt UEFN ein auf World Partition basierendes Spatial-Streaming-System. Der Server repliziert schlichtweg nicht jeden einzelnen Actor zu jeder Zeit an jeden Client. Stattdessen wird die Replication durch Network-Relevancy-Regeln gesteuert, die bestimmen, welche Datenpakete an welchen Spieler gesendet werden.

World Partition und Network Relevancy Distance

Unter Standard-Fortnite-Einstellungen ist die NetRelevancyDistance der Radius, innerhalb dessen ein Actor für einen Spieler repliziert wird. Wenn eine Entity außerhalb dieser Bubble gespawnt wird (normalerweise etwa 15.000 Unreal Units oder 150 Meter), weigert sich der Server, ihre Replication-Daten an den Client zu senden. Diese räumliche Optimierung reduziert die aktiven Replication-Channels in Open-World-Maps um bis zu 80 %. Das bedeutet allerdings auch, dass ein Client völlig blind gegenüber Entities sein kann, die an weit entfernten Koordinaten existieren.

Wenn ein Spieler die Map durchquert, fordert der Client dynamisch Grid Cells vom Server an. Wird eine Entity in einer Grid Cell gespawnt, die vom Client des Spielers aktuell nicht gestreamt wird, weiß der Client nichts von ihrer Existenz. Dieses Culling hilft dabei, wertvollen GPU-Speicher zu sparen und verhindert, dass die Rendering Pipeline durch entfernte Draw Calls ins Stocken gerät.

Wie UEFN die Instanziierung von Entities handhabt

In UEFN bestehen Custom-Item-Prefabs aus einer Basis-Entity kombiniert mit Komponenten wie item_component, mesh_component und icon_component. Wenn dein Verse-Script eines dieser Prefabs instanziiert, erstellt der Server den Entity-Container und seine Sub-Komponenten im Speicher. Die physische Replication dieser Rendering-Komponenten an den Client bleibt jedoch an den Spatial Transform der Entity gebunden. Wenn dieser Transform zu weit vom Spieler entfernt ist, wird der Client niemals über die Existenz der Komponenten informiert.

Den AddItem Distance Bug analysieren

Das Problem tritt auf, wenn man das räumliche Spawnen von Entities mit dem Inventarsystem des Spielers kombiniert. Die Inventory-Hotbar-Komponente wird global repliziert, da sie direkt an den Charakter des Spielers angehängt ist. Wenn du AddItem() aus großer Entfernung aufrufst, erzeugst du einen direkten Desync zwischen einem global relevanten Container und einem räumlich gecullten Asset.

Schritt-für-Schritt-Analyse des Failure-Loops

Werfen wir einen genauen Blick darauf, was bei diesem Desync unter der Haube passiert:

  • Spawning: Ein Verse-Script spawnt ein Item-Prefab an einer entfernten Koordinate, wie zum Beispiel {X:=0.0, Y:=0.0, Z:=25000.0}.
  • Inventory-Aufruf: Das Script ruft sofort AddItem() auf der fort_inventory_weapon_hotbar_component des Spielers auf.
  • UI-Registrierung: Die clientseitige Inventar-UI empfängt ein Replication-Event, das besagt, dass ein neues Item den Hotbar-Slot belegt.
  • Null-Lookup: Der Client versucht, die Item-Referenz aufzulösen, um dessen icon_component für das Rendering zu laden.
  • Visueller Fehler: Da die gespawnte Entity aufgrund des Distance-Cullings nicht an den Client repliziert wurde, schlägt der Lookup fehl, was zu einem leeren Slot führt.

Deep-Dive: UEFN Component Lifecycle und UI-Binding

In UEFN sind Komponenten wie mesh_component und icon_component direkt an clientseitige Rendering Pipelines gebunden. Die UI wird mithilfe von Slate-UI-Widgets erstellt, die Icons direkt aus der icon_component der aktuell in der Hotbar vorhandenen Items ziehen. Wenn die Hotbar-Komponente eine Statusänderung erfährt (z. B. Hinzufügen oder Entfernen eines Items), löst sie ein internes Replication-Event aus. Die clientseitige UI lauscht auf dieses Event und zeichnet die UI-Slots neu.

Da das Neuzeichnen der UI jedoch unmittelbar nach dem Empfang des Replication-Events erfolgt, versucht der Client, auf die Icon-Textur der referenzierten Item-Entity zuzugreifen. Wenn der Replication-Channel der Item-Entity noch nicht geöffnet wurde, ist der Textur-Pointer ungültig. Dies führt zu dem Bug, bei dem das Item fehlt oder fehlerhaft dargestellt wird. Das Inventarsystem verwendet Soft Object References für Komponenten, was ein Graceful Failure ermöglicht (d. h. das Spiel stürzt nicht ab), aber eben zum „unsichtbaren Item“-Bug führt.

Wenn die clientseitige Slate-UI die Anweisung zur Aktualisierung erhält, prüft sie die Item-Referenz. Ist der zugrundeliegende Actor noch nicht eingestreamt oder repliziert, muss die clientseitige UI-Engine eine Null-Repräsentation oder einen visuellen Stub zuweisen. Dies führt zu leeren Slots, die sich erst füllen, wenn der Replication-Channel explizit aufgebaut wird. In der Standard-Unreal-Engine könnte ein Entwickler manuell einen Callback für die Actor-Replication registrieren, aber die Verse-API von UEFN abstrahiert dies derzeit, sodass Entwickler keinen direkten Listener für die Component-Replication haben.

Das mysteriöse Verhalten am World-Origin {0.0, 0.0, 0.0}

Viele Entwickler bemerken, dass sich der Bug von selbst behebt, wenn sich der Spieler dem Koordinatenursprung bei {0.0, 0.0, 0.0} nähert. Im Replication-Modell der Unreal Engine setzen Actors mit nicht aufgelösten räumlichen Parent-Objekten oder nicht initialisierten Physics-Layern ihren replizierten Transform standardmäßig auf den Origin zurück. Dadurch wird der Ursprung zu einem Hotspot für ausstehende Replication-Updates. Nähert sich der Spielercharakter {0.0, 0.0, 0.0}, öffnet die Engine die Replication-Channels für diese nicht aufgelösten Referenzen und erzwingt das Herunterladen der Item-Daten.

Dieses Verhalten ist eine bekannte Eigenheit des Unreal Engine Network-Drivers. Wenn das Spatial Streaming den Transform eines replizierten Actors nicht auflösen kann, setzt es die Koordinaten auf ihre Default-Floats zurück. Da der Spieler normalerweise in der Nähe des Origins vorbeikommt oder der Origin für bestimmte globale Manager-Actors immer als relevant eingestuft wird, öffnet der Client schließlich den Channel. Sobald dieser geöffnet ist, werden alle ausstehenden Komponentendaten auf einmal repliziert, wodurch das Item plötzlich erscheint.

Es ist nicht das erste Mal, dass Spatial Replication bei der Entwicklung von Multiplayer-Spielen Kopfschmerzen bereitet. So führt beispielsweise das Handling von High-Speed-Spielerbewegungen oder Remote-Triggern über riesige Terrains hinweg häufig zu Positionsfehlern, wie in unserem Guide darüber, wie man Player Location Desyncs in UEFN und Unreal Engine Multiplayer behebt, beschrieben wird. Ebenso kann sich das Component-Ownership verheddern, wenn Items zwischen verschiedenen Actors übertragen werden – ein Thema, das wir in unserem Walkthrough zum Beheben von Multiplayer-Inventar-Alpträumen und vertauschten ActorComponent-Ownern in Unreal Engine ausführlich behandeln.

Fixes und Workarounds auf Engine-Ebene

Um den uefn additem far distance bug mit nativen Tools zu lösen, musst du sicherstellen, dass die Entity für den Client relevant ist, bevor du Inventar-Funktionen aufrufst. Da UEFN keine direkten Low-Level-Replication-Controls (wie bAlwaysRelevant oder manuelle Relevancy-Groups) für Verse bereitstellt, müssen wir auf clevere räumliche Workarounds zurückgreifen. Hier sind die drei zuverlässigsten Ansätze zur Lösung dieses Problems.

Strategie 1: Lokales Player-Anchoring

Die zuverlässigste native Lösung besteht darin, das Item-Prefab direkt an den aktuellen Positionskoordinaten des Zielspielers zu spawnen. Da sich der Spieler immer innerhalb seiner eigenen Net-Relevancy-Bubble befindet, repliziert der Server die Entity und ihre Komponenten sofort an den Client. Sobald der Client die Entity registriert hat, kannst du AddItem() ausführen, um das Item sicher in die Hotbar einzufügen. Da das Inventarsystem das Item nun besitzt, ist seine Spatial Replication am Spieler verankert, sodass dieser sich überall auf der Map bewegen kann, ohne die visuellen Assets des Items zu verlieren.

Strategie 2: Delayed State Allocation

Wenn deine Spiellogik das Spawnen von Items an weit entfernten Truhen-Locations erfordert, solltest du das Hinzufügen des Items zur Hotbar verzögern. Anstatt AddItem() sofort nach dem Spawnen der Entity aufzurufen, wartest du, bis sich der Spieler innerhalb eines bestimmten Entfernungs-Grenzwerts zur Truhe befindet. Du kannst diesen Grenzwert mithilfe eines Custom Verse Triggers oder eines Distance-Check-Loops verwalten. Sobald der Spieler den Relevancy-Radius betritt (innerhalb von 10.000 Units), repliziert die Entity, und du kannst den Inventar-Transfer sicher auslösen.

Strategie 3: Clientseitige UI-Reinitialisierung

Wenn du das Spawnen von Items aus der Ferne nicht vermeiden kannst, kannst du ein Neuzeichnen der clientseitigen UI erzwingen, sobald die Entity repliziert ist. Dies erreichst du, indem du auf ein Custom Event lauschst, das ausgelöst wird, wenn sich der Spieler der Spawn-Zone nähert. Sobald der Spieler nah genug herankommt, damit die Entity eingestreamt wird, aktualisiert das Verse-Script eine replizierte UI-Statusvariable. Dies zwingt das Custom HUD-Widget dazu, die Inventar-Komponenten neu auszuwerten und die korrekten Texturen zu zeichnen.

Verse-Code-Implementierung: Sicheres lokales Spawnen

Das folgende Verse-Script zeigt, wie man ein Custom-Entity-Prefab exakt an den Koordinaten des Spielers spawnt, bevor man es seinem Inventar hinzufügt. Dieser Ansatz umgeht das Distance-Culling-Problem, indem er die Replication innerhalb der aktiven Network-Bubble des Spielers erzwingt.

using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Playspaces }
using { /Verse.org/Simulation }
using { /Verse.org/SpatialMath }

# Custom device to safely manage item spawning and inventory allocation
inventory_spawner_device := class(creative_device):

    # Reference to the custom item prefab asset
    @editable
    ItemPrefab : entity_prefab = entity_prefab{}

    # Triggers the item generation and addition to the player's inventory
    GiveItemToPlayer(Player : player) : void =
        if (FortChar := Player.GetFortCharacter[]):
            # Get the player's current location to bypass spatial culling
            PlayerLocation := FortChar.GetTransform().Translation
            
            # Spawn the item prefab directly at the player's position.
            # This guarantees that the entity falls within the client's network relevancy bubble.
            SpawnResult := SpawnEntity(ItemPrefab, PlayerLocation, IdentityRotation())
            
            if (SpawnedEntity := SpawnResult?):
                # Retrieve the item component from the spawned entity
                if (ItemComponent := SpawnedEntity.GetComponent(item_component[])):
                    # Get the player's hotbar inventory component
                    if (InventoryComponent := FortChar.GetInventoryComponent[fort_inventory_weapon_hotbar_component]):
                        # Safely add the item to the hotbar.
                        # Since the entity was spawned locally, the client has already replicated
                        # its icon_component and mesh_component, preventing desyncs.
                        InventoryComponent.AddItem(ItemComponent)
                        Print("Successfully added item to hotbar without desync.")
                    else: 
                        Print("Error: Could not locate fort_inventory_weapon_hotbar_component.")
                else:
                    Print("Error: Spawned entity is missing item_component.")
            else:
                Print("Error: Failed to spawn the entity prefab.")

Inventar-States entkoppeln mit horizOn

Das Management dieser Replication-Workarounds auf Engine-Ebene kann schnell mühsam werden, insbesondere wenn deine Map wächst und du komplexe Gameplay-Mechaniken einführst. Wenn dein Spiel persistente Inventare, Cross-Match-Progression oder Trading-Systeme erfordert, erzeugt der Verlass auf physische Actor-Replication für Inventar-States einen massiven Flaschenhals.

Hier wird ein spezialisiertes Backend wie horizOn unschätzbar wertvoll.

Anstatt tatsächliche physische Entities an weit entfernten Orten zu spawnen, nur um deren Daten zu extrahieren, ermöglicht horizOn dir, deinen Game State von der Actor-Replication-Pipeline von Unreal zu entkoppeln.

Wenn ein Spieler ein Item verdient oder kauft, führt der Game Server einen leichtgewichtigen API-Call aus, um das Profil des Spielers auf horizOn zu aktualisieren. Die clientseitige UI liest diesen Status direkt aus dem Backend und rendert die Items mithilfe lokaler statischer Assets, ohne dass irgendwelche Actors über das Netzwerk repliziert werden müssen.

Diese Architektur eliminiert entfernungsbedingte Desyncs, garantiert eine sichere Speicherung der Inventardaten und reduziert die Netzwerklast des Servers drastisch.

Best Practices für High-Performance UEFN-Networking

Wenn du dich dafür entscheidest, Spatial Replication in UEFN manuell zu verwalten, befolge diese Industry Best Practices, um Network Overhead und Desyncs zu minimieren:

  1. Immer lokal instanziieren: Halte transiente Item-Spawner nah an den Spielercharakteren, um eine sofortige Replication zu garantieren.
  2. Visuelle Fallbacks implementieren: Gestalte deine Custom-UI-Widgets so, dass sie Platzhalter-Icons rendern, falls die Komponenten eines Items noch nicht repliziert wurden.
  3. Daten von der Optik entkoppeln: Verwende Verse-Structs, um den logischen Zustand von Items (Haltbarkeit, Anzahl, Stats) zu verwalten, und nutze Entities ausschließlich für die visuelle Darstellung.
  4. Inventar-Operationen drosseln: Vermeide es, AddItem() oder RemoveItem() kurz nacheinander aufzurufen, da Network-Serialization-Queues unter hoher Last Updates verwerfen können.

Fazit & Nächste Schritte

Spatial-Replication-Bugs wie der uefn additem far distance bug zeigen, wie leicht lokale Einschränkungen der Engine das Spielerlebnis stören können. Wenn du verstehst, wie Network Relevancy und World Partition in UEFN funktionieren, kannst du intelligentere Spawning-Flows entwickeln, die Client- und Server-States im Einklang halten. Für Entwickler, die anspruchsvolle Spiele bauen, die persistente States, globale Spielerprofile und sichere Wirtschaftssysteme erfordern, ist der Schritt über die reine Engine-Ebene hinaus die ultimative Lösung.

Bereit, dein Multiplayer-Backend zu skalieren? Teste horizOn kostenlos oder wirf einen Blick in die API-Docs.


Quelle: Adding Item not working in far distance