Along the same lines, as I am unlikely to pursue this any further, here is my half-baked doodle towards a game DSL :) You can move about (using 'east', 'west', 'upstairs', etc.) but nothing else. Regards, Sean -- CODE -- module Attributes def has(*names) self.class_eval { names.each do |name| define_method(name) {|*args| if args.size > 0 instance_variable_set("@#{name}", *args) else instance_variable_get("@#{name}") end } end } end end module Directions def directions(*directions) directions.each do |name| self.class.class_eval { define_method(name) { dest = @location.exits[name] if dest @location = @rooms[dest[1]] look else puts "You can't move in that direction" end } } end end end class GameObject extend Attributes has :identifier, :name, :description def initialize(identifier, &block) @identifier = identifier instance_eval &block end end class Thing < GameObject has :location end class Room < GameObject has :exits def initialize(identifier, &block) # put defaults before super - they will be overridden in block (if at all) super end end class Game include Directions attr_accessor :name, :rooms, :location, :things def initialize(name, &block) @name = name @rooms = {} @things = {} # read game definition instance_eval &block end def room(identifier, &block) @rooms[symbol(identifier)] = Room.new(symbol(identifier), &block) end def thing(identifier, &block) @things[symbol(identifier)] = Thing.new(symbol(identifier), &block) end def symbol(s) s.to_s.to_sym end def start(room_identifier) @location = @rooms[room_identifier] end def describe_path(direction, path) "There is a #{path} going #{direction}." end def describe_exits(location) location.exits.map {|direction, (path, destination)| describe_path(direction, path) } end def describe_floor(location) @things.select{|key, thing| thing.location == location.identifier}.map{|key, thing| "There is a #{thing.description} here."} end def main_loop while input = gets input.chomp! case input when 'exit', 'quit' break when 'help' puts "Sorry pal! You're on your own here :)" else begin instance_eval input rescue Exception => e puts e.to_s puts "Eh?" end end end end # commands def look puts location.description puts describe_exits(location) puts describe_floor(location) end def quit break end end def game(name, &block) g = Game.new(name, &block) g.look g.main_loop end # Game definition game "Ruby Adventure" do directions :east, :west, :north, :south, :up, :down, :upstairs, :downstairs room :living_room do name 'Living Room' description "You are in the living-room of a wizard's house. There is a wizard snoring loudly on the couch." exits :west => [:door, :garden], :upstairs => [:stairway, :attic] end room :garden do name 'Garden' description "You are in a beautiful garden. There is a well in front of you." exits :east => [:door, :living_room] end room :attic do name "Attic" description "You are in the attic of the wizard's house. There is a giant welding torch in the corner." exits :downstairs => [:stairway, :living_room] end thing :whiskey_bottle do name 'whiskey bottle' description 'half-empty whiskey bottle' location :living_room end thing :bucket do name 'bucket' description 'rusty bucket' location :living_room end thing :chain do name 'chain' description 'sturdy iron chain' location :garden end thing :frog do name 'frog' description 'green frog' location :garden end start :living_room end -- END --