I often review projects where customers with careers in game development creates game-switching applications. These apps have a main menu presenting multiple game choices for players. The main concerns are ensuring quick game-switching times and optimal performance across games. In this blog post, we’ll explore various strategies based on project needs and share best practices for any game environment.
Managing Game Executables
When planning a multi-application environment for gaming or simulations, deciding how to manage game executables is crucial. Consider these factors:
- Number of games on the platform
- Size of the games
- Unity versions used
- Target hardware, memory, CPU, and disk speed
These factors help determine whether to use separate executables for each game, one shared executable, or a combination of both for optimal performance.
Multiple Executables
Using multiple executables is ideal for games with different Unity versions. This approach reduces game-switching time by caching executables in memory. However, it can strain memory if games have a high memory footprint or if there are many games.
Single Executable
For games using the same Unity version, sharing a single executable can ease memory constraints. Games can be in a single Unity project or have individual projects. This method may slow game switching, so follow loading best practices to minimize this drawback.
Best Loading Strategies
Fast loading times are vital, especially for game-switching apps. Here are some strategies:
Use Addressables
Addressables load content as needed, reducing initial load times and preventing CPU bottlenecks. Learn more in the Addressables: Planning and Best Practices blog post.
Asynchronous Loading
Use asynchronous loading APIs to load scenes efficiently. Set Application.backgroundLoadingPriority
to High during loading screens and lower it once loading is complete.
Async Texture Upload
Async texture loading reduces load time by managing texture and mesh uploads to the GPU. The Understanding Async Upload Pipeline blog post explains this process.
Additional Tips
- Minimize scene content and use a bootstrap scene.
- Disable cameras during loading.
- Disable UI Canvases while populating.
- Parallelize network requests.
- Avoid complex
Awake/Start
implementations. - Always use texture compression.
- Stream large media files.
- Avoid JSON Serializer; use binary serializers instead.
Managing Background CPU Usage
In multi-game environments, background CPU activity can affect performance. When games are not active, their CPU usage can hinder the performance of the active game. Prevent CPU starvation by setting Run in Background
to false in Unity settings. This stops the Unity game loop when the game is not in focus. Use the following script to change the setting dynamically:
csharpCopy codepublic class ExampleClass : MonoBehaviour
{
void Example()
{
Application.runInBackground = false;
}
}
Ensure custom scripting threads of non-playing games are set to sleep using Thread.Sleep
. Proper synchronization with the main Unity thread is essential to avoid issues like deadlocks and race conditions.
Preventing Memory Leaks
Identifying and fixing memory leaks can be challenging. Here are some tips to prevent leaks:
- Delete new objects/assets when not needed. Release unused assets if using Addressables.
- Properly remove assets from memory when loading/unloading scenes. Use
Resources.UnloadUnusedAssets
to clean up assets. - Avoid frequent use of
Instantiate
andDestroy
. If necessary, remove all references to prevent leaked shell objects. - Manage events using Singletons carefully. Implement the Weak Event Pattern or
IDisposable
in objects listening to singleton events. - Perform profiling, CI/CD testing, and stress testing early to detect and address leaks promptly.
Conclusion
By following these strategies, you can optimize your game development process and game-switching applications for quick transitions and smooth performance. Managing executables, loading efficiently, controlling background CPU usage, and preventing memory leaks are key to creating a seamless gaming experience. Use these tips to enhance your game development projects and ensure your games run smoothly across different environments.