world object features... # world # attributes default procs will be called upon access, not at initialization this will fix the problem of WorldObject#id being nil when Attributes is prepended and Attributes#initialize is run first boolean attributes ok detected by class level definition boolean default value attribute open: true attribute dark: false ok after defintion, set boolean attribute values... open = true open true open! # ... open true ok query boolean attribute values... ? dark dark? # ... dark ? true : false is? :dark # ... def is? attr ; attributes[attr] ? true : false ; end ok additional class level define (and detect?) boolean attribute values... is :open is :dark is :warm, :bright group... group weapons: [ :sword, :knife, :rock, :fists ] # hash - key will be group name, value an array of symbols for members group :weapons, [ :sword, :knife, :rock, :fists ] # symbol will be group name, array of symbols for members ok group :weapons, :sword, :knife, :rock, :fists # symbols, first will be group name, rest will be members group stats: [ speed: 10, charisma: 20, strength: 30 ] # defaults like attributes (these are attributes) ok group :stats, speed: 10, charisma: 20, strength: 30 # ditto ok group is hash-like alias :names, :keys world_object.weapons.names #=> weapons.keys world_object.weapons.values #=> weapons.values ok group is not an enum, it has no value itself ok attribute methods for members in parent world_object.sword world_object.knife no is group a namespace ? - optional ... attribute methods in group world_object.weapons.sword world_object.weapons.knife ok access attributes via group hash world_object.weapons[:sword] #=> rusty_sword world_object.weapons[:sword] = sharp_sword ok exclusive group (booleans)... ok exclusive_group passable: , :open, :close exclusive_group light: [ :dark, :dim, :bright ] exclusive_group temperature: [ :cold, :cool, :warm, :hot ] ok same as regular group +... ok first member will be true, the rest false ok additional convenience methods for members... world_object.open? world_object.close? world_object.open! world_object.close! # descriptions displayed everytime a location is visited... description 'string' full description (short + long) displayed first visit short description displayed on subsequent visit + ellipses to expand long description on demand description short: "...", long: "..." may depend on location state ? description bright: '...', cold: '...' # is :bright, "........." # is :cold, "........." # openable open default is open way: player can go container: player can see inside closed (!open) specify with 'closed' or 'open false / open no' way: player cannot go way: is closed without 'to' (wrong-way) container: player cannot see inside condition must be true to open a proc/lambda 'locked' is just closed that has a key condition for opening action tests condition to try to open response for condition state/progress # visiblty visible default is visible description will be displayed invisible (!visible) specify with 'invisible' or 'visible false / visible no' description will not be displayed items will not be counted, etc.. # location locations do NOT contain locations locations are a graph, linked by ways location :here do name 'Home' description 'Cosy' end location :here, name: 'Home', description: 'cosy' mass assignment... locations do home name: 'Home', description: 'Cosy' yard name: 'Garden', description: 'Green' cellar name: 'Basement', description: 'Damp' end # way a way leads one-way to a location way :out do name 'Door' description 'Big strong' to :garden end way can describe being open closed way :out do name 'Door' to :garden description 'Wooden door' description :open => 'An open wooden door leading to sunlit garden', :closed => 'A closed solid wooden door' end way can describe going (open) or not (closed) way :out do name 'Door' to :garden go :open => 'Stepping into the warm sunlight', :closed => 'The solid wooden door remains stubbornly closed' end way :door, to: :other_location, description: 'Big' is openable, default open mass assignment... ways do east to: :china, name: 'slow boat' west to: :wild_west, name: 'fast horse' up to: :sky, name: 'balloon' down to: :pit, name: 'hole' end standard ways map to directions and movements ? - north,south,east,west,up,down,forward,back,left,right # items items may be in a location item :id do name 'Thing' description 'Useful object' end item :id, name: 'Thing', description: "...", detail: "..." mass assignment... items do thing name: 'Thing', description: "..." gadget name: 'Device', description: "..." key name: 'Gold key' end may be examined ? longer description when examined detail "....." have attributes attributes :small, :light may know their location ? if item.location == :home may know their relation to other items ? if item.contains? :water if item.near? :monster if item.on? :desk if item.in? :box # items can relate to other items ?.... # contains / contained # before / behind # on / under # above / below # near / far # module for this 'Relation' feature ? end # code for ... triggers, events, handlers, conditions, etc... # can locations, items be subclassed in DSL ? class Vase < Item attributes :small end vase :default do name 'Vase' attributes item :vase do description "a vase" aspect :small, :light end vase :blue_vase do aspect :blue end vase :red_vase do aspect :red end # is this more like prototyping than subclassing ?