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 set_goals_cmd.rb
in 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/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.
Type goals/set Some goals.
to set some goals on yourself.
Type 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 enactor
and 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.
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: self.goals
.
The 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.
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.