diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 739de1f0..5dfbba5e 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -39,6 +39,9 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
+ with:
+ submodules: true
+ fetch-depth: 0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
diff --git a/.gitmodules b/.gitmodules
index 37e5cd06..a8ec31b5 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
[submodule "ferricia"]
path = ferricia
url = https://github.com/bitsusei/TerraModulus-Ferricia-Engine
+[submodule "vector-math"]
+ path = vector-math
+ url = https://github.com/bitsusei/kotlin-vector-math
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index e254cd93..e3cab1e4 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,16 +1,16 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 00000000..e40fc1cc
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index 131e44d7..2e4da65a 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,7 @@
-
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index ba62ca49..00000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index ba9deec3..6e08a227 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -5,5 +5,6 @@
+
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 8541b9db..5a90eaf0 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -5,21 +5,64 @@ plugins {
kotlin("jvm") version "2.3.21"
kotlin("plugin.serialization") version "2.1.20"
id("org.jetbrains.kotlinx.atomicfu") version "0.27.0"
+ id("net.terramodulus.plugins.cargo") apply false
+// id("fr.stardustenterprises.rust.wrapper") version "3.2.4" apply false
application
+ kotlin("kapt") version "2.3.21"
}
-allprojects {
- apply(plugin = "org.jetbrains.kotlin.jvm")
+version = "0.0.1"
- version = "0.0.1"
+repositories {
+ mavenCentral()
+}
+
+project(":ferricia") {
+ // Candidates: fr.stardustenterprises.rust.wrapper
+ apply(plugin = "net.terramodulus.plugins.cargo")
- repositories {
- mavenCentral()
+ if (providers.gradleProperty("release").isPresent) configure {
+ release = true // use `-Prelease=true`
+ }
+ configure {
+ outputFile = release.map {
+ projectDir.resolve("target/${if (it) "release" else "debug"}/${System.mapLibraryName("ferricia")}")
+ }
+ }
+ // somehow, .cargo extension is unusable
+ tasks.register("buildClient") {
+ args = listOf("-F", "client")
+ println(outputFile.get())
+ }
+ tasks.register("buildServer") {
+ args = listOf("-F", "server")
+ }
+ configurations {
+ create("client") {
+ isCanBeConsumed = true
+ isCanBeResolved = false
+ }
+ create("server") {
+ isCanBeConsumed = true
+ isCanBeResolved = false
+ }
+ }
+ artifacts {
+ add("client", tasks.named("buildClient"))
+ add("server", tasks.named("buildServer"))
}
}
configure(listOf(project(":kernel"), project(":internal"))) {
configure(listOf(project("common"), project("client"), project("server"))) {
+ apply(plugin = "org.jetbrains.kotlin.jvm")
+
+ version = rootProject.version
+
+ repositories {
+ mavenCentral()
+ }
+
sourceSets.main {
kotlin.srcDir("kotlin")
resources.srcDir("resources")
@@ -61,7 +104,26 @@ project(":kernel") {
}
}
+project(":kernel:client") {
+ dependencies {
+ implementation(project(":ferricia", "client"))
+ }
+}
+project(":kernel:server") {
+ dependencies {
+ implementation(project(":ferricia", "server"))
+ }
+}
+
+configure(listOf(project(":internal:common"), project(":kernel:common"))) {
+ dependencies {
+ api("com.cout970:kotlin-vector-math:0.1.0")
+ }
+}
+
project(":kernel:common") {
+ apply(plugin = "org.jetbrains.kotlin.kapt")
+
dependencies {
api("org.jetbrains:annotations:26.1.0")
api("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1")
@@ -77,7 +139,7 @@ project(":kernel:common") {
implementation("org.apache.logging.log4j:log4j-api:2.24.3")
implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.24.3")
implementation(platform("org.apache.logging.log4j:log4j-bom:2.24.3"))
- annotationProcessor("org.apache.logging.log4j:log4j-core:2.24.3")
+ kapt("org.apache.logging.log4j:log4j-core:2.24.3")
runtimeOnly("com.lmax:disruptor:4.0.0")
api("io.github.oshai:kotlin-logging-jvm:7.0.3")
implementation("net.sf.jopt-simple:jopt-simple:5.0.4")
@@ -86,10 +148,12 @@ project(":kernel:common") {
project(":kernel:client").dependencies {
implementation("net.sf.jopt-simple:jopt-simple:5.0.4")
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0")
}
project(":kernel:server").dependencies {
implementation("net.sf.jopt-simple:jopt-simple:5.0.4")
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0")
}
project(":internal:common").dependencies {
@@ -112,28 +176,6 @@ configure(listOf(project(":kernel:server"), project(":kernel:client"))) {
}
}
-/** Build Ferricia Engine with Cargo */
-tasks.register("cargoBuildClient") {
- onlyIf {
- !gradle.taskGraph.hasTask(":kernel:server:jar")
- }
- workingDir = rootProject.file("ferricia")
- commandLine("cargo", "build")
- if (project.hasProperty("release")) args("--release") // use `-Prelease=true`
- args("-F", "client")
-}
-tasks.register("cargoBuildServer") {
- onlyIf {
- !gradle.taskGraph.hasTask(":kernel:client:jar")
- }
- workingDir = rootProject.file("ferricia")
- commandLine("cargo", "build")
- if (project.hasProperty("release")) args("--release") // use `-Prelease=true`
- args("-F", "server")
-}
-project(":kernel:client").tasks.named("jar") { dependsOn(tasks.named("cargoBuildClient")) }
-project(":kernel:server").tasks.named("jar") { dependsOn(tasks.named("cargoBuildServer")) }
-
tasks.register("buildClient") {
group = "build"
description = "Build client"
@@ -151,17 +193,13 @@ tasks.named("run") {
tasks.register("runClient") {
group = "application"
description = "Run client"
- dependsOn("cargoBuildClient")
dependsOn(":kernel:client:run")
}
-project(":kernel:client").tasks.named("run").get().mustRunAfter(tasks.named("cargoBuildClient"))
tasks.register("runServer") {
group = "application"
description = "Run server"
- dependsOn("cargoBuildServer")
dependsOn(":kernel:server:run")
}
-project(":kernel:server").tasks.named("run").get().mustRunAfter(tasks.named("cargoBuildServer"))
configure(listOf(project(":kernel:server"), project(":kernel:client"))) {
distributions {
@@ -170,15 +208,12 @@ configure(listOf(project(":kernel:server"), project(":kernel:client"))) {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
into("lib") {
val dir = if (project.hasProperty("release")) "release" else "debug"
+ from("$rootDir/ferricia/target/$dir/${System.mapLibraryName("ferricia")}")
if (OperatingSystem.current().isWindows) from(
- "$rootDir/ferricia/target/$dir/ferricia.dll",
"$rootDir/ferricia/target/$dir/oded.dll",
"$rootDir/ferricia/target/$dir/OpenAL32.dll",
"$rootDir/ferricia/target/$dir/SDL3.dll",
- ) else { // suppose UNIX
- // other libs should be installed on user's end directly
- from("$rootDir/ferricia/target/$dir/libferricia.so")
- }
+ ) // for UNIX, other libs should have been installed on user's end directly
}
}
}
@@ -197,9 +232,18 @@ configure(listOf(project(":kernel:server"), project(":kernel:client"))) {
}
tasks.named("run") {
- jvmArgs("-Djava.library.path=${rootProject.file("ferricia/target/${
- if (project.hasProperty("release")) "release" else "debug"
- }").path}")
+ jvmArgs(
+ "-Djava.library.path=${
+ rootProject.file(
+ "ferricia/target/${
+ if (project.hasProperty("release")) "release" else "debug"
+ }"
+ ).path
+ }"
+ )
args("--screen-size", "800x500")
}
}
+dependencies {
+ testImplementation(kotlin("test"))
+}
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
new file mode 100644
index 00000000..fb5da883
--- /dev/null
+++ b/buildSrc/build.gradle.kts
@@ -0,0 +1,22 @@
+/*
+ * SPDX-FileCopyrightText: 2026 TerraModulus Team and Contributors
+ * SPDX-License-Identifier: LGPL-3.0-only
+ */
+
+plugins {
+ `kotlin-dsl`
+}
+
+repositories {
+ mavenCentral()
+ gradlePluginPortal()
+}
+
+gradlePlugin {
+ plugins {
+ register("cargoPlugin") {
+ id = "net.terramodulus.plugins.cargo"
+ implementationClass = "CargoPlugin"
+ }
+ }
+}
diff --git a/buildSrc/src/main/kotlin/CargoExtension.kt b/buildSrc/src/main/kotlin/CargoExtension.kt
new file mode 100644
index 00000000..520ea2ae
--- /dev/null
+++ b/buildSrc/src/main/kotlin/CargoExtension.kt
@@ -0,0 +1,12 @@
+/*
+ * SPDX-FileCopyrightText: 2026 TerraModulus Team and Contributors
+ * SPDX-License-Identifier: LGPL-3.0-only
+ */
+
+import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.provider.Property
+
+interface CargoExtension {
+ val release: Property
+ val outputFile: RegularFileProperty
+}
diff --git a/buildSrc/src/main/kotlin/CargoPlugin.kt b/buildSrc/src/main/kotlin/CargoPlugin.kt
new file mode 100644
index 00000000..843b7d61
--- /dev/null
+++ b/buildSrc/src/main/kotlin/CargoPlugin.kt
@@ -0,0 +1,21 @@
+/*
+ * SPDX-FileCopyrightText: 2026 TerraModulus Team and Contributors
+ * SPDX-License-Identifier: LGPL-3.0-only
+ */
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+class CargoPlugin : Plugin {
+ override fun apply(target: Project) {
+ val extension = target.extensions.create("cargoConfig", CargoExtension::class.java)
+
+ extension.release.convention(false)
+
+ target.tasks.withType(CargoTask::class.java).configureEach {
+ release.convention(extension.release)
+ outputFile.convention(extension.outputFile)
+ inputs.dir(project.projectDir)
+ }
+ }
+}
diff --git a/buildSrc/src/main/kotlin/CargoTask.kt b/buildSrc/src/main/kotlin/CargoTask.kt
new file mode 100644
index 00000000..1ee19e2a
--- /dev/null
+++ b/buildSrc/src/main/kotlin/CargoTask.kt
@@ -0,0 +1,47 @@
+/*
+ * SPDX-FileCopyrightText: 2026 TerraModulus Team and Contributors
+ * SPDX-License-Identifier: LGPL-3.0-only
+ */
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.model.ObjectFactory
+import org.gradle.api.provider.ListProperty
+import org.gradle.api.provider.Property
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Optional
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+import org.gradle.process.ExecOperations
+import javax.inject.Inject
+
+abstract class CargoTask @Inject constructor(private val execOperations: ExecOperations, objectFactory: ObjectFactory) : DefaultTask() {
+// @get:Input
+// abstract val environment: Property