30 Mar, 2014, Davion wrote in the 1st comment:
Votes: 0
Is anyone interested in translating Rom24b6 to Python? I'm mostly trying to find interest in this. I've done python embedding in ROM but it's not quite the same. At this point it's more then a concept and fairly promising. It's definitely not amazing python but I think a nice start would first be a direct translation, then branch off from there. I'd like to avoid external libraries (except miniboa of course :D).

The progress thus far was done mostly with regex then I go over it to translate the scope. I've tried my best to keep as much of the original code as possible. I'd like to not start adding stuff until the entire thing is translated first. Anyways, if you want to contribute the https://bitbucket.org/mudbytes/pyom repository is public now. Try not to comment there as I'm terrible at reading the comments. Just ask Kelvin :D.
31 Mar, 2014, donky wrote in the 2nd comment:
Votes: 0
I suspect you are on your own for this one. But direct translation sounds like a good start - reduces the likelihood of drift and loss of focus and eventual loss of interest.

Responding to comments on bitbucket is easy, just watch the repository and you get notified about everything. I get emails for commits, issues, issue comments and so forth for the stackless repo, just by watching it. All can be replied to directly via email IIRC. I like bitbucket so much, I've even started moving my git projects there. Goodbye github.
31 Mar, 2014, Davion wrote in the 3rd comment:
Votes: 0
donky said:
I suspect you are on your own for this one. But direct translation sounds like a good start - reduces the likelihood of drift and loss of focus and eventual loss of interest.

Responding to comments on bitbucket is easy, just watch the repository and you get notified about everything. I get emails for commits, issues, issue comments and so forth for the stackless repo, just by watching it. All can be replied to directly via email IIRC. I like bitbucket so much, I've even started moving my git projects there. Goodbye github.


Haha, I suspect you're right :). It's certainly not the most entertaining thing to do! This is actually my second attempt, but the last one got lost in a hard drive crash. I've gotten a lot farther on this one though. The entire DB boots up and you can get mostly through chargen. My local copy can almost look!
31 Mar, 2014, quixadhal wrote in the 4th comment:
Votes: 0
The idea of translating any of the Dikurivatives to something more dynamic (python, ruby, even perl) is a good one. Any chance you've also commited your translation script to the repository? It might be a handy place to start if anyone wanted to do the same thing to a different codebase as well.
31 Mar, 2014, Davion wrote in the 5th comment:
Votes: 0
quixadhal said:
The idea of translating any of the Dikurivatives to something more dynamic (python, ruby, even perl) is a good one. Any chance you've also commited your translation script to the repository? It might be a handy place to start if anyone wanted to do the same thing to a different codebase as well.


I'm writing a lot of regex search/replace in a text editor. Not exactly a script ;). The only real constant ones are replacing &&, ||, ;, and -> with their python counterparts. Fortunately the tables convert nicely to dictionaries. It took me about 4-5 hours to translate magic.c and magic2.c. It's roughly 4500 lines (translated nicely into 2500!) There's really no easy way to do the scope. I leave the curly brackets untouched and go line by line. The formatting is pretty inconsistent and in switch statements formatting AND style go out the window.

Merc was pretty simple. a lot of "#define\s(.*)\s+(-?\d+)" -> "\1=\2" It's making decent progress. I've tried to stay focused on getting a logged in character.

One really cool thing I'm liking running as an interactive shell. I redirect all ch.send() calls to print, and after the DB boots you can call code at will! It'll be interesting to see it finished. There's lots of stuff I'd like to do differently.
01 Apr, 2014, Rarva.Riendf wrote in the 6th comment:
Votes: 0
I don't get why you owuld translate ROM in any langage at all as the core has logical limitation. First it was not meant to deal correctly with cascading events (killing someone and the next one in the list at the same time with an area spell/skill was definitely not meant to be). Object/characters different handling prevented object to cast spell in a sane manner. Group managing is very limited.
So many logical limitations (meant to save memory and cpu power, I can understand why that was done at the time) I really dont see the point.
Unless of course by tranlastion you just mean just keep the spell/skill handling/ tick ryhtm; and scrap everything else.
01 Apr, 2014, Runter wrote in the 7th comment:
Votes: 0
I think the point would be to give developers who understand rom a rosetta stone to transition into python.
01 Apr, 2014, Davion wrote in the 8th comment:
Votes: 0
Rarva.Riendf said:
I don't get why you owuld translate ROM in any langage at all as the core has logical limitation. First it was not meant to deal correctly with cascading events (killing someone and the next one in the list at the same time with an area spell/skill was definitely not meant to be). Object/characters different handling prevented object to cast spell in a sane manner. Group managing is very limited.
So many logical limitations (meant to save memory and cpu power, I can understand why that was done at the time) I really dont see the point.
Unless of course by tranlastion you just mean just keep the spell/skill handling/ tick ryhtm; and scrap everything else.


A lot of what you talk about is language limitations. The cascading events is pretty much a non-issue, as you can just run the lists as a copy in python (for x in list[:]). Lets you mutate the original list without fear of bad list pointers.

And why? Because ROM is awesome. I'll bet you've spent 90% of your time mostly just fixing up issues in the logic. A lot of which dance with memory and fancy low-level tricks. I think it's be very interesting to see what people would come up with, if they didn't have to waist time on memory management, and creating containers. A lot of the bugs that exist in ROM should inherently not exist in this. However, I do expect a new crop ;).

And another handy piece of regex send_to_char\("(.*)",\s?(\w+)\)
01 Apr, 2014, Rarva.Riendf wrote in the 9th comment:
Votes: 0
>A lot of what you talk about is language limitations.

Not only: there were perticular tricks used to save memory likethe notorious limited 'flags'
The different structure used for players/object/rooms that limited a lot what you could do with them. (againto save memory as some values would be useless for some use)
The way it saved spellaffect and reapplied them at load on a player (exact same bug you can find in diablo 2 btw, as you can wear the items in a perticular order when playing as some items would give you somme bonus that would allow to wear other item (like str) but when loading a player it would equip the character in a perticular order that woudl prevent to wear everything) as well.
There are a lot of logical short thinking that was understandable at the time but not nowadays. (like fighting round would always occur in the order the people log etc, as the player list will always be parsed in this order in the aggro update function)

Off course most of those problem are easily solved in a new langage (reordering a list is a lot easier in every other langage than C, not to mention having safe iterator over one ) or with a little work as you are saying.
But then it is not just a 'translation' but a new engine that can replicate the same thing, but a lot more tweakable without having it falling appart.
02 Apr, 2014, Davion wrote in the 10th comment:
Votes: 0
Rarva.Riendf said:
>A lot of what you talk about is language limitations.

Not only: there were perticular tricks used to save memory likethe notorious limited 'flags'

That's definitely a limitation of the language. One of the things C lacks compared to these new languages is mutable variable types. You can safely set the 1 << 100th bit of any integer in python no problem! Don't even have to worry about expanding and you still get the great benefits of using bitwise operators.

Rarva.Riendf said:
The different structure used for players/object/rooms that limited a lot what you could do with them. (againto save memory as some values would be useless for some use)


Python doesn't hate. It accepts any variable as anything really. You can even pass the class itself as a variable! So as long as you use identical variable names (which ROM does very well actually), you can pass around objects far looser than you probably should! The language is lifting a lot of the problems that came with ROM.

One nice thing I've found is how much code I don't have to write at all. Python has the %s style formatting built into it. Miniboa handles all the telnet negotiations for you. Some of the crazy mind bending memory allocations in ROM are simply for containers. That's all pretty much gone now. Basic commands were turned into feats of endurance and mental strength just because you needed a dictionary-like object to display what skills you have at what level. I am just straight deleting chunks of code and replacing them with things like "var = {}". I'm also cheating using json for pfiles.

Rarva.Riendf said:
But then it is not just a 'translation' but a new engine that can replicate the same thing, but a lot more tweakable without having it falling appart.


I'm keeping as many of the function names the same, unless a python equivalent exists (eg, number_range is now random.randint(), str_prefix is now .startswith). There are a couple notable changes. First it's ch.guild now instead of ch.class and guild_table instead of class_table. one_argument(argument,arg) is now argument, arg = read_word(argument). And send_to_char("",ch) is now ch.send(). You set the port in settings.py and you run from the pysrc directory via pyom.py or shell.py(if you want an interactive shell).
02 Apr, 2014, Rarva.Riendf wrote in the 11th comment:
Votes: 0
>That's definitely a limitation of the language.

Nope the flag was definitely short sighting, as they were only true or false to begin with, so if you had two spells adding it, you had no way to know if it should stay when a spell wore off unless you parsed everything that could add it. and it is not a limitation of a langage, as you could simply store a hella number of flag easily with bit in a string. (but with the same problem: only true or false value)
02 Apr, 2014, quixadhal wrote in the 12th comment:
Votes: 0
Not to defend ROM, or anything… but Rarva, you're mistaken.

The limitation you're describing is not an artifact of the bit flag system at all. The bit flag were never meant to handle spell effects, they were meant to be inherent properties of the npc/object/room. The affect system was meant to apply changes from spells or other temporary things which could wear off.

Now, you can argue that the way the affect system was built was poorly done, and that's as much due to the designers not really understanding data structures beyond the linked list. A properly done affect system would likely be done as a stack or priority queue, where the thing on the top is the thing which will expire first.

Not sure what python has to offer for this, but in perl, I would probably do exactly that… make it a stack (array) where new affects are inserted at their time-to-live point (perl lets you use slices of arrays, so $a = $a[0..3] + $new_thing + $a[4 ..]; would just return a new array with $new_thing as $a[4]). Then, if I wanted to find all the affects on a characer that had to do with intelligence, you could use grep (perl function… grep { $_->{attribute} == "intelligence" } @a).. or you could build a secondary array if it were something you did frequently.

As Davion said, many of the bugs in ROM (both logical AND code) were due to the constant dance of pointers and the effort to fit everything into less than 8MB of RAM. That limit is silly today, and thus many of the things done are overly complex and fragile.
02 Apr, 2014, Davion wrote in the 13th comment:
Votes: 0
Rarva.Riendf said:
>That's definitely a limitation of the language.

Nope the flag was definitely short sighting, as they were only true or false to begin with, so if you had two spells adding it, you had no way to know if it should stay when a spell wore off unless you parsed everything that could add it. and it is not a limitation of a langage, as you could simply store a hella number of flag easily with bit in a string. (but with the same problem: only true or false value)


I guess we'll have to agree to disagree here. The way they use bitflags is awesome (in the sense lotsa boolean values with rapid access, and low memory). It's a practice I'd use even today. I use a similar technique in my exploration code. Affects and bit flags really have little to do with one another. The reason AFF_* exists is to determine whether or not a player holds an affect without having to transverse the affected lists. You will not find a smaller, faster, more efficient way to accomplish this particular task. It's probably unnecessary here, but I'm goin for a translation.

Most of the scalability and gameplay issues you talk about are a PITA to change in C ROM. In Python it'd be a lot simpler. You spend your time writing code that functions instead of creating fancy containers to hold your objects only to get to the meat of the code and realize you have to write more containers to display/filter it. So as to why I've picked ROM? It's a decent starting point. Most of the short falls you've mentioned are really just fumbling with pointers or having to contest with a class-prejudice compiler.

Another upside to the change to this language, you on longer require a lot of the MAX_ variables. So many times, there were bugs caused by people over running skills, class or race tables. Now that's impossible. There's a few files that are translated almost line for line. Check out skills.c and skills.py for a decent comparison. That should be fully translated. update.py should be up later today, and that is done line for line.

For my next segment, I present to you, I can't believe that's C! This is from update.c Fortunately it's formatted correctly or it'd be very difficult to understand. I was a big fan of using no {}'s on single line if's, but not like this!
if (obj->in_obj) /* in another object */
obj_to_obj(t_obj,obj->in_obj);

else if (obj->carried_by) /* carried */
if (obj->wear_loc == WEAR_FLOAT)
if (obj->carried_by->in_room == NULL)
extract_obj(t_obj);
else
obj_to_room(t_obj,obj->carried_by->in_room);
else
obj_to_char(t_obj,obj->carried_by);

else if (obj->in_room == NULL) /* destroy it */
extract_obj(t_obj);

else /* to a room */
obj_to_room(t_obj,obj->in_room);
03 Apr, 2014, quixadhal wrote in the 14th comment:
Votes: 0
Personally, I dislike packing data into bizzaro shapes unless you HAVE to do so. DikuMUD's bit flags were done that way because when you only had a few megabytes of memory, you HAD to find a way to squeeze every drop out of it.

It's far simpler and nicer to just make every "bit" be a boolean variable, first class. It requires you to make a one-time pass through the code to change things like if(room_flags & ( BIT_FOO | BIT_BAR | BIT_FAP )) into if(room.foo && room.bar && room.fap), but the resulting code is easier to read AND makes it directly storable in an SQL table that can be directly queried (SELECT * FROM rooms WHERE foo AND bar AND fap);

Now that most modern servers have between 4 and 16GB, I think we can safely "waste" a few on making life simpler. :)
03 Apr, 2014, quixadhal wrote in the 15th comment:
Votes: 0
Davion said:
A good reason to split else and if apart… :)

if (obj->in_obj) /* in another object */
obj_to_obj(t_obj,obj->in_obj);
else
if (obj->carried_by) /* carried */
if (obj->wear_loc == WEAR_FLOAT)
if (obj->carried_by->in_room == NULL)
extract_obj(t_obj);
else
obj_to_room(t_obj,obj->carried_by->in_room);
else
obj_to_char(t_obj,obj->carried_by);
else
if (obj->in_room == NULL) /* destroy it */
extract_obj(t_obj);
else /* to a room */
obj_to_room(t_obj,obj->in_room);
04 Apr, 2014, Kelvin wrote in the 16th comment:
Votes: 0
quixadhal said:
Personally, I dislike packing data into bizzaro shapes unless you HAVE to do so.

Agreed. Simple and explicit is the way to go. No need to be clever. In fact, you want to be as far from clever as possible. Be boring and unremarkable so I can read and understand your crap :)
04 Apr, 2014, Nathan wrote in the 17th comment:
Votes: 0
quixadhal said:
Personally, I dislike packing data into bizzaro shapes unless you HAVE to do so. DikuMUD's bit flags were done that way because when you only had a few megabytes of memory, you HAD to find a way to squeeze every drop out of it.

It's far simpler and nicer to just make every "bit" be a boolean variable, first class. It requires you to make a one-time pass through the code to change things like if(room_flags & ( BIT_FOO | BIT_BAR | BIT_FAP )) into if(room.foo && room.bar && room.fap), but the resulting code is easier to read AND makes it directly storable in an SQL table that can be directly queried (SELECT * FROM rooms WHERE foo AND bar AND fap);

Now that most modern servers have between 4 and 16GB, I think we can safely "waste" a few on making life simpler. :)


On the memory, that's a nice thought, but unless you host it yourself or pay significantly higher rates or rent a VPS (not cheap) then it's a heck of a problem. If your code somehow requires >30mb for 10-15 players then you have a problem, you can't use most of the actual mud hosting services (granted, only found in a relatively quick google searcH) since their "packages" are aligned around the notion of mud servers with fairly limited memory requirements.

for the least expensive package (memory/disk)
http://www.thirdhosting.com/mud_hosting/ ( OK – 50mb, 2gb)
http://www.genesismuds.com/ ( PASSABLE – 30mb, 400mb)
http://www.dune.net/mud/?plan-chart ( IFFY – 20mb, 100mb)
https://www.mudmagic.com/ ( IFFY – 15mb, 400mb)
http://www.bizfu.com/mud.shtml ( IFFY – 10mb, 100mb)
http://www.oxonet.com/mudhosting.html ( IFFY – 10mb, 100mb)
http://www.themudhost.net/ ( ???? – cpu/ram percentages, so maybe…)
http://frostmud.com/accounts.html ( ???? – cpu/ram percentages, so maybe…)
* granted that at least one of these sites isn't offering new accounts

Most of these services run $4 - $10+/month on the cheapest plan (i.e. that noted). While there are other benefits to some services than just memory and ram, it's probably less expensive to make and run a webgame (even with HTML5 and possibly MYSQL) and more people will actually play it.

Your code shouldn't require more than 50mb under almost any circumstances, or it might simply not be viable for an average mud admin to make work unless they have lots of money and free time. Not that it would be easy without either of those, regardless. Granted that a few extra boolean variables vs bitfields is a marginal increase in memory use by comparison.
04 Apr, 2014, quixadhal wrote in the 18th comment:
Votes: 0
The amount of RAM you'll save from having less code will probably outweigh any savings you'd see using that complex bit manipulation. Consider that your bash shell sucks up 20M of RAM, all by itself.

Maybe mud hosting sites charge extra because they can… I know it's not horribly expensive to just get a hosted VM these days, and do whatever you want with it. I think linode charges $20/month for 1GB of RAM, 48GB of disk, and 2TB of data transfers per month. I can't imagine any MUD using more than that, no matter how it was written.
05 Apr, 2014, Nathan wrote in the 19th comment:
Votes: 0
quixadhal said:
The amount of RAM you'll save from having less code will probably outweigh any savings you'd see using that complex bit manipulation. Consider that your bash shell sucks up 20M of RAM, all by itself.

Maybe mud hosting sites charge extra because they can… I know it's not horribly expensive to just get a hosted VM these days, and do whatever you want with it. I think linode charges $20/month for 1GB of RAM, 48GB of disk, and 2TB of data transfers per month. I can't imagine any MUD using more than that, no matter how it was written.


Of course. No idea why a shell should use 20MB anyway.

I suspect that the mud hosting sites are just a bit behind the times, honestly. They probably ought to double or triple their space offerings for the same price. Still, the people that want that service may be willing to pay for that. It's probably just what always been done.

Yeah, 1GB of ram is probably way more than adequate. For people who don't have a job and/or a life, though, $20/month is insanely expensive (that's $240/year) and most people aren't going to pay that just to have some space to play around. People who have jobs are probably pretty busy and largely don't have time to dedicate to running/administrating obscure text game servers much less developing a playable game. They may also be engaged in more practical projects. – I'm just saying that someone writing a mud should aim to minimize memory usage when possible without overly constraining the design., etc. Unfortunately java has overhead, so it might be hard to ensure that you stay within a service's designated limitations. The VPS approach just doesn't look particularly practical, although arguably it's better than wasting ~$10/month for an inferior service, so it's probably worth it if you are really serious.
05 Apr, 2014, quixadhal wrote in the 20th comment:
Votes: 0
IMHO, the only people who should be spending money on hosting a MUD are serious people who already have a small player base and want to grow into a larger game. If you're reading this forum, you have a machine capable of running a MUD. Yes, even if you're reading it on your cell phone! I always encourage people to just download virtualbox (free) and setup their own VM to work on their MUD.

Most home PC's these days can easily run a VM in the background that's likely going to use very little RAM, very little disk I/O, and an almost ignorable amount of CPU. It's not as nice as having a spare machine, or an actual hosted site… but it works quite well for development, and with a small amount of effort, you can easily let a few others in to work on it with you.

THEN, once you're ready to go and maybe already have a few players, you can take your time thinking about how you want to host it for real. At that point, you've invested enough time and energy into it that spending a small amount of cash is probably worth it, and even if you don't have much to spare, odds are good you'll find a way.

I know to many, $20/month sounds expensive. I usually try to put it in perspective, which admittedly is from a USA point of view. Here, going to see a movie for 2 hours costs $10… $20 if you want a drink and popcorn. Eating lunch at most restaurants is $10, dinner being $20. A month of game time for World of Warcraft is $15. A coffee is $5. You see where I'm going with this.
0.0/93