korlibs / korge

KorGE Game Engine. Multiplatform Kotlin Game Engine
https://korge.org/
Other
2.58k stars 125 forks source link

Example integration of korge with KMP app #2222

Open omkar-tenkale opened 7 months ago

omkar-tenkale commented 7 months ago

I already have a kotlin multiplatform app built using KMP and Compose Multiplatform.

In one screen of the app, I want to run a small korge game but I'm unable to figure out the setup.

tarikkeskin commented 2 months ago

Did you find any documentation or any example project to solve this issue ? @omkar-tenkale

omkar-tenkale commented 2 months ago

Nope

tarikkeskin commented 2 months ago

Is it possible or are we trying the wrong thing ? Could you please help us with this @soywiz

ygdrasil-io commented 2 months ago

Did you succeed at least in configuring the dependencies? Korge libraries are published on Maven Central just like any other Multiplatform library: https://mvnrepository.com/search?q=com.soywiz&sort=newest

For reference, I use Matrix and Image Features in this project: https://github.com/wgpu4k/wgpu4k/blob/main/examples/common/build.gradle.kts

tarikkeskin commented 2 months ago

@ygdrasil-io thank you for your reply. First of all , i also can add 'korlibs-image' dependencies with adding implementation(libs.korlibs.image) to commonMain.dependencies but when i can only see import korlibs.image. libraries not import korlibs.korge. libraries. When try to add plugin alias(libs.plugins.korge) i got this error: Caused by: org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$ArtifactResolveException: Could not resolve all files for configuration ':composeApp:iosArm64CInterop'.

tarikkeskin commented 2 months ago

any comment for my last response? @ygdrasil-io

ygdrasil-io commented 2 months ago

@tarikkeskin It's difficult to pinpoint the exact issue without examining the full stack, but it seems like the library you're using might not include support for iOS ARM64. Perhaps the version you're using doesn't support this architecture.

Additionally, if you're using the plugin with a non-pure Korge app, keep in mind that the plugin might not be designed for that scenario.

Soywiz would be the best person to ask for specific guidance on this, but you could try adding your Korge project like this:

import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
    id("org.jetbrains.kotlin.multiplatform") version "2.0.20"
    id("com.android.library") version "8.2.2"
}

kotlin {
    androidTarget {
        @OptIn(ExperimentalKotlinGradlePluginApi::class)
        compilerOptions {
            jvmTarget.set(JvmTarget.JVM_11)
        }
    }

    jvm()
    iosX64()
    iosArm64()
    iosSimulatorArm64()

    sourceSets {

        commonMain.dependencies {
            implementation("com.soywiz.korge:korge:6.0.0-beta4")
        }
    }
}

android {
    namespace = "test.korge"

}

Then, you can delve into the Korge source code to understand how rendering is handled across different targets.

ferranpons commented 1 month ago

It's possible to configure your project to use KorGE only by adding the dependency on your libs.versions.toml:

[plugins]
korge = { id = "com.soywiz.korge", version = "6.0.0-beta4" }

And then adding the plugin to your shared build.gradle.kts:

plugins {
    alias(libs.plugins.korge)
}

And finally adding the Scene on your compose code like this:

@Composable
    override fun Content() {
        LaunchedEffect("game") {
            main()
        }
    }

    private suspend fun main() = Korge {
        sceneContainer().changeTo { MyScene() }

    }

    class MyScene : Scene() {
        override suspend fun SContainer.sceneMain() {
            solidRect(100, 100, RGBA(Color.Red.toArgb()))
        }
    }

BUT there is a big problem right now: "CreateDefaultGameWindow" is not implemented for Android so it's not possible to use it. All this using the latest 6.0.0-beta4. 😢

@soywiz it seems that there are some people interested in the same functionality. Please could you take a look to this? Many thanks in advance 🙏

0megaD commented 1 month ago

@ferranpons

Current workarounds until it's supported 'out of the box': Android Compose Project (Not KMP)

  1. Add KorGE as a dependency for project.

I used api("com.soywiz.korge:korge:6.0.0-beta4") directly instead of the plugin because of conflicts with Kotlin plugin.

  1. Embed using the KorgeAndroidView and AndroidView. korgeModule() just contains the basic Korge() constructor with whatever screens / sizes are injected.
@Composable
fun getKorgeView(modifier: Modifier) {
    AndroidView(factory = { context ->
        val v = KorgeAndroidView(context)
        launch(Dispatchers.IO) { v.loadModule(korgeModule()) }
        v
    }, modifier)
}

korgeModule():

Korge(mainSceneClass = MenuScreen::class,
    virtualSize = Size(gameWidth, gameHeight),
    windowSize = Size(gameWidth, gameHeight),
    configInjector = {
        mapPrototype { MenuScreen() }
        mapPrototype { SplashScreen() }
        mapPrototype { GameScreen() }
        mapPrototype { OptionsScreen() }
        mapPrototype { LoadingScreens(get(), getOrNull()) }
    })
  1. Profit!

Android Compose inside KMP Project

  1. Add expected function

commonMain

@Composable
expect fun getKorgeView(modifier: Modifier = Modifier)
  1. Add actual function per platform (android depicted)

Note that korgeModule() can live inside commonMain and does not need to be added to androidMain

androidMain

@Composable
actual fun getKorgeView(modifier: Modifier) {
    AndroidView(factory = { context ->
        val v = KorgeAndroidView(context)
        launch(Dispatchers.IO) { v.loadModule(korgeModule()) }
        v
    }, modifier)
}
  1. Profit!

The result: https://github.com/user-attachments/assets/df39de35-6559-4161-9bca-94bafa9c2d7b

ferranpons commented 1 month ago

@0megaD thanks for your suggestion! 💯 🔝

I hope this is solved in a future release, for now, this solution works as a charm 😉