# from some other source
purge = ->
self.destroy_and_remove_from_game()
ch.after "input", ->
if good_input
ch.trigger("self delete")
ch.after "self delete", logic
ch.after "received third strike", logic
ch.after "character didn't login for 3 years", logic
npc.after "death", logic
…
if good_input
ch.trigger("self delete")
…
# from some other source
purge = ->
self.destroy_and_remove_from_game()
ch.after "input", ->
if good_input
ch.trigger("self delete")
ch.after "self delete", purge
ch.after "received third strike", purge
ch.after "character didn't login for 3 years", purge
npc.after "death", purge
{
:look =>
{
:default => look_lambda
[[:at, LivingThing], [:LivingThing]] => look_at_lambda,
[[:in, Item]] => look_in_lambda
}
}
@verb container:get this in any
verb "put place insert" : "in into" = put_in;
verb "get remove take" : "from in" = remove_from;
verb "l*ook" : "in into inside" = look_in;
class Living < GameObject
verb /say (.+)/, :cmd_say
def cmd_say *args
end
end
class Command
attr_reader :cmd, :name, :help
…
def self.load
…
cmds = YAML::load_file("cmd/#{i}.yaml")
cmds.each do |c|
Kernel::load("cmd/#{i}/#{c.cmd}.rb")
cmdtable.insert(c.name, c)
end
…
end
end
$has_commands local = #
$has_commands local = #[
["wh?isper", [["wh?isper", "* to *", "wh?isper <any> to <any>", 'whisper_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]],
["pose", [["pose", "*", "pose <any>", 'pose_cmd, #[[1, ['any, []]]]]]],
["get|take", [["get|take", "*", "get|take <descendant of $thing>", 'get_cmd, #[[1, ['descendant, [$thing]]]]],
["drop", [["drop", "*", "drop <descendant of $thing>", 'drop_cmd, #[[1, ['descendant, [$thing]]]]]]]
]; [/code]
Of course there are user commands that manipulate the structure.
All the above approaches are really fundamentally data-driven.
class Socials
def smirk; "You say something."; end
def laugh; "You laugh."; end
def method_missing method
closest_cmd = match_partial_command(method)
if closest_cmd
self.send(closest_cmd)
end
end
private
def match_partial_command value
self.methods.select{|name| name =~ /\A#{value}/ }[0]
end
def not_exposed
"Does something, does not return nil."
end
end
class FelineSocials < Socials
def pur; "You pur."; end
end
interface = FelineSocials.new
interface.smirk # You smirk.
interface.smir # You smirk.
interface.pur # You pur.
interface.not_exposed # nil
interface.non_existant # nil
This is straightforward, but it also makes me wonder, is it a good idea to express player verbs with the server language verbs like this? One obvious problem is the shadowing of any language symbols that might share the same name. Of course you can get around that with naming conventions or some kind of namespace clarification, but on a more abstract level do you want to couple your command language so closely with your server language anyway?
The first answer to this I thought of was a data-driven approach, (XML, YAML, something in your language or whatever) with accompanying bits of logic for each command. What might be some other solutions? Or is it not an issue in your eyes?