Overview
The Parameter system provides type-safe command arguments with validation, auto-completion, and flexible configuration. Parameters can be required or optional, support varargs, and include custom verification logic.
Package: net.ccbluex.liquidbounce.features.command
Parameter Class
class Parameter<T : Any>(
val name: String,
val required: Boolean,
val default: T?,
val vararg: Boolean,
val verifier: Verificator<T>?,
val autocompletionHandler: AutoCompletionProvider?
)
Parameter name for display and error messages
Whether parameter must be provided
Default value if parameter is optional and not provided
If true, parameter consumes all remaining arguments as array
Validates and parses parameter value
autocompletionHandler
AutoCompletionProvider?
required
Provides completion suggestions
Properties
Parent command (set automatically)
Parameter index in command (set automatically)
Translated parameter descriptionval description: MutableComponent
Methods
nameAsText
fun nameAsText(): Component
Returns formatted parameter name with hover description:
- Required:
<name>
- Optional:
[<name>]
- Vararg:
<name>...
Verificator Interface
fun interface Verificator<T : Any> {
fun verifyAndParse(sourceText: String): Result<out T>
sealed interface Result<T : Any> {
class Ok<T : Any>(val mappedResult: T) : Result<T>
class Error(val errorMessage: String) : Result<Nothing>
}
}
Creating Verificators
// Integer with range
val intVerifier = Parameter.Verificator { text ->
val value = text.toIntOrNull()
if (value == null) {
Parameter.Verificator.Result.Error("Must be a number")
} else if (value !in 1..100) {
Parameter.Verificator.Result.Error("Must be between 1 and 100")
} else {
Parameter.Verificator.Result.Ok(value)
}
}
// Module verification
val moduleVerifier = Parameter.Verificator { text ->
val module = ModuleManager[text]
Parameter.Verificator.Result.ofNullable(module) {
"Module '$text' not found"
}
}
// Enum verification
val enumVerifier = Parameter.Verificator<MyEnum> { text ->
try {
Parameter.Verificator.Result.Ok(MyEnum.valueOf(text))
} catch (e: IllegalArgumentException) {
Parameter.Verificator.Result.Error("Invalid value. Valid values: ${MyEnum.values().joinToString()}")
}
}
AutoCompletionProvider
fun interface AutoCompletionProvider {
fun autocomplete(begin: String, args: List<String>): Iterable<String>
}
Current partial text of the parameter being completed
All current arguments of the command
Creating Auto-completion Providers
// Module names
val moduleCompletion = AutoCompletionProvider { begin, _ ->
ModuleManager
.filter { it.name.startsWith(begin, ignoreCase = true) }
.map { it.name }
}
// File names
val fileCompletion = AutoCompletionProvider { begin, _ ->
File(".")
.listFiles { file -> file.name.startsWith(begin, ignoreCase = true) }
?.map { it.name }
?: emptyList()
}
// Contextual completion
val contextualCompletion = AutoCompletionProvider { begin, args ->
when (args.getOrNull(0)) {
"add" -> getAvailableItems(begin)
"remove" -> getCurrentItems(begin)
else -> emptyList()
}
}
Parameter Examples
Required String Parameter
val name = parameter<String>(
name = "name",
required = true
)
Optional Integer Parameter
val count = parameter(
name = "count",
required = false,
default = 10,
verifier = Parameter.Verificator { text ->
val value = text.toIntOrNull()
Parameter.Verificator.Result.ofNullable(value) {
"Must be a number"
}
}
)
Vararg String Parameter
val message = parameter<String>(
name = "message",
required = true,
vararg = true
)
// Usage: .say Hello world this is a message
// message = ["Hello", "world", "this", "is", "a", "message"]
Module Parameter with Validation
val module = parameter(
name = "module",
required = true,
verifier = Parameter.Verificator { text ->
val module = ModuleManager[text]
Parameter.Verificator.Result.ofNullable(module) {
"Module '$text' not found"
}
},
autocompletionHandler = AutoCompletionProvider { begin, _ ->
ModuleManager
.filter { it.name.startsWith(begin, ignoreCase = true) }
.map { it.name }
}
)
Float Parameter with Range
val speed = parameter(
name = "speed",
required = false,
default = 1.0f,
verifier = Parameter.Verificator { text ->
val value = text.toFloatOrNull()
when {
value == null -> Parameter.Verificator.Result.Error("Must be a number")
value < 0.1f -> Parameter.Verificator.Result.Error("Must be at least 0.1")
value > 10.0f -> Parameter.Verificator.Result.Error("Must be at most 10.0")
else -> Parameter.Verificator.Result.Ok(value)
}
}
)
Boolean Parameter
val enabled = parameter(
name = "enabled",
required = false,
default = true,
verifier = Parameter.Verificator { text ->
when (text.lowercase()) {
"true", "yes", "on", "1" -> Parameter.Verificator.Result.Ok(true)
"false", "no", "off", "0" -> Parameter.Verificator.Result.Ok(false)
else -> Parameter.Verificator.Result.Error("Must be true/false")
}
},
autocompletionHandler = AutoCompletionProvider { begin, _ ->
listOf("true", "false").filter { it.startsWith(begin, ignoreCase = true) }
}
)
Enum Parameter
enum class GameMode { SURVIVAL, CREATIVE, ADVENTURE, SPECTATOR }
val gameMode = parameter(
name = "mode",
required = true,
verifier = Parameter.Verificator { text ->
try {
Parameter.Verificator.Result.Ok(GameMode.valueOf(text.uppercase()))
} catch (e: IllegalArgumentException) {
Parameter.Verificator.Result.Error(
"Invalid mode. Valid modes: ${GameMode.values().joinToString()}"
)
}
},
autocompletionHandler = AutoCompletionProvider { begin, _ ->
GameMode.values()
.map { it.name.lowercase() }
.filter { it.startsWith(begin, ignoreCase = true) }
}
)
Best Practices
- Always provide verification - Validate input before use
- Add auto-completion - Improves user experience significantly
- Use meaningful names - Parameter names appear in error messages
- Provide helpful error messages - Guide users to correct input
- Use nullable defaults for optional parameters - Clear intent
- Varargs must be last - Only one vararg per command, at the end
- Parse early - Convert strings in verificator, not in handler
- Consider context - Auto-completion can be context-aware
Common Parameter Types
Player Parameter
val player = parameter(
name = "player",
required = true,
verifier = Parameter.Verificator { text ->
val player = mc.level?.players()?.firstOrNull {
it.gameProfile.name.equals(text, ignoreCase = true)
}
Parameter.Verificator.Result.ofNullable(player) {
"Player '$text' not found"
}
},
autocompletionHandler = AutoCompletionProvider { begin, _ ->
mc.level?.players()
?.map { it.gameProfile.name }
?.filter { it.startsWith(begin, ignoreCase = true) }
?: emptyList()
}
)
Block Parameter
val block = parameter(
name = "block",
required = true,
verifier = Parameter.Verificator { text ->
val block = BuiltInRegistries.BLOCK
.get(ResourceLocation(text))
Parameter.Verificator.Result.ofNullable(block) {
"Block '$text' not found"
}
}
)
See Also