Phase 6 concludes with the most satisfying part: seeing it all come together. We have three game engines (Tic-Tac-Toe, Scrabble, Chess) and two native platforms (macOS, Windows). This week is about project architecture — how to structure your folders, your build scripts, and your asset pipelines so that you aren't manually copying files back and forth.

The "Single Source of Truth" Structure

A professional multi-platform project keeps the logic shared and the platforms isolated. We organize our repository so that each app project links to the same shared C++ files.

/project-root
  /shared
    /engines
      tic-tac-toe.cpp
      scrabble.cpp
      chess.cpp
    /bridge
      native_bridge.h
  /macos
    PositionGames.xcodeproj (Links to /shared)
  /windows
    PositionGames.sln (Links to /shared)
  /assets
    board_textures/
    sounds/

One build system to rule both platforms: CMake

Xcode and Visual Studio are great IDEs, but their project files are platform-specific. The standard answer for shared C++ is CMake — a meta-build system that generates Xcode projects on Mac and Visual Studio solutions on Windows from the same CMakeLists.txt. You describe what to compile once; CMake produces the right project file for whichever IDE you open.

# shared/CMakeLists.txt — used by both platforms
cmake_minimum_required(VERSION 3.20)
project(PositionGamesEngine CXX)
set(CMAKE_CXX_STANDARD 20)

add_library(engine STATIC
    engines/tic_tac_toe.cpp
    engines/scrabble.cpp
    engines/chess.cpp
    bridge/native_bridge.cpp
)
target_include_directories(engine PUBLIC include)

On Mac you run cmake -G Xcode and open the resulting .xcodeproj. On Windows you run cmake -G "Visual Studio 17" and open the .sln. Both IDEs see the same source files, the same compiler flags, the same dependencies. Add a file to CMakeLists.txt once and both platforms pick it up.

Architectures: fat binaries and you

Modern hardware is split. Macs are arm64 (Apple Silicon) and x86_64 (Intel). Windows is x64 and increasingly ARM64. Phones are arm64 only. Your engine has to compile for whichever architectures your target users actually have.

Apple's answer is the universal binary: one .app bundle with both arm64 and x86_64 slices, glued together by lipo. Set ARCHS = arm64 x86_64 in Xcode and the build produces both. The OS picks the right slice at launch. Universal binaries are roughly 1.7× the size of a single-architecture build — usually fine for a game, never an issue for an engine.

Windows handles it differently: x64 and ARM64 ship as separate installers (or the new "ARM64EC" hybrid for partial native + x64 emulation). MSIX bundles can carry both, but most apps still publish two downloads.

Conditional Compilation

Sometimes the engine needs to behave slightly differently on each platform. We use preprocessor macros to handle these cases without cluttering the main logic. For example, macOS might use a specific fast math library that Windows doesn't have.

#ifdef __APPLE__
    // macOS / iOS specific optimization
    #include <Accelerate/Accelerate.h>
#elif _WIN32
    // Windows specific optimization
    #include <intrin.h>
#endif

One engine, three games, multiple platforms. The beauty of a C++ core is that it doesn't care if it's running on a high-end Mac or a budget Windows laptop.

The Final Polish

Now that the code is linked, we focus on the experience. This means adding high-resolution textures, smooth animations in SwiftUI and WinUI, and ensuring that the AI feels "alive" by adding small delays so it doesn't move instantly.

// Artificial thinking delay in Swift
func playAIMove() {
    isThinking = true
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        let move = engine.bestMove()
        self.apply(move)
        isThinking = false
    }
}

Try it yourself

What's next

Congratulations! You've built a suite of native apps from the ground up. You know the hardware, the memory, the logic, and the bridge. Now, we enter the final Phase: The AI Hero. We'll explore how modern AI tools can accelerate your development, and why everything you've learned so far makes you a master of these new tools.

Week 48 is Vibe Coding 101.

Quick check

1. What is CMake?
  1. An IDE
  2. A meta-build tool that generates Xcode projects on Mac and Visual Studio solutions on Windows from one CMakeLists.txt
  3. A package manager
Reveal Answer

Answer: B. Describe what to build once; CMake produces the platform-specific project files for your IDE of choice.

2. What is a 'universal binary' on macOS?
  1. An app that runs on every OS
  2. An app bundle containing both arm64 and x86_64 slices, so it runs on Apple Silicon and Intel
  3. A signed installer
Reveal Answer

Answer: B. macOS's loader picks the right slice at launch. About 1.7× the size of a single-arch build, but covers both processor families.

3. What does '#ifdef __APPLE__' do?
  1. Conditionally compiles platform-specific code only on Apple platforms
  2. Forces the code to run on iOS
  3. Disables optimisation on Apple
Reveal Answer

Answer: A. Combined with _WIN32, it lets one shared codebase contain platform-specific blocks while staying portable.