Kotlin Multiplatform sample heavily inspired by Wordle game and also Word Master and wordle-solver samples. The main game logic/state is included in shared KMP code with basic UI then in following clients
- iOS (SwiftUI)
- Android (Jetpack Compose)
- Desktop (Compose for Desktop)
The shared WordMasterService class exposes the game state as StateFlows:
val boardGuesses = StateFlow<ArrayList<ArrayList<String>>>() // letters entered on each row
val boardStatus = StateFlow<ArrayList<ArrayList<LetterStatus>>>() // per-letter result
val keyStatus = StateFlow<Map<String, LetterStatus>>() // best status per key, colours the keyboard
val guessError = StateFlow<String?>() // validation feedback
Each client renders a board of read-only tiles plus an on-screen keyboard. Key presses call
WordMasterService.addLetter() / removeLetter(), and submitGuess() validates the row against the
word list (surfacing "Not enough letters" / "Not in word list" via guessError) before evaluating it
and updating the flows above. The Compose clients observe state as following (with any updates to those
StateFlow's triggering recomposition)
val boardStatus by wordMasterService.boardStatus.collectAsState()
val keyStatus by wordMasterService.keyStatus.collectAsState()
On iOS we're using the KMP-NativeCoroutines library to map the StateFlow to Swift AsyncSequence. So, for example, our Swift view model includes
@Published public var boardStatus: [[LetterStatus]] = []
@Published public var boardGuesses: [[String]] = []
which are then updated using for example
let stream = asyncSequence(for: wordMasterService.boardStatus)
for try await data in stream {
self.boardStatus = data as! [[LetterStatus]]
}
let stream = asyncSequence(for: wordMasterService.boardGuesses)
for try await data in stream {
self.boardGuesses = data as! [[String]]
}
Any updates to boardStatus or boardGuesses will trigger our SwiftUI UI to be recomposed again.
- PeopleInSpace (https://github.com/joreilly/PeopleInSpace)
- GalwayBus (https://github.com/joreilly/GalwayBus)
- Confetti (https://github.com/joreilly/Confetti)
- BikeShare (https://github.com/joreilly/BikeShare)
- FantasyPremierLeague (https://github.com/joreilly/FantasyPremierLeague)
- ClimateTrace (https://github.com/joreilly/ClimateTraceKMP)
- GeminiKMP (https://github.com/joreilly/GeminiKMP)
- MortyComposeKMM (https://github.com/joreilly/MortyComposeKMM)
- StarWars (https://github.com/joreilly/StarWars)
- WordMasterKMP (https://github.com/joreilly/WordMasterKMP)
- Chip-8 (https://github.com/joreilly/chip-8)
- FirebaseAILogicKMPSample (https://github.com/joreilly/FirebaseAILogicKMPSample)