To create a command, we need a Command Handler class to do the command processing. In the Quickstart tutorial, we used the tinker command handler. Now we’re going to create one of our own.
Our goals system has two commands. Let’s tackle the set goals command first.
`goals/set <goals>` - Sets goals.
Create a file named
aresmush/plugins/custom. Give it the following contents:
module AresMUSH module Custom class SetGoalsCmd include CommandHandler attr_accessor :goals def parse_args self.goals = trim_arg(cmd.args) end def handle enactor.update(goals: self.goals) client.emit_success "Goals set!" end end end end
Then modify the
get_cmd_handler method in
aresmush/plugins/custom.rb to wire up the command handler:
def self.get_cmd_handler(client, cmd, enactor) case cmd.root when "goals" case cmd.switch when "set" return SetGoalsCmd end end return nil end
In the game, type
load custom to reload the custom plugin.
goals/set Some goals. to set some goals on yourself.
ruby enactor.goals to view them.
When we were tinkering in the Quickstart tutorial, we just smushed all of our command processing into the
handle method. But for real commands, that can get unwieldy. There’s a better way to do it.
Just as the
CommandHandler utility gives us some useful utilities like
client, it also gives us a structured way to handle commands. There are three steps:
Splitting up the code into multiple methods makes it more organized and readable.
In this example, the
parse_args method takes the arguments from
cmd.args and stuffs it into a class variable named goals. The
trim_arg processing strips off any leading or trailing spaces.
It's common practice to use Ruby's class variables (defined by
attr_accessor ) to store command arguments. A class variable defined by
attr_accessor can be accessed throughout the class. To distinguish it from regular variables, you put
self. in front of the name when using it. For example:
handle method takes the goals (again from
self.goals) and updates the goals database attribute on the enactor. It then emits a success message to the client.
Remember we need to use
update to save a database field.
Goals are just a free-form string, so there isn’t any error checking to do here.
We’ve talked a lot about how commands get handled, but how do you get from the player typing “goals/set” in their MU client to the
SetGoalsCmd class? The answer is the Dispatcher.
One of the Dispatcher’s jobs is calling each plugin’s
get_cmd_handler method any time it gets a command. A plugin can return
nil - if they don’t want the command - or an appropriate command handler if they do.
In this example, we have a simple case statement that returns the
SetGoalsCmd class if the command root is ‘goals’ and the switch is ‘set’.
You can learn more about the dispatcher in the Advanced Tutorial on Command Dispatching.