SkyBlockTweaks/docs/CLIENT_COMMAND_BUILDER.md
2025-04-22 09:22:46 -06:00

3.4 KiB

Client Command Framework

I'm using a lightweight Kotlin DSL, annotation-based command system for making client side commands.

Defining Commands

All commands are defined as Kotlin functions annotated with @SubCommand in ClientCommands.kt.

Example:

@SubCommand(
    name = "test",
    description = "Runs a test command"
)
fun test(ctx: CommandContext) {
    ctx.send("Test command executed!")
}

Subcommand Options:

  • name: command name (required)
  • usage: shows usage in help menu
  • description: description shown in help
  • aliases: optional aliases

CommandContext helpers:

  • ctx.arg(index: Int): get argument (nullable)
  • ctx.require(index: Int, errorMsg: String): get required argument (throws error if missing)
  • ctx.send(msg: String): send message to client player

Help System

  • /sbt shows all available subcommands
  • /sbt help <command> shows usage & description for a subcommand

Tab Completion

  • Tab completion works for first argument (subcommands)

Example:

@SubCommand(
    name = "test",
    description = "Runs a test command"
)
fun test(ctx: CommandContext) {
    ctx.send("Test command executed!")
}

Subcommand Options:

  • name: command name (required)
  • usage: shows usage in help menu
  • description: description shown in help
  • aliases: optional aliases

CommandContext helpers:

  • ctx.arg(index: Int): get argument (nullable)
  • ctx.require(index: Int, errorMsg: String): get required argument (throws error if missing)
  • ctx.send(msg: String): send message to client player

Help System

  • /sbt shows all available subcommands
  • /sbt help <command> shows usage & description for a subcommand

Tab Completion

  • Tab completion works for first argument (subcommands)

Example Commands

@SubCommand(
    name = "autogrotto",
    usage = "<status|enable|disable>",
    description = "Manages the AutoGrotto feature"
)
fun autogrotto(ctx: CommandContext) {
    when (ctx.require(0, "Provide status, enable, or disable")) {
        "status" -> ctx.send("Autogrotto is enabled")
        "enable" -> ctx.send("Autogrotto enabled")
        "disable" -> ctx.send("Autogrotto disabled")
        else -> ctx.send("Invalid usage. Try /sbt help autogrotto")
    }
}

How to Add a New Command

  1. Go to ClientCommands.kt
  2. Define a function
  3. Annotate with @SubCommand
  4. Use ctx to get args and send messages

That's it!

Using CommandContext Helpers

val playerName = ctx.player?.name  // Nullable: client-side player
val firstArg = ctx.arg(0)          // Safe nullable accessor
val secondArgRequired = ctx.require(1, "Missing second argument")  // Throws if missing
ctx.send("You said: $firstArg and $secondArgRequired")  // Send chat to player

Calling Functions From Another Class

Create a utility or manager class like:

object MyFeatureManager {
    fun toggleFeature(enabled: Boolean) {
        // logic here
    }
}

Then call it from a command:

@SubCommand(name = "feature", usage = "<on|off>", description = "Toggles a feature")
fun feature(ctx: CommandContext) {
    val toggle = ctx.require(0, "Provide a toggle option")
    when (toggle.lowercase()) {
        "on", "enable" -> // same action 
        "off", "disable" -> // another action
        else -> {
            ctx.send("Invalid argument '$toggle'. Usage:")
            ctx.send("/sbt autogrotto <enable|disable|status>")
        }
    }
}