Move arena runtime configuration into GameCore

- Replace FightSystem runtime properties with shared GameConfig
- Update dependent modules, commands, states, and tests
This commit is contained in:
2026-07-24 12:51:03 +02:00
parent f8cda32119
commit 12e085600e
45 changed files with 216 additions and 265 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ contains the mechanics that do not depend on a specific arena:
- reusable winner/draw results and score/last-remaining evaluation;
- the complete state-dependent lifecycle (one-shots, tasks, listeners, commands,
and countdowns);
- the FightSystem arena modes and typed JVM runtime properties;
- the FightSystem arena modes and shared JVM runtime configuration;
- observable, generic game-state transitions.
GameCore intentionally does not define a game-state enum. Each consumer supplies
@@ -11,7 +11,6 @@
package de.steamwar.gamecore
import de.steamwar.gamecore.config.GameRuntimeProperties
import java.util.Collections
import java.util.EnumSet
@@ -50,16 +49,6 @@ enum class ArenaMode {
@JvmField val NotOnBau: Set<ArenaMode> = complement(TEST, CHECK, PREPARE, REPLAY)
@JvmField val SeriousFight: Set<ArenaMode> = complement(TEST, CHECK, REPLAY)
@JvmStatic
fun from(properties: GameRuntimeProperties): ArenaMode = when {
properties.checkSchematicId != 0 -> CHECK
properties.prepareSchematicId != 0 -> PREPARE
properties.fightId >= 1 -> EVENT
properties.fightId == -1 -> TEST
properties.replayId != 0 -> REPLAY
else -> NORMAL
}
private fun complement(vararg modes: ArenaMode): Set<ArenaMode> =
immutable(EnumSet.complementOf(EnumSet.copyOf(modes.toSet())))
@@ -0,0 +1,65 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*/
package de.steamwar.gamecore
import java.util.UUID
/**
* Runtime configuration shared by all GameCore game modes.
*
* The values are supplied as JVM system properties by the game server launcher.
*/
object GameConfig {
@JvmField
val CheckSchemID: Int = System.getProperty("checkSchemID", "0").toInt()
@JvmField
val PrepareSchemID: Int = System.getProperty("prepareSchemID", "0").toInt()
@JvmField
val ReplayID: Int = System.getProperty("replay", "0").toInt()
@JvmField
val ConfigFile: String = System.getProperty("config", "config.yml")
@JvmField
val EventKampfID: Int = System.getProperty("fightID", "0").toInt()
@JvmField
val BlueLeader: UUID? = System.getProperty("blueLeader")?.let(UUID::fromString)
@JvmField
val RedLeader: UUID? = System.getProperty("redLeader")?.let(UUID::fromString)
@JvmField
val mode: ArenaMode = resolveArenaMode(CheckSchemID, PrepareSchemID, EventKampfID, ReplayID)
@JvmStatic
fun test(): Boolean = ArenaMode.Test.contains(mode)
@JvmStatic
fun replayserver(): Boolean = ReplayID < 0
internal fun resolveArenaMode(
checkSchemID: Int,
prepareSchemID: Int,
eventKampfID: Int,
replayID: Int,
): ArenaMode = when {
checkSchemID != 0 -> ArenaMode.CHECK
prepareSchemID != 0 -> ArenaMode.PREPARE
eventKampfID >= 1 -> ArenaMode.EVENT
eventKampfID == -1 -> ArenaMode.TEST
replayID != 0 -> ArenaMode.REPLAY
else -> ArenaMode.NORMAL
}
}
@@ -1,63 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*/
package de.steamwar.gamecore.config
import java.util.Properties
import java.util.UUID
/**
* Typed view of every JVM system property historically consumed by FightSystem.
*
* Other game modes use the same names and parser, so launch behavior is
* consistent across the complete GameCore family.
*/
data class GameRuntimeProperties(
val checkSchematicId: Int,
val prepareSchematicId: Int,
val replayId: Int,
val configFile: String,
val fightId: Int,
val blueLeader: UUID?,
val redLeader: UUID?,
) {
val isReplayServer: Boolean
get() = replayId < 0
companion object {
const val CHECK_SCHEMATIC_ID = "checkSchemID"
const val PREPARE_SCHEMATIC_ID = "prepareSchemID"
const val REPLAY_ID = "replay"
const val CONFIG_FILE = "config"
const val FIGHT_ID = "fightID"
const val BLUE_LEADER = "blueLeader"
const val RED_LEADER = "redLeader"
@JvmStatic
@JvmOverloads
fun load(properties: Properties = System.getProperties()): GameRuntimeProperties =
GameRuntimeProperties(
checkSchematicId = properties.int(CHECK_SCHEMATIC_ID),
prepareSchematicId = properties.int(PREPARE_SCHEMATIC_ID),
replayId = properties.int(REPLAY_ID),
configFile = properties.getProperty(CONFIG_FILE, "config.yml"),
fightId = properties.int(FIGHT_ID),
blueLeader = properties.uuid(BLUE_LEADER),
redLeader = properties.uuid(RED_LEADER),
)
private fun Properties.int(name: String): Int =
getProperty(name, "0").toInt()
private fun Properties.uuid(name: String): UUID? =
getProperty(name)?.let(UUID::fromString)
}
}
@@ -1,38 +1,31 @@
package de.steamwar.gamecore
import de.steamwar.gamecore.config.GameRuntimeProperties
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.junit.Test
import java.util.Properties
class ArenaModeTest {
@Test
fun resolvesEveryFightSystemArenaMode() {
assertThat(mode(), equalTo(ArenaMode.NORMAL))
assertThat(mode(GameRuntimeProperties.FIGHT_ID to "42"), equalTo(ArenaMode.EVENT))
assertThat(mode(GameRuntimeProperties.FIGHT_ID to "-1"), equalTo(ArenaMode.TEST))
assertThat(mode(GameRuntimeProperties.REPLAY_ID to "42"), equalTo(ArenaMode.REPLAY))
assertThat(mode(GameRuntimeProperties.PREPARE_SCHEMATIC_ID to "42"), equalTo(ArenaMode.PREPARE))
assertThat(mode(GameRuntimeProperties.CHECK_SCHEMATIC_ID to "42"), equalTo(ArenaMode.CHECK))
assertThat(mode(eventKampfID = 42), equalTo(ArenaMode.EVENT))
assertThat(mode(eventKampfID = -1), equalTo(ArenaMode.TEST))
assertThat(mode(replayID = 42), equalTo(ArenaMode.REPLAY))
assertThat(mode(prepareSchemID = 42), equalTo(ArenaMode.PREPARE))
assertThat(mode(checkSchemID = 42), equalTo(ArenaMode.CHECK))
}
@Test
fun keepsFightSystemResolutionPrecedence() {
val resolved = mode(
GameRuntimeProperties.CHECK_SCHEMATIC_ID to "1",
GameRuntimeProperties.PREPARE_SCHEMATIC_ID to "2",
GameRuntimeProperties.FIGHT_ID to "3",
GameRuntimeProperties.REPLAY_ID to "4",
)
val resolved = mode(checkSchemID = 1, prepareSchemID = 2, eventKampfID = 3, replayID = 4)
assertThat(resolved, equalTo(ArenaMode.CHECK))
}
private fun mode(vararg values: Pair<String, String>): ArenaMode {
val properties = Properties().apply {
values.forEach { (name, value) -> setProperty(name, value) }
}
return ArenaMode.from(GameRuntimeProperties.load(properties))
}
private fun mode(
checkSchemID: Int = 0,
prepareSchemID: Int = 0,
eventKampfID: Int = 0,
replayID: Int = 0,
): ArenaMode = GameConfig.resolveArenaMode(checkSchemID, prepareSchemID, eventKampfID, replayID)
}
@@ -0,0 +1,22 @@
package de.steamwar.gamecore
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.hamcrest.Matchers.nullValue
import org.junit.Test
class GameConfigTest {
@Test
fun usesFightSystemDefaults() {
assertThat(GameConfig.CheckSchemID, equalTo(0))
assertThat(GameConfig.PrepareSchemID, equalTo(0))
assertThat(GameConfig.ReplayID, equalTo(0))
assertThat(GameConfig.ConfigFile, equalTo("config.yml"))
assertThat(GameConfig.EventKampfID, equalTo(0))
assertThat(GameConfig.BlueLeader, nullValue())
assertThat(GameConfig.RedLeader, nullValue())
assertThat(GameConfig.mode, equalTo(ArenaMode.NORMAL))
assertThat(GameConfig.test(), equalTo(false))
assertThat(GameConfig.replayserver(), equalTo(false))
}
}
@@ -1,50 +0,0 @@
package de.steamwar.gamecore.config
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.hamcrest.Matchers.nullValue
import org.junit.Test
import java.util.Properties
import java.util.UUID
class GameRuntimePropertiesTest {
@Test
fun loadsEveryFightSystemRuntimeProperty() {
val blueLeader = UUID.randomUUID()
val redLeader = UUID.randomUUID()
val properties = Properties().apply {
setProperty(GameRuntimeProperties.CHECK_SCHEMATIC_ID, "11")
setProperty(GameRuntimeProperties.PREPARE_SCHEMATIC_ID, "12")
setProperty(GameRuntimeProperties.REPLAY_ID, "-13")
setProperty(GameRuntimeProperties.CONFIG_FILE, "event.yml")
setProperty(GameRuntimeProperties.FIGHT_ID, "14")
setProperty(GameRuntimeProperties.BLUE_LEADER, blueLeader.toString())
setProperty(GameRuntimeProperties.RED_LEADER, redLeader.toString())
}
val runtime = GameRuntimeProperties.load(properties)
assertThat(runtime.checkSchematicId, equalTo(11))
assertThat(runtime.prepareSchematicId, equalTo(12))
assertThat(runtime.replayId, equalTo(-13))
assertThat(runtime.configFile, equalTo("event.yml"))
assertThat(runtime.fightId, equalTo(14))
assertThat(runtime.blueLeader, equalTo(blueLeader))
assertThat(runtime.redLeader, equalTo(redLeader))
assertThat(runtime.isReplayServer, equalTo(true))
}
@Test
fun usesFightSystemDefaults() {
val runtime = GameRuntimeProperties.load(Properties())
assertThat(runtime.checkSchematicId, equalTo(0))
assertThat(runtime.prepareSchematicId, equalTo(0))
assertThat(runtime.replayId, equalTo(0))
assertThat(runtime.configFile, equalTo("config.yml"))
assertThat(runtime.fightId, equalTo(0))
assertThat(runtime.blueLeader, nullValue())
assertThat(runtime.redLeader, nullValue())
assertThat(runtime.isReplayServer, equalTo(false))
}
}