First FOnline Headless Project
This tutorial runs the engine-owned minimal project without another game repository. At the end, FOnline has configured and built a baker and headless server, baked an AngelScript module, started the server with an in-memory database, executed the project start callback, and shut down cleanly.
This is the first supported milestone, not a playable game. The starter deliberately has no client, map, critter, item, dialog, or GUI.
Prerequisites
Use a standalone FOnline checkout with submodules initialized. The validation wrapper requires:
- Git;
- Python 3;
- CMake 3.22 or newer;
- a C++20 toolchain supported by the host platform;
- the platform prerequisites described in Build Workflow.
The canonical scaffold is Examples/MinimalProject. Do not use an embedding game’s files to complete this tutorial.
Run the starter
From the engine repository root, run the command for the current host.
Windows x64:
cd Examples\MinimalProject
python validate.py
Linux x64:
cd Examples/MinimalProject
python3 validate.py
BuildTools recreates Workspace/validation-project, copies the canonical scaffold into it, links that copy back to the current engine checkout, configures the server and baker, builds them, bakes resources, and runs the StarterSmoke sub-config. The smoke runner has a 60-second timeout.
Confirm success
Near the end of the output, the server must report:
starter_project=FOnline Starter
starter_native_extension_value=42
starter_server_started
starter_smoke_passed
[starter-smoke] required lifecycle markers found
The command must exit with code zero. The native value proves that the server-scoped C++ source entered ServerLib, codegen generated its script binding, and baked AngelScript called it. The lifecycle markers prove that the module subscribed to Game.OnStart and ran after server initialization; a native process that merely started and stopped is not sufficient.
Generated files stay under Workspace/:
Examples/MinimalProject/Build/windows/is the Windows build/output tree;Examples/MinimalProject/Build/linux/is the Linux build/output tree.
Read the complete project
The starter is small enough to inspect in one pass:
| File | Responsibility |
|---|---|
Examples/MinimalProject/CMakeLists.txt |
Composes the public FOnline CMake stages and defines RunStarterSmoke. |
Examples/MinimalProject/FOnlineStarter.fomain |
Declares the minimum runtime settings, resource packs, and deterministic smoke sub-config. |
Examples/MinimalProject/Scripts/Starter.fos |
Defines a project setting, subscribes to server start, logs lifecycle markers, and requests a successful smoke shutdown. |
Examples/MinimalProject/StarterServerExtension.cpp |
Demonstrates one server-scoped native script export and one optional engine hook. |
Examples/MinimalProject/run_starter_smoke.py |
Enforces timeout, process result, native/script lifecycle markers, and baked remote-call metadata. |
Two constraints are intentional:
- The example does not enable the
Configbaker. That baker is for distributable runtime configuration and requires every engine setting to be initialized explicitly. - The example does not import all engine
CoreScripts. Several client-facing core modules require project enums, settings, and generated GUI symbols. Add them only with the matching project contracts.
Make and observe a script change
In Examples/MinimalProject/Scripts/Starter.fos, change the string returned by GetProjectName() while leaving the required smoke markers intact. Run the same validation command again.
The new value must appear in the starter_project=... line, followed by both required markers. This second run proves that the changed AngelScript source was copied and rebaked rather than served from stale workspace data.
Troubleshooting
ConfigBakerException: Main config baking error: aConfigresource pack was added without a complete project configuration. Remove it for this milestone or initialize the complete settings contract before packaging.Nothing was built in the module: one generated runtime side became empty after preprocessing. Keep at least one valid common declaration or split the project modules according to their supported sides.- Missing
WorldTime,GuiScreen, orGuiScreenssymbols: the fullCoreScriptsdirectory was imported without its project-owned metadata or generated GUI contracts. [starter-smoke] server timed out: inspect the preceding startup output. The script callback probably did not request shutdown, or initialization blocked beforeGame.OnStart.- Missing lifecycle markers with exit code zero: treat the run as failed;
run_starter_smoke.pyrejects this case.
Next steps
Continue with First Playable Client, First Content Change, and First Automated Test. Use Getting Started for the wider documentation map, Embedding FOnline in a Game Project before turning the scaffold into a separate repository, and Baking Pipeline before adding resource types.