Tips and tricks for working with O3DE

Tips for improving the development process

Launch the asset processor manually

Whenever you launch the editor (which you must do when you recompile your native code), the editor will try to connect to the asset processor. If it isn't running, it will launch it for you, and then wait for it to initialize. This is very slow. Fortunately, you rarely will have to relaunch the asset processor while developing, so it's safe to launch it once and keep it running at all times. That way, when you re-launch the editor it will connect to the existing instance and start up almost instantly.

Keep the Lua editor open

The built in Lua editor is kind of crappy, but it has one killer feature: the EBus panel. Basically, these are important APIs that are not actually documented anywhere since they're generated from reflection data at runtime. The Lua editor can connect to your game's editor instance, read all those APIs, and present them to you in a nice list. Even if you're not writing Lua, the EBus names and events are the same ones you'll use from C++. It's an invaluable tool!

Fortunately, the Lua editor is a standalone program, so it doesn't close when you close the editor. However, the EBus panel requires you to enable the remote tools gem for your project. This can be done with the project manager. Once that's done, you can connect the Lua editor to your game editor by clicking the weird-looking target button. Doing that will cause the EBus panel on the side to populate.

Get autocompletions for your IDE

You can tell CMake to generate a compile_commands.json file, which can be used by clangd to provide autocompletion and intelligent code features. If you have a text editor/IDE that supports LSPs, then you can feed this file to the clangd language server.

All you have to do is enable the CMAKE_EXPORT_COMPILE_COMMANDS flag in the root CMakeLists.txt file in your project folder. For example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
if(NOT PROJECT_NAME)
    cmake_minimum_required(VERSION 3.20)
    include(cmake/EngineFinder.cmake OPTIONAL)
    find_package(o3de REQUIRED)
    project(MyProject
        LANGUAGES C CXX
        VERSION 1.0.0.0
    )
    set(CMAKE_EXPORT_COMPILE_COMMANDS ON) #<---right here
    o3de_initialize()
endif()

Now whenever you reconfigure the project, the file will be generated in your build folder. Depending on your IDE, you may want to copy that out into the project root, or maybe set up a symbolic link.

If you followed along with the Fedora guide, you also need to make sure that clangd is running inside the same toolbox as O3DE, otherwise it might fail. You'll also probably need to run your IDE/text editor inside that toolbox, otherwise it won't be able to find clangd! That's why I named my toolbox dev rather than o3de, since it's a general purpose development toolbox, not just for running O3DE.

Reducing build times

If your project has C++ code, then you'll probably find yourself waiting around for things to compile. There are some easy ways I found to speed this up:

Use the "Mold" linker

The mold linker is ridiculously fast, and while I haven't encountered any issue using it with O3DE, it's possible that some broken edge cases exist. Still, the massive speed boost is well worth that risk IMO.

Disable unity builds

Unity builds are meant to improve build times, but in my experience they actually slow things down for the common case. The initial build will probably be faster with a unity build, but when you recompile after changing one file, it's probably faster to do a regular build. You'll have to test this out yourself with your own project though.

Use ccache

CCache is probably not going to be that useful, but when you're iterating on some code, testing a change, then undoing those changes, you'll probably find yourself recompiling the exact same code multiple times. In that case, ccache will help. It could also be very useful if you find yourself needing to compile the engine from source multiple times.