Skip to content

Start your own project

Starting a game on Labrador means copying the minimal sample and owning everything inside it. Your project is its own repository. Labrador sits inside it as a Git submodule, pinned to the commit you chose, and is built as part of your build.

This page calls the project mygame. Use your own name wherever that appears.

When you have finished, the project looks like this:

  • Directorymygame/
    • CMakeLists.txt your build, which builds Labrador first
    • CMakePresets.json
    • vcpkg.json the engine’s dependencies, at the engine’s versions
    • .gitignore
    • Directoryexternal/
      • Directorylabrador/ the engine, as a submodule
        • …
    • Directorygame/
      • CMakeLists.txt
      • main.cpp
      • Directorycontent/
        • …
      • Directorystates/
        • …
  1. Make the repository. In the x64 Native Tools Command Prompt:

    Terminal window
    cd C:\dev
    mkdir mygame
    cd mygame
    git init
  2. Add Labrador as a submodule:

    Terminal window
    git submodule add https://github.com/matt439/Labrador.git external/labrador

    Your repository now records exactly which commit of Labrador it builds against, and moving to a newer one is a change you make deliberately and commit. Anyone cloning your project needs git clone --recurse-submodules to get the engine too.

  3. Copy the minimal sample into a folder called game:

    Terminal window
    xcopy external\labrador\samples\minimal game /E /I
  4. Point its includes at the new folder. Includes in Labrador are written from the root of the repository, so the sample names its own headers as samples/minimal/.... In your project they are under game/. Change these lines:

    FileChange this lineTo this
    game/main.cpp#include "samples/minimal/states/hello_state.h"#include "game/states/hello_state.h"
    game/states/confirm_state.cpp#include "samples/minimal/states/confirm_state.h"#include "game/states/confirm_state.h"
    game/states/hello_state.cpp#include "samples/minimal/states/hello_state.h"#include "game/states/hello_state.h"
    game/states/hello_state.cpp#include "samples/minimal/states/confirm_state.h"#include "game/states/confirm_state.h"
  5. Replace game\CMakeLists.txt with this:

    game/CMakeLists.txt
    add_executable(MyGame WIN32
    main.cpp
    states/confirm_state.cpp
    states/hello_state.cpp
    )
    target_link_libraries(MyGame PRIVATE
    LabradorEngine
    labrador_settings
    )
    # Includes are written from the project root - "game/states/hello_state.h" -
    # so the directory above game/ is this target's include root.
    target_include_directories(MyGame PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")
    # Content is found beside the executable, so copy it there on every build.
    add_custom_target(game_content ALL)
    add_custom_command(TARGET game_content POST_BUILD
    COMMAND "${CMAKE_COMMAND}" -E copy_if_different
    "${CMAKE_CURRENT_SOURCE_DIR}/content/manifest.json"
    "$<TARGET_FILE_DIR:MyGame>/manifest.json"
    VERBATIM
    )
    add_custom_command(TARGET game_content POST_BUILD
    COMMAND "${CMAKE_COMMAND}" -E copy_directory_if_different
    "${CMAKE_CURRENT_SOURCE_DIR}/content/fonts"
    "$<TARGET_FILE_DIR:MyGame>/fonts"
    VERBATIM
    )
    add_dependencies(MyGame game_content)

    It is the sample’s build file with three changes. The program is called MyGame. The content target is game_content. And target_include_directories makes the folder above game the place your includes start from, which the sample did not need because Labrador’s root already was.

  6. Add the project’s own build files to the mygame folder.

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.26)
    project(MyGame LANGUAGES CXX)
    # Defines LabradorEngine and labrador_settings. Labrador is not the top-level
    # project here, so its tests, benchmarks and samples are not built.
    add_subdirectory(external/labrador)
    add_subdirectory(game)

    add_subdirectory(external/labrador) builds the engine library and defines two targets: LabradorEngine, and labrador_settings, which applies the engine’s compiler settings to your code too, warnings as errors included. Do not define your own labrador_settings; CMake stops at a second target with the same name.

    vcpkg.json
    {
    "name": "mygame",
    "version-string": "0.1.0",
    "dependencies": [
    {
    "name": "directxtk",
    "features": [
    "xaudio2redist"
    ]
    }
    ],
    "builtin-baseline": "d92484ed3c5020c6679d095ad3e5add907887b62"
    }

    vcpkg reads only the top-level project’s manifest, so your project names the engine’s dependencies itself. The builtin-baseline is Labrador’s own, which pins them to the versions the engine is built and tested with.

    CMakePresets.json
    {
    "version": 6,
    "cmakeMinimumRequired": { "major": 3, "minor": 26, "patch": 0 },
    "configurePresets": [
    {
    "name": "base",
    "hidden": true,
    "generator": "Ninja",
    "binaryDir": "${sourceDir}/out/build/${presetName}",
    "toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
    "architecture": { "value": "x64", "strategy": "external" }
    },
    {
    "name": "x64-debug",
    "inherits": "base",
    "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
    },
    {
    "name": "x64-release",
    "inherits": "base",
    "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
    }
    ],
    "buildPresets": [
    { "name": "x64-debug", "configurePreset": "x64-debug" },
    { "name": "x64-release", "configurePreset": "x64-release" }
    ]
    }
    .gitignore
    out/
  7. Build and run it:

    Terminal window
    cmake --preset x64-debug
    cmake --build --preset x64-debug
    out\build\x64-debug\game\MyGame.exe

    The window is the minimal sample’s, because so far the game is the minimal sample. The configure step installs the dependencies for this project; vcpkg reuses what it built for Labrador, so it is quicker than the first time.

  8. Commit it:

    Terminal window
    git add .
    git commit -m "Start from Labrador's minimal sample"

Development documentation (unreleased). Built from Labrador 862e08b of 2026-10-08.