Background and Goals
Note: This post is a work in progress. Please let me know if you have experience or expertise to share!
I helped port Keep Talking and Nobody Explodes to 8 platform targets with 6 optional VR APIs and multiple storefronts with different services. We did this with the Unity game engine from a single main branch in source control. Through this process, I learned a little about what needs to be done to port and maintain a game on so many platforms.
This guide enumerates some general porting challenges that come up, regardless of which game engine is used, and describes how to solve each of them using the Godot game engine. In cases where there is currently no built-in solution, I have provided a link to proposals where there is discussion on the subject.
This article was last updated for Godot version 4.3.
Controlling Behaviour with Feature Tags:
Controlling App Size and Memory Usage:
- Selectively Excluding Resources
- Bulk Changing Import Parameters
- Texture Resolution and Compression
- Audio Compression
Tooling:
- Inspect Build for Resource Sizes
- Quickly Preview Exported Resources
- Quickly Debug on Target Platform
Controlling Behaviour with Feature Tags
Feature tags are the backbone of per-export configuration. You can either use built-in feature tags, such as pc
, mobile
, or web
or add your own custom feature tags, such as google_play
or meta_quest
.
Important note: Only built-in feature tags are available when running a project or scene from the editor! To test with custom feature tags, you must export the project or customize run instances. Note that customizing run instances will only change the runtime feature list and will not export the game, which means that export scripts, such as the Resource Remaps plugin, will not run.
Here are a few ways to configure your project based on its feature tags:
Project Settings
Each export can use different project settings by creating project setting overrides for specific feature tags. To enable this feature, you must first enable Advanced Project Settings.
The first override that matches a feature tag of your export will be used. If no override matches any of your export’s feature tags, the base project setting will be used.
Remapping Resources by Feature Tag
The Resource Remaps plugin allows you to remap any resource or file in your project to a different one when your project is exported, based on the feature tags of that export:
Here are some examples of how this plugin can be used:
- Remap high quality music files used in the PC exports to be low quality web music files in the web exports.
- Change button call-out textures to represent the controller used by the platform.
- Make menu scenes appear different in the mobile game than the PC game.
You can also write your own EditorExportPlugin to further customize resources during the export process.
Scripting: Platform Services and Capabilities
Platform services and capabilities can be enabled and disabled through scripting based on feature tags. For example, if your game supports leaderboards on Meta Quest and does not support them on Google Play, you can assign a leaderboards
feature tag to the Meta Quest Export and check for it in your code:
if OS.has_feature("leaderboards"):
pass # make leaderboards visible here
else:
pass # make leaderboards invisible here
Controlling App Size and Memory Usage
Selectively Excluding Resources
Textures, audio, and other large files that are specific to one export should not be included in other exports that cannot use them to keep the app size small. For example, textures specific to the Meta Quest export should not be included in the Google Play export. I recommend the following two ways to selectively exclude resources from your export…
Automatically Remapping Resources
The Resource Remaps plugin, mentioned above, will automatically exclude resources that are a part of a remap group, but are not used by the export.
Manually Excluding Resources
The export window in the Godot editor has a number of Export modes that control which resources are included in the export:
I recommend the “Export all resources in the project except resources checked below” mode instead of the options that automatically detect dependencies because the later will not automatically add new scenes or resources if the new resource cannot be detected as a dependency, such as a scene that is loaded through a script by its path. If a new scene or resource is not added to every export preset, a runtime error will occur and can only be seen on the export(s) that are missing the new resource.
Bulk Changing Import Parameters
These two Godot editor features help with applying import parameters to a large number of resources all at once:
Use these steps to multi-edit import parameters for files across different folders:
- Switch to the split view using the icon on the top right of the File System dock
- Filter files to match the file extension of the files you want to multi-edit, such as “.png” for all
png
texture files
When changing default import parameters, only newly imported resources will use these defaults. You can use the “Preset” button to apply these default parameters to all existing resources selected in the File System dock.
Texture Resolution and Compression
One of the simplest and most effective ways to reduce app size and memory usage is to change the texture resolution and compression import parameters. This change should not impact exports that use higher resolution textures, such as PC platforms. Additionally, you may desire higher resolution textures for high performance Android VR platforms such as Meta Quest, while using lower resolution textures for Android devices that download your game from an app store such as Google Play.
There is currently no built-in functionality in Godot 4 for this. A proposal to add this functionality can be found here.
Workarounds:
Custom scripting or a custom engine build can be used to generate or customize resources at export time with an EditorExportPlugin. If you take this approach, be aware of the the Texture2D Size Limit import parameter. Note that this Size Limit parameter will impact the size of Sprite2D nodes, etc. A new parameter that does not affect the behaviour of Nodes is in development.
Another approach is to duplicate the texture source files in your project to include both high and low quality versions and use the Resource Remaps plugin, mentioned above. The downside of this approach is that it is very easy to accidentally introduce platform-specific bugs in one texture, but not the other duplicate texture.
Audio Compression
Similar to changing texture resolution, changing audio compression parameters is an effective way to reduce app size and memory usage.
Microsoft WAV Files
There is currently no built-in functionality in Godot 4 for to change import parameters per-export. A proposal to add this functionality can be found here.
For now, I recommend simply using the same Microsoft WAV compression parameters for all exports of your project.
MP3 or Ogg Vorbis Files
Any changes to the file size and memory usage of MP3 and Ogg Vorbis files must be handled outside of the Godot editor.
In some cases, such as music files, it may be necessary to duplicate the project files to have a low quality and high quality version. Use the Resource Remaps plugin, mentioned above, to export the low quality version on mobile and web platforms and the high quality version on PC platforms.
Tooling
Inspect Build for Resource Sizes
When reducing the app size of an export, one of the most valuable things to know is the file size of each resource in your app package. Specifically, you want to know which are the worst contributors to an app size that is too large.
For each export preset in your project, select “Export PCK/ZIP…”, choose the .zip file extension, and extract the resulting zip file into a folder on your computer. Then use a file size analysis tool to determine which resources are taking up too much space in your build. This is an approximate method because final game package compression prevents knowing exactly how much any individual resource may be contributing to your app size without the tedious process of exporting a build with an without each specific resource.
I like to use WizTree on Windows, and there are many other tools like it for other platforms:
Quickly Preview Exported Resources
Especially when modifying import settings of a resource to reduce its file size in the final app, it can be useful to inspect what that resource will look or sound like without running the game.
The Godot editor currently allows for viewing the host platform’s imported texture at its largest mipmap level in the Inspector panel by double clicking the texture in the File System panel. I am not aware of any tooling that allows for this sort of functionality for other textures formats or resources. Please let me know if you know of any!
Quickly Debug on Target Platform
After porting your game, it is normal for the game’s behaviour to be different between exports. These differences make it important to be able to debug export-specific scripting issues by stepping through scripts with a scripting debugger attached.
You can do this using remote debugging and one-click deploy.