------ art_2193_32568951.1142620392843
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
I've attached a library, GalaxyLoader, that parses a DSL for "world
builders". There's a brief example of the DSL following, and an
example world attached. The library also adds a class method
Galaxy.load to your Galaxy class. With this library, loading a galaxy
is as simple as:
require 'galaxy_loader'
galaxy = Galaxy.load('sample.glx')
# do stuff with the galaxy...
The DSL is fairly simple. A galaxy can have many sectors, possibly
within regions:
galaxy {
region("Federation Space") {
sector(1) { ... }
sector(2) { ... }
}
region("Klingon Space") {
sector(3) { ... }
sector(4) { ... }
}
sector(5) { ... }
sector(6) { ... }
}
A sector can have planets, stations and neighbors:
galaxy {
sector(1) {
planet "Earth"
station "Alpha"
neighbors 2, 3
}
sector(2) {
station "Beta"
neighbors 1, 3
}
sector(3) {
neighbors 1, 2
}
}
And that's all there is to it! I tried to make the GalaxyLoader class
as consistent as possible, so it should be fairly easy to add further
attributes to planets and stations by following the pattern of the
existing methods.
Enjoy!
Jacob Fugal
------ art_2193_32568951.1142620392843
Content-Type: application/octet-stream; name=galaxy_loader.rb
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ekwtx01d
Content-Disposition: attachment; filename="galaxy_loader.rb"
require 'galaxy'
require 'sector'
require 'planet'
require 'station'
class GalaxyLoader
class InvalidContext < Exception; end
def initialize
@context_stack ]
@sectors ]
@neighbors }
end
def execute(definition)
instance_eval(definition)
end
private
def galaxy(&block)
raise InvalidContext, "galaxy allowed only in root context" unless context nil
with(:galaxy Galaxy.instance) do
instance_eval(&block) if block
resolve_neighbors
end
end
def region(name, &block)
raise InvalidContext, "region allowed only in galaxy context" unless context :galaxy
with(:region name) do
instance_eval(&block) if block
end
end
def sector(name, &block)
raise InvalidContext, "sector allowed only in galaxy or region context" unless context :galaxy or context :region
with(:sector Sector.new(name, @region)) do
instance_eval(&block) if block
@sectors[name] sector
@galaxy.add_sector(@sector)
end
end
def planet(name, &block)
raise InvalidContext, "planet allowed only in sector context" unless context :sector
with(:planet Planet.new(@sector, name)) do
instance_eval(&block) if block
@sector.add_planet(@planet)
end
end
def station(name, &block)
raise InvalidContext, "station allowed only in sector context" unless context :sector
with(:station Station.new(@sector, name)) do
instance_eval(&block) if block
@sector.add_station(@station)
end
end
def neighbors(*sectors)
raise InvalidContext, "neighbors allowed only in sector context" unless context :sector
@neighbors[@sector] ectors
end
def with(context)
name ontext.keys.first
value ontext[name]
instance_eval("@#{name} alue")
@context_stack << name
yield
@context_stack.pop
instance_eval("@#{name} il")
end
def context
@context_stack.last
end
def resolve_neighbors
@neighbors.each do |sector,neighbors|
neighbors.each do |name|
neighbor sectors[name]
sector.link(neighbor)
end
end
end
end
def Galaxy.load(filename)
GalaxyLoader.new.execute(File.read(filename))
Galaxy.instance
end
------ art_2193_32568951.1142620392843
Content-Type: application/octet-stream; name=sample.glx
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ekwuoos3
Content-Disposition: attachment; filename="sample.glx"
galaxy {
region("Federation Space") {
sector(1) {
planet "Earth"
station "Alpha"
neighbors 2, 3, 4
}
sector(2) {
neighbors 1, 3, 4, 8
}
sector(3) {
neighbors 1, 2, 5, 12
}
sector(4) {
neighbors 1, 2, 3, 16
}
}
region("Klingon Space") {
sector(5) {
planet "Kronos"
station "Beta"
neighbors 6, 7, 8
}
sector(6) {
neighbors 5, 7, 8, 15
}
sector(7) {
station "Gamma"
neighbors 5, 6, 8, 10
}
sector(8) {
neighbors 2, 5, 6, 7
}
}
region("Romulan Space") {
sector(9) {
planet "Romulus"
planet "Remus"
neighbors 10, 11, 12
}
sector(10) {
neighbors 7, 9, 11, 12
}
sector(11) {
station "Delta"
neighbors 9, 10, 12, 14
}
sector(12) {
neighbors 3, 9, 10, 11
}
}
region("Ferengi Space") {
sector(13) {
planet "Ferenginar"
station "Epsilon"
neighbors 14, 15, 16
}
sector(14) {
neighbors 11, 13, 15, 16
}
sector(15) {
station "Zeta"
neighbors 6, 13, 14, 16
}
sector(16) {
neighbors 4, 13, 14, 15
}
}
}
------ art_2193_32568951.1142620392843--