Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions plugin/src/main/kotlin/gg/grounds/push/manifest/GroundsYaml.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ data class GroundsYaml(
* Architecture).
*/
val services: Map<String, ServiceDecl>? = null,
/**
* Agones knobs. Only meaningful for the types forge renders as a Fleet.
*/
val agones: Agones? = null,
/**
* Hands the GameServer's lifecycle to the matchmaker. Its mere presence makes forge render
* `GROUNDS_MATCHMAKING` onto the pod and declare the Agones `matches` counter with this
* capacity — and without the counter DECLARED, the matchmaker's allocation selector matches
* nothing and no match can ever be placed on the fleet.
*/
val matchmaking: Matchmaking? = null,
) {
data class Resources(val cpu: String? = null, val memory: String? = null)

Expand Down Expand Up @@ -68,6 +79,10 @@ data class GroundsYaml(
}
}

data class Agones(val replicas: Int? = null)

data class Matchmaking(val matchesPerServer: Int)

class GroundsYamlParseException(
message: String,
cause: Throwable? = null,
Expand Down Expand Up @@ -114,11 +129,14 @@ object GroundsYamlParser {
val resources = raw.optResources("resources")
val events = raw.optEvents("events")
val services = raw.optServices("services")
val agones = raw.optAgones("agones")
val matchmaking = raw.optMatchmaking("matchmaking")
return GroundsYaml(
name = name, type = type, baseImage = baseImage,
jar = jar, plugins = plugins,
target = target, resources = resources, flavors = flavors,
events = events, services = services,
agones = agones, matchmaking = matchmaking,
)
}

Expand All @@ -145,6 +163,38 @@ object GroundsYamlParser {
return v.ifEmpty { null }
}

private fun Map<*, *>.optAgones(key: String): Agones? {
val v = this[key] ?: return null
if (v !is Map<*, *>) throw GroundsYamlParseException(
"grounds.yaml: '$key' must be a mapping, got ${v.javaClass.simpleName}",
)
val replicas = v["replicas"]
return Agones(
replicas = when (replicas) {
null -> null
is Int -> replicas
else -> throw GroundsYamlParseException(
"grounds.yaml: 'agones.replicas' must be an integer",
)
},
)
}

private fun Map<*, *>.optMatchmaking(key: String): Matchmaking? {
val v = this[key] ?: return null
if (v !is Map<*, *>) throw GroundsYamlParseException(
"grounds.yaml: '$key' must be a mapping, got ${v.javaClass.simpleName}",
)
val perServer = v["matchesPerServer"]
?: throw GroundsYamlParseException(
"grounds.yaml: 'matchmaking.matchesPerServer' is required",
)
if (perServer !is Int) throw GroundsYamlParseException(
"grounds.yaml: 'matchmaking.matchesPerServer' must be an integer",
)
return Matchmaking(matchesPerServer = perServer)
}

private fun Map<*, *>.optResources(
key: String,
label: String = key,
Expand Down
14 changes: 14 additions & 0 deletions plugin/src/main/kotlin/gg/grounds/push/tasks/GroundsPushTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,20 @@ abstract class GroundsPushTask : DefaultTask() {
pluginSources: List<SourceRef>,
): String = Json.encodeToString(JsonObject.serializer(), buildJsonObject {
put("name", JsonPrimitive(manifest.name))
// Fleet knobs. Hand-built JSON means a block that is not named here simply
// does not exist as far as forge is concerned — `matchmaking:` was dropped
// in silence, so the fleet came up with no `matches` counter and no
// GROUNDS_MATCHMAKING, and the matchmaker could never place a match on it.
manifest.agones?.let { agones ->
put("agones", buildJsonObject {
agones.replicas?.let { put("replicas", JsonPrimitive(it)) }
})
}
manifest.matchmaking?.let { mm ->
put("matchmaking", buildJsonObject {
put("matchesPerServer", JsonPrimitive(mm.matchesPerServer))
})
}
// Forge maps these to the gg.grounds/events SA annotation + NATS_URL.
manifest.events?.takeIf { it.isNotEmpty() }?.let { events ->
put("events", buildJsonArray {
Expand Down