From: Todd Benson Date: 2008-10-06T08:46:47+09:00 Subject: Re: Object Persistence for a MUD On Sat, Oct 4, 2008 at 8:46 PM, Brent Dillingham wrote: > Hi all, > > For fun, I'm writing a MUD with Ruby. I thought I'd query the hive > mind here and ask some opinions on what library I might use for object > persistence -- that is, storing objects like players and rooms > somewhere. > > I could do something really simple like store everything in YAML, I > could try DRb, or I could go all out and use an ORM like DataMapper... > DataMapper is the first route I took, but I soon realized that I'll > have to be really careful when using a lot of the ORM niceties while > still ensuring that a database row only every represents one object in > memory. i.e.: > > # assuming Player has_one :room ... > > player = Player.get(1) # get Player with ID=1 > player.room # the player's current Room association > > ... player logs out, logs back in later ... > > player.room > > Oh noes! The ORM fetches the same room from the DB, but creates a > totally new object to represent it. Two players could be in the same > room ID, but actually reference different objects, and thus couldn't > see or interact with one another. Bad. > > This problem is hackable by carefully keeping a cache of loaded > objects -- but might end up negating the value of using an ORM like > DataMapper. So, any suggestions out there of what I might do instead? There are probably a hundred different ways to approach this. I've never programmed a MUD, but after playing around with the Sequel gem and Postgresql, I had a simple map with locations, players, and objects. I updated the DB on the fly, but I'm sure there are other paradigms. Very, very simple example... sql... create database mud; create table map ( x int not null, y int not null, synopsis varchar not null, description varchar primary key (x, y) ); create table people ( name varchar not null primary key, xcurrent int not null, ycurrent int not null, foreign key (x, y) references map (x, y) ); insert into map values (0, 0, 'start'); insert into map values (1, 0, 'hallway'); insert into people values ('Loki', 1, 0); insert into people values ('Thor', 0, 0); insert into people values ('Freya', 1, 0); ...ruby... require 'rubygems' require 'sequel' Area = Struct.new(:description, :synopsis, :x, :y) DB = Sequel.connect("postgres://user_name:password@localhost:5432/mud") #print everyone in the hallway... DB[:map].join(:people, :xcurrent => :x, :ycurrent => :y).where (:x => 1, :y => 0).all.each {|row| p row[:name]} #=> Loki #=> Freya Todd