Skip to content

Repository files navigation

stroads

A Mini-Motorways-style resource/traffic game: you draw a road network and cars route themselves from houses to destinations along the shortest connected path. Built with Kotlin Multiplatform + Compose Multiplatform so the same game code runs on Android now and iOS later.

Docs

Project layout

composeApp/
  src/commonMain/kotlin/com/example/stroads/
    game/         # PURE Kotlin simulation — no UI, no platform types (portable)
      Grid.kt         # board + tiles
      Pathfinder.kt   # A* over the road network ("fast path algo")
      Car.kt          # a car following a cached path
      GameWorld.kt    # spawn/update loop, one house + one destination
    ui/
      GameScreen.kt   # Compose Canvas rendering + tap-to-place + game loop
    App.kt        # root composable (shared by both platforms)
  src/androidMain/  # MainActivity + manifest + theme (Android entry point)
  src/iosMain/      # MainViewController (iOS entry point)
iosApp/             # Xcode project that hosts the shared Compose UI on iOS

The golden rule for portability: keep game/ free of Compose and platform imports. Rendering/input live in ui/. That separation is what lets iOS reuse 100% of the game and most of the drawing.

Build & run — Android

java isn't on PATH globally; use the Android Studio bundled JBR:

export JAVA_HOME="/home/kalieki/Downloads/android-studio-quail3-linux/android-studio/jbr"
export PATH="$JAVA_HOME/bin:$PATH"
./gradlew :composeApp:assembleDebug   # build the Android APK
./gradlew :composeApp:installDebug    # build + install on a connected device/emulator

Or just open the folder in Android Studio and press Run.

Tests

Testing is a standing requirement: add or update tests with every change, and commit only when they're green. Run the suite on the JVM (no device):

./gradlew :composeApp:testAndroidHostTest

What's covered (all in composeApp/src/commonTest):

  • game/ — the whole simulation is pure, platform-free Kotlin, so it's fully unit-tested: buildings/footprints, grid rules, weighted A*, the car lifecycle, and the office-never-oversubscribed reservation invariant.
  • ui/ pure logic — the isometric projection is kept Compose-free (Iso) and tested, including a projectcellAt round-trip that guards tap→cell mapping.

Design rule that makes this possible: keep logic out of Compose. game/ has no Compose/platform imports, and rendering math (projection, sprite mapping) is extracted from the Compose renderer so it's testable without UI infrastructure.

Compose recomposition/rendering itself (e.g. HUD bindings) is verified on the emulator; a Robolectric/Compose-UI-test harness is a possible future addition.

Build & run — iOS (on a Mac)

The Gradle/Kotlin side is fully wired (iOS targets + framework + iosMain). On a Mac with Xcode: open iosApp/iosApp.xcodeproj, set your signing Team in iosApp/Configuration/Config.xcconfig (or the Signing pane), and Run. The build phase invokes ./gradlew :composeApp:embedAndSignAppleFrameworkForXcode to compile the shared framework.

iOS cannot be compiled on Linux — Apple targets require macOS. The .xcodeproj here is the standard KMP template; if Xcode complains, let it re-sync the file references (or regenerate from the KMP wizard) — the Swift/Kotlin sources are the real content.

Toolchain

Kotlin 2.2.10 · Compose Multiplatform 1.8.2 · AGP 9.3.1 · Gradle 9.5 · JDK 25 · compileSdk/targetSdk 37 · minSdk 24.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages