The LocalNetworkAuthority component is a testing stub and single-player fallback that implements all network authority interfaces. It provides immediate approval for all network operations without actual networking.
If you're building a single-player only game and never plan to add networking, you can skip the network interfaces entirely. But if your game supports both modes and you have already wired in your Multiplayer solution (NGO, FishNet, etc), LocalNetworkAuthority is the clean way to handle the single-player path without conditional code everywhere.
For Real Multiplayer: LocalNetworkAuthority is NOT suitable for actual multiplayer games. It's designed for:
Testing and development
Single-player mode
A reference implementation for your own network authority
For real multiplayer, implement INetworkAuthority with your networking solution (NGO, Mirror, Photon, FishNet).
Or use the Setup Wizard (it adds this automatically when networking is enabled)
Inspector Settings
Property
Type
Default
Description
Simulate Network Delay
bool
false
Adds artificial latency to mimic real network conditions
Simulated Delay Ms
int
50
Delay in milliseconds (0-500) when simulation is enabled
Enable Debug Logging
bool
false
Logs all network operations to Console
Local Player Id
int
0
Player ID used for ownership tracking
Use Cases
1. Development & Testing
Enable debug logging to see how Enemy Masses makes network calls:
2. Single-Player Mode
Use LocalNetworkAuthority as your default authority for single-player games:
3. Reference Implementation
Study LocalNetworkAuthority to understand how to implement your own authority:
How It Works
Automatic Registration
When LocalNetworkAuthority starts, it automatically registers itself with the NetworkAuthorityProvider:
Immediate Approval
All operations are immediately approved since there's no network validation:
Operation
Behavior
Spawn Requests
Always approved, generates local network IDs
Damage Attempts
Always approved, no rollback possible
Move Commands
Always approved, immediate execution
Attack Commands
Always approved, immediate execution
Network ID Generation
LocalNetworkAuthority generates sequential network IDs starting from 1:
Implemented Interfaces
LocalNetworkAuthority implements INetworkAuthorityExtended, which includes:
Core Interfaces
Interface
Purpose
INetworkAuthority
Base authority (spawn + damage + command)
INetworkSpawnAuthority
Agent spawning and despawning
INetworkDamageAuthority
Damage validation and death tracking
INetworkCommandAuthority
RTS commands (move, attack, stop)
Extended Interfaces (Sub-Authorities)
Interface
Local Implementation
INetworkTransformAuthority
LocalTransformAuthority
INetworkStateAuthority
LocalStateAuthority
INetworkFogAuthority
LocalFogAuthority
INetworkProjectileAuthority
LocalProjectileAuthority
API Reference
Properties
Spawn Methods
Damage Methods
Command Methods
Helper Methods
Simulating Network Conditions
Enable network simulation to test how your game handles latency:
Inspector Setup
Check Simulate Network Delay
Set Simulated Delay Ms (e.g., 100 for 100ms latency)
What Gets Affected
Property
Effect
RoundTripTime
Returns simulatedDelayMs / 1000f
Actual Operations
Not delayed (only RTT property changes)
Note: The delay simulation only affects the RoundTripTime property. Actual operations still execute immediately. For true latency testing, use a real network with artificial delay.
Transitioning to Real Multiplayer
When you're ready for actual multiplayer, replace LocalNetworkAuthority with your own implementation:
Step 1: Remove LocalNetworkAuthority
Step 2: Create Your Authority
Step 3: Register Your Authority
Step 4: Handle Client vs Server
Troubleshooting
"Network authority not found" errors
Cause: LocalNetworkAuthority hasn't started yet or was destroyed.
Solution: Ensure LocalNetworkAuthority is on an active GameObject that starts before your spawning code.
Debug logging not showing
Cause: Enable Debug Logging is not checked.
Solution: Enable it in the Inspector.
Network IDs resetting
Cause: LocalNetworkAuthority was destroyed and recreated.
Solution: Keep the authority component persistent, or implement proper ID synchronization.
public class GameManager : MonoBehaviour
{
[SerializeField] private LocalNetworkAuthority localAuthority;
void Start()
{
if (!IsMultiplayerSession())
{
// LocalNetworkAuthority auto-registers on Start
// No additional setup needed
Debug.Log("Running in single-player mode");
}
}
}
// Example: Creating a custom authority based on LocalNetworkAuthority
public class MyNetworkAuthority : MonoBehaviour, INetworkAuthority
{
// Copy the structure from LocalNetworkAuthority
// Replace no-op methods with real network calls
public bool CanSpawnLocally(int factionIndex, Vector3 position,
Quaternion rotation, int count, int requestingPlayerId)
{
// LocalNetworkAuthority returns true
// Your implementation: Check with server
return NetworkManager.Singleton.IsServer;
}
}
void Start()
{
// Registers all authority interfaces at once
NetworkAuthorityProvider.SetAuthority(this);
}
void OnDestroy()
{
// Cleans up when removed
NetworkAuthorityProvider.ClearAuthorities();
}
// Always returns true (simulates "connected" state)
bool IsNetworkActive { get; }
// Always returns true (local player is the "host")
bool IsHost { get; }
// Always returns true (always has server authority)
bool IsServer { get; }
// Always returns false (not a dedicated server)
bool IsDedicatedServer { get; }
// Time since component started
float NetworkTime { get; }
// Simulated delay if enabled, otherwise 0
float RoundTripTime { get; }
// Configured local player ID
int LocalPlayerId { get; }
// Whether client prediction is enabled (always false)
bool EnableClientPrediction { get; }
// Always returns true - spawning always allowed
bool CanSpawnLocally(int factionIndex, Vector3 position,
Quaternion rotation, int count, int requestingPlayerId);
// Generates network IDs and tracks spawned agents
uint[] OnAgentsSpawned(int[] agentIndices, int factionIndex,
Vector3[] positions, Quaternion[] rotations, int ownerPlayerId);
// Removes network ID from tracking
void OnAgentDespawning(int agentIndex, uint networkId, DespawnReason reason);
// Generates sequential network IDs
uint GenerateNetworkId();
// Always returns true with next sequence number
bool OnDamageAttempt(uint targetNetworkId, float damage,
uint attackerNetworkId, Vector3 hitPoint, DamageType damageType,
out int sequence);
// Logs the confirmed damage (no-op otherwise)
void OnDamageConfirmed(uint targetNetworkId, float actualDamage,
float newHealth, bool isDead, int sequence);
// Tracks death and removes from spawned set
void OnAgentDeath(uint networkId, uint killerNetworkId,
int killerPlayerId, Vector3 deathPosition);
// Generate unique projectile IDs
int GenerateProjectileId();
// Check if a network ID is currently spawned
bool IsNetworkIdSpawned(uint networkId);
// Remove from GameObject or disable
Destroy(GetComponent<LocalNetworkAuthority>());
public class NGONetworkAuthority : NetworkBehaviour, INetworkAuthority
{
// Implement all interface methods with real networking
// See our NGO Integration Guide for a complete example
}
public override void OnNetworkSpawn()
{
if (IsServer)
{
NetworkAuthorityProvider.SetAuthority(this);
}
}
public bool CanSpawnLocally(int factionIndex, Vector3 position,
Quaternion rotation, int count, int requestingPlayerId)
{
// Only server can approve spawns
if (!IsServer) return false;
// Validate the request
return ValidateSpawnRequest(factionIndex, count, requestingPlayerId);
}