Lesson 12: Performance Optimization & Scalability
With movement, combat, matchmaking, UI, and audio in place, your battle royale is playableβbut with many players and a large map, frame rate and server load can drop. Performance optimization and scalability make the game smooth for everyone and keep servers stable under load.
In this lesson you will use Unreal's profiling tools to find bottlenecks, optimize replication and rendering, and configure scalability so the game runs well on a range of hardware. By the end, you will have a clear optimization workflow and settings that scale from low to high spec.
What You'll Learn
By the end of this lesson, you will be able to:
- Profile your game with Unreal's GPU and CPU tools (Stat commands, Profiler, Insights)
- Identify bottlenecks in rendering, replication, and Blueprint/C++
- Optimize replication (relevance, priority, and bandwidth) for many actors
- Tune rendering (LODs, draw calls, shadows, and scalability settings)
- Set performance targets (frame time, tick budget, server tick) and measure against them
- Apply scalability presets so low-end and high-end machines both run well
Why This Matters
Good performance and scalability:
- Keep players engaged β Stable frame rate and low latency feel fair and responsive
- Reduce server cost β Efficient replication and tick logic let you run more players per server
- Widen your audience β Scalability lets lower-spec machines run the game
- Support launch β A polished, smooth game stands up better at release
Prerequisites
Before starting this lesson, make sure you have:
- Completed Lessons 1β11 in this course
- A battle royale project with core gameplay (movement, weapons, matchmaking, UI, audio)
- A test map with multiple players or AI and a variety of assets
- Basic familiarity with Unreal Editor (Content Browser, World Outliner, Details)
Step 1: Establish Performance Targets and Baselines
Before optimizing, define what "good" looks like and measure where you are now.
Frame Rate and Frame Time
- Target: 60 FPS (16.67 ms frame time) on mid-range hardware; 30 FPS (33.33 ms) minimum on low-end.
- Measure: Use Stat FPS or Stat Unit in-game (tilde console). Stat Unit breaks down Game, Draw, and GPU time.
- Baseline: Run your busiest map with 10β20 players (or bots), record average and worst-case frame time. Note GPU and CPU (Game) time.
Server and Replication
- Target: Server tick at 30β60 Hz; replication bandwidth under your budget (e.g. 64β128 kbps per client).
- Measure: Stat Net shows replication traffic; Stat Game and server profilers show tick cost.
- Baseline: Run a dedicated server (or listen server) with multiple clients and note replication bytes per second and server frame time.
Pro Tip: Test with Release or Development builds and Shipping-like settings (e.g. no editor overhead). Editor PIE is useful for iteration but not for final performance numbers.
Step 2: Profiling with Unreal Tools
Use Unreal's built-in tools to find where time and bandwidth are spent.
In-Editor: Stat Commands
- Stat FPS β Current frame rate and frame time
- Stat Unit β Breakdown: Game thread, Draw thread, GPU. Find whether CPU or GPU is the bottleneck
- Stat Game β Game thread breakdown (tick, physics, etc.)
- Stat GPU β GPU timing by pass (base pass, shadows, etc.)
- Stat Net β Replication: bytes sent/received, channels, relevancy
Type these in the console (tilde) while playing. Leave them on during a typical 1β2 minute session and note the worst spikes.
Session Frontend and Unreal Insights
- Window > Developer Tools > Session Frontend β Capture a frame or a short session and view timing on the main threads
- Unreal Insights (external tool) β For deeper analysis, run your game with
-trace=defaultand open the .utrace in Unreal Insights to see detailed CPU/GPU timelines
Start with Stat Unit and Stat Net; if one thread or replication dominates, drill down with Session Frontend or Insights.
Common mistake: Optimizing the wrong thing. If Stat Unit shows GPU at 25 ms and Game at 3 ms, focus on rendering (LODs, draw calls, shadows), not Blueprint tick.
Step 3: Optimize Replication for Many Actors
In a battle royale, many actors (players, projectiles, pickups, vehicles) can replicate. Poor relevance and priority cause lag and bandwidth spikes.
Relevance and Net Cull Distance
- Relevance β Only replicate an actor to clients that "need" it (e.g. within range). Override IsNetRelevantFor in C++ or use Net Cull Distance (or custom logic in Blueprint) so distant actors do not replicate.
- Net Cull Distance β Set per-actor or per-class so actors beyond a distance are not considered for replication. Shrink this for small or unimportant actors (e.g. distant pickups).
Replication Priority
- Priority β High for players and critical gameplay (weapons, objectives); lower for cosmetics or distant props. Set Net Update Priority on actors or in Replication settings so important updates send first when bandwidth is limited.
- Replication frequency β Reduce update rate for slow-changing actors (e.g. environment) so fast-changing ones (players, projectiles) get more bandwidth.
Reduce Replicated Properties
- Replicate only what gameplay needs (position, rotation, state flags). Avoid replicating every tick if a lower rate is enough.
- Use RepNotify only when the client must react (e.g. health change); avoid heavy logic in RepNotify.
- Pro Tip: Run Stat Net while 20+ players are active. If "Out" bandwidth is high, look at relevance, priority, and property count per actor.
Step 4: Optimize Rendering and Draw Calls
Rendering often dominates frame time on the GPU. Focus on overdraw, draw calls, and LODs.
Level of Detail (LOD)
- Ensure static meshes and skeletal meshes have LODs (LOD0βLOD2 or more). Use Auto LOD (e.g. Simplygon, Unreal's built-in) or author them in your DCC tool.
- Set LOD screen size so distant objects switch to lower LODs and reduce triangle count. Test with Stat RHI or Stat GPU to confirm draw call and triangle count drop with distance.
Draw Calls and Batching
- Instanced Static Meshes (ISM) β Use for repeated geometry (foliage, props). Reduces draw calls and state changes.
- Hierarchical LOD (HLOD) β Combine distant meshes into fewer draw calls. Useful for large open maps.
- Occlusion β Ensure occluded objects are culled (Unreal does this by default; check that large occluders exist and that you are not overdrawing).
Shadows and Lighting
- Shadow distance β Reduce Shadow Distance in scalability or per-light so distant shadows are disabled or use cheaper cascades.
- Shadow resolution β Lower resolution or use Virtual Shadow Maps (UE5) with appropriate resolution for your target.
- Light count β Limit overlapping dynamic lights; prefer static or baked lighting where possible.
Pro Tip: Use Stat RHI to see draw call count. Aim to reduce calls (LOD, ISM, HLOD) until GPU time is within budget.
Step 5: Scalability Settings and Presets
Scalability lets you run the same game on low-end and high-end hardware by scaling quality.
Engine Scalability
- Edit > Project Settings > Engine > Scalability β Configure Resolution Scale, View Distance, Anti-Aliasing, Post Process, Shadows, Global Illumination, Reflections, Texture Quality for Low, Medium, High, Epic.
- Console: sg.ResolutionQuality, r.ShadowQuality, r.ViewDistanceScale (and similar) can be set at runtime or via Scalability UI (Options menu).
Presets
- Low β Lower resolution scale, shorter view distance, simpler shadows and post process. Target 30+ FPS on minimum spec.
- Medium / High / Epic β Step up quality for better hardware. Keep 60 FPS target on High for mid-range.
- Let players choose a preset or auto-detect based on initial benchmark.
Server-Side and Tick
- Server tick rate β 30 Hz is often enough for battle royale; 60 Hz for twitch gameplay. Lower tick rate reduces server CPU and can reduce replication frequency.
- Tick only when needed β Disable tick on actors that do not need per-frame updates (use timers or events instead).
Step 6: Mini Challenge
- Task: Profile your current map with Stat Unit and Stat Net with 10+ players (or bots). Write down GPU time, Game time, and replication bytes/sec. Apply at least one replication optimization (relevance or priority) and one rendering optimization (LOD or shadow distance). Re-measure and note the change.
- Checklist: Frame time improves or stays stable; replication bandwidth does not increase; no visible regression in quality at medium preset.
- Stretch: Add a simple in-game options menu that sets Scalability to Low/Medium/High and confirm FPS and quality change.
Share your before/after stats in the community or with your team.
Troubleshooting
Frame rate still low after optimization
- Confirm the bottleneck with Stat Unit (Game vs GPU). If GPU-bound, add LODs, reduce shadows, or lower resolution scale. If Game-bound, reduce tick cost or replication.
- Check for tick on many actors; move logic to events or timers.
Replication bandwidth too high
- Use Stat Net to see which actor classes send the most. Reduce replicated properties, increase Net Cull Distance, or lower update rate for non-critical actors.
- Ensure IsNetRelevantFor (or equivalent) excludes distant or irrelevant actors.
Server frame time spikes
- Profile server with Stat Game or Unreal Insights. Optimize heavy Blueprint or C++ tick; use async or lower frequency updates where possible.
- Consider lowering server tick rate if gameplay allows.
LODs popping or too aggressive
- Adjust LOD screen size and hysteresis so transitions are less noticeable. Test at multiple resolutions and FOVs.
Recap
- You established performance targets (frame time, replication bandwidth) and baselines using Stat FPS, Stat Unit, and Stat Net.
- You used Unreal profiling (Stat commands, Session Frontend, Insights) to find CPU and GPU bottlenecks.
- You optimized replication with relevance, Net Cull Distance, priority, and fewer replicated properties.
- You optimized rendering with LODs, instancing, HLOD, and shadow/view distance.
- You configured scalability presets so the game runs on a range of hardware.
Next Lesson
In Lesson 13: Anti-Cheat Systems & Security, you will design and implement client and server-side checks to keep your battle royale fair and secure. Performance and replication choices from this lesson will support those systems.
Related Resources
- Unreal Engine Profiling documentation β Stat commands, Session Frontend, and Insights
- Unreal Engine Replication β Relevance, priority, and bandwidth
- Optimizing Game Performance in Unity β Concepts that transfer across engines
Bookmark this lesson for ongoing optimization passes. If it helped, share it with your team or community.