Archive for the ‘muds’ Category

Who was Rolindar?

I’ve been going through my collection of mud areas lately (you can download areas freely from various codebase repositories). Many are entertaining reads in their own right; over 20 years of mud development is bound to produce at least a few highly skilled wielders of OLC (or an area format file, whatever the case may be). One of my favorite builders is Rolindar.

In my experience Rolindar’s areas are not to everyone’s taste (he has a distinct style), but his flair for writing, the interactivity in his zones, and feel for creating a coherent zone make him a standout in my opinion. If you’re curious you can search for some of his areas here, http://www.smaugmuds.org/index.php?a=files&s=search .

There must be other builders, past (and perhaps) present of Rolindar’s caliber; there surely are thousands of original mud areas out there. I wonder who would be in the ‘top 5 builders of all time’. I find it a little sad that such a question will never be answered, if only that it deprives future builders of knowing who came before them. Maybe it isn’t a necessary question to answer in a hobby like this. No (well, let’s say most) builders don’t create areas to make a name for themselves, but out of a sense of contributing to a greater whole.

It does seem lacking though to have to create without a past.

Advertisements

server in Clojure, fourth attempt

Getting closer! Continue reading

server in Clojure, second attempt

(ns exvarcis.core
  (:import [java.net InetAddress InetSocketAddress Socket]
           [java.nio ByteBuffer]
           [java.nio.channels ServerSocketChannel SocketChannel Selector SelectionKey]))

(defmulti select-op
  (fn [chkey server] (.readyOps chkey)))

(defmethod select-op (SelectionKey/OP_ACCEPT) [chkey server]
  (do (-> 
        (.accept (:acceptor server))
        (.configureBlocking false)
        (.register (:selector server) (SelectionKey/OP_READ)))
      (println "Client registered")))

(defmethod select-op :default [chkey server]
  (println "Default op."))

(defn start []
  (let [acc (-> (ServerSocketChannel/open) (.configureBlocking false) (.bind (InetSocketAddress. "127.0.0.1" 0)))
        sel (Selector/open)]
    (.register acc sel (SelectionKey/OP_ACCEPT))
    {:selector sel :acceptor acc}))

(defn -main []
  (let [server (start)
        sel (:selector server)]
    (println "Starting Ex v Arcis on" (.getLocalAddress (:acceptor server)))
    (while true
      (.select sel)
      (let [sel-keys (.selectedKeys sel)]
        (doseq [chkey sel-keys]
          (select-op chkey server))
        (.clear sel-keys)
        (Thread/sleep 3000)))))

Getting better — shortened -main by moving logic into multimethods. I like how those work; you don’t need a conditional branch to test which operation to do, which makes the doseq nice. In the case of a select call it’s not that big a deal since there are only a few operations, but what the hey. I now realize that dispatching functions using a map/dictionary rather than conditionals (something I gravitated to early in Python) serves kind of the same purpose, but multimethods are a more complete expression of the idea. That Thread/sleep is just there so I have time to watch stuff in the repl by the way — I’ll have to put a stop condition in the while there eventually too, right now I just interrupt it at the repl.

The while is just a macro for a loop/when/recur. I keep thinking that there’s some way to do that with an infinite lazy sequence, but maybe not.

Continue reading

A single-threaded multiplexing server in Clojure, first attempt

(ns exvarcis.core
  (:import [java.net InetAddress InetSocketAddress Socket]
           [java.nio ByteBuffer]
           [java.nio.channels ServerSocketChannel SocketChannel Selector SelectionKey]))

(defn start []
  (let [acc (-> (ServerSocketChannel/open) (.configureBlocking false) (.bind (InetSocketAddress. "127.0.0.1" 0)))
        sel (Selector/open)]
    (.register acc sel (SelectionKey/OP_ACCEPT))
    {:selector sel :acceptor acc}))

(defn -main []
  (let [server (start)]
    (println "Starting Ex v Arcis on" (.getLocalAddress (:acceptor server)))
    (while true
      (.select (:selector server))
      (let [sel-keys (.selectedKeys (:selector server))]
        (doseq [ch-key sel-keys]
          (cond
           (.isAcceptable ch-key)
           (do (->
                (.accept (:acceptor server))
                (.configureBlocking false)
                (.register (:selector server) (SelectionKey/OP_READ)))
               (println "Client registered"))))
        (.clear (.selectedKeys (:selector server))))
      (Thread/sleep 3000))))

No doubt due to the influence of the recent MudBytes thread about “keeping it simple” I’m currently having a go with writing Ex v Arcis from the ground up, more or less…hmm, I may have misinterpreted that thread. But anyway, here’s the first attempt. It’s very bad, but it gets the job done. Well, sort of — all it does at the moment is accept new connections.

What’s awful about it? I could be wrong as I’m just learning Clojure and barely know Java, but I don’t think I have a good handle on the Java interop yet. It’s a bit hard to figure out as at the moment it’s mostly all Java interop. Dealing with mutable Java collections (the selectedKeys for example of the Selector) with Clojure collection functions (like doseq) is still a little beyond my grasp. But it’s a start.

There are dozens (hundreds?) of example mud codebases out there if you want to learn how to write a server, and plenty of tutorials on basic single-threaded nonblocking TCP servers. I found a few tutorials that were especially helpful.

http://onjava.com/pub/a/onjava/2002/09/04/nio.html?page=1

http://rox-xmlrpc.sourceforge.net/niotut/index.html

http://www.owlmountain.com/tutorials/NonBlockingIo.htm#_Toc524339526

For Java interop with Clojure the standard Java docs are of course indispensable:

http://docs.oracle.com/javase/7/docs/api/java/nio/channels/ServerSocketChannel.html

Finally, if you had to look at one mud as an example, I think I would choose Miniboa:

http://code.google.com/p/miniboa/

The file async.py (http://code.google.com/p/miniboa/source/browse/trunk/miniboa/async.py ) is what you want, though the Telnet implementation is a great reference too.

I would be remiss if I did not mention Mire, https://github.com/technomancy/mire/blob/master/src/mire/server.clj , a multithreaded Clojure mud. Multithreaded muds (that is, a thread per client connection) in Clojure are rather nice to write compared with other languages because of Clojure’s concurrency story. Perhaps in the end that’ll be the way to go. But I had a hankering to write a single-threaded non-blocking server, so for now that’s the path I’ll take.

edit:

Somehow I missed this:

http://pepijndevos.nl/2011/06/18/nio-in-clojure.html

First, there was the wheel. Then there was another wheel.

(ns exvarcis.core
  (:import [java.net InetAddress InetSocketAddress Socket]
           [java.nio ByteBuffer]
           [java.nio.channels ServerSocketChannel SocketChannel SelectionKey]))

(def selector
  (atom (java.nio.channels.Selector/open)))

(def acceptor
  (ref
   {:ch (->
         (ServerSocketChannel/open)
         (.configureBlocking false)
         (.bind nil 0))}))

(defn -main []
  (do
    (.register (:ch @acceptor) @selector (SelectionKey/OP_ACCEPT))
    (println "Starting Ex V Arcis on" (InetAddress/getLocalHost))))

a micro mud?

Inspired by a recent thread at MudBytes I’ve been thinking about what it would take to put out a small, playable, fun mud. I slimmed down an idea I’ve been sketching on recently and this is what I have so far.

exVarcis_header

You, a champion warrior, fight for dominance within a dark and mysterious castle prison.

* every character gets a home room which you can’t lose.
* you win control of new rooms.
* you have one stat, dominus.
* you’re ranked on a leaderboard by (number of rooms won) * dominus
* you find wards to use battling other players, and to set as defenses on rooms.
* wards are single-use and usually have a timed delay.
* when you win a number of rooms greater than dominus, you reincarnate.
* when you reincarnate you wake in a new room, all of your won rooms lost. Your dominus increases and you can use new kinds of wards.
* every character has two powers, direct and indirect (those are the actual powers; I need a better term here), and can be either pure or in one of three warps, twisted, reversed, or inverted (recycling an old RL idea here).
* When you use a ward, which power you use and your warp state determine the effect, so each ward has eight permutations (two powers X four states). This counts for wards you set; your current warp and power selection determines what the ward will go off as when triggered.
* every character can have one piece of gear that will affect ward effects in some way.
* as your won rooms approach max dominus, your chance to warp increases. You warp in order, so pure -> twisted -> reversed -> inverted.
* once warped, you may revert to a prior warp, or push to a higher warp, using warping wards.
* the more wards in a single location, the higher chance of wards going off with unpredictable results.

Good advice

1) Start it yourself, and be prepared to do it yourself. This doesn’t mean you will be doing everything yourself, and it doesn’t mean you can’t give things to other people. It means that if you don’t have anyone else to do something, you have to be prepared to do it yourself.

2) Get something working, even if it’s simple and sucks, as quickly as possible. If you have something that works and sucks, you’ll want to improve it and make it suck less, which is good motivation.

3) Get users as quickly as possible, and if they want to help, let them. Make sure you talk to them and tell them about what you’re doing and why.

The way #3 worked out for me was that I got other mudder friends involved pretty much as soon as we were able to build areas online. They built areas, which gave them a creative outlet and helped the game, and I built code, which helped them be creative. They pushed me, and I pushed them. Great motivation.

4) Take good care of your users, and reward them for finding bugs in your stuff. The value of testers and testing cannot be overemphasized.

5) If something needs to get done, sit down and do it. Don’t wait around until you find someone to do what you need done; if other people wanted to do it, they would tell you, and if they do it when they don’t want to, the result will be poor.

 

(thanks dentin)

on the banks of the O-rontes

I just wanted to highlight a rather interesting MOO-like project I came across on Github, Antioch. According to the readme,

Django-powered, standards-compliant web interface using Bootstrap, jQuery, REST and COMET

Sandboxed Pure-Python execution enables live programming of in-game code

PostgreSQL-backed object store scales to million of objects and provides transactional security during verb execution

Flexible plugin system, highly scalable messaging using RabbitMQ

I can’t say how far along it is but it looks pretty impressive. The author’s name, Phil Christensen, rang a bell — and then I realized that Phil (a rather interesting fellow himself) was working on txSpace (a cool Python MOO-like) a few years ago, and that it seems like Antioch is the next iteration of txSpace. Nice!

pb4

Lately I’ve been playing a lot of online chess. At the same time I’ve been messing around with new mud ideas. I like chess, and I like muds, so naturally I ask myself — can a mud play more like chess?

battle chess

My answer isn’t an unqualified ‘yes’. To play strictly like chess you’d have to remove chance (notwithstanding some chess variants I guess) and I wouldn’t be happy with a system that totally relies on player skill. Some of the attraction of a mud is playing a character after all.

However injecting chance into chess is really a minor point. What are some of the qualities of chess that might work in a mud?

  • You start off equal to your opponent

    This seems like the least workable chess-ism, however it’s not unusual to spot another player a piece or two, so there’s some precedent for asymmetrical starts at least.

  • You have a variety of pieces with different moves

    Different ‘moves’ in a mud aren’t unusual (kick, punch, etcetera), but I think this quality of chess leads to an interesting idea.

    You have a variety of abilities, each with a range of moves. Standard stuff. But, as with chess, at any time your abilities will be in some arranged state. There’s a big difference between a white pawn on a2 and a7. Now add a white rook on a1 and the game changes yet again.

    This is the essence of chess. One problem doing this in a text mud is visualizing this arrangement without making it look like, well, chess. One simplification would just be to reduce the number of pieces/abilities. Another might be to create a dynamic description of your character in a conflict that updates itself as the conflict continues.

    This gets to a personal taste of mine; in many muds the flow of action is very quick, with text whizzing up the screen. It gets even faster when you’re grouped. Many players enjoy this, no doubt, but I’ve always liked a slower pace, or at least more of a reading experience than the virtual text shmup of much mud conflict.

    So I’ve seen some muds experiment with a fixed room description window in the client that changes as you move. Why not a ‘fixed conflict description window’ that updates too? Basically this is your ‘chess board’ that shows the arrangement of abilities versus your opponent(s). Thinking of it that way, it probably would work best combined with a fixed room description anyway.

    Now as I said, the visualization is one problem. It’s easy for a player to strategise when they understand their options — a pawn moves forward, a rook can protect pieces on its file and so on — but it gets more complicated when you’re in a mud simulating some world model. I don’t have an easy answer to that, but I think it’s an interesting avenue to explore at least.

  • You (might) have a time limit

    Since I’ve been thinking of doing something turn-based in a mud, an overall time limit (of course you can have each turn take limited time, but I’m thinking for the whole conflict too) might work very well. I’m not sure if modeling this as ‘fatigue’ or some other reserve pool, or an actual extra-diagetic time limit would work. Maybe a combination of the two.

  • There’s a tradition of studying games

    I think this is an interesting possibility. Usually to ‘get good’ at a mud you just play your character, talk to and group with other players and maybe read a guide or two. What if studying other character’s conflicts was a means to improve as well? It might be cool to put this in the game fiction somehow…say, you could listen to game-generated songs that described a character’s actions in some situation.

At the moment I’m working on an idea where I think some of these concepts could work well, so we’ll see where this goes.

Playing: Geas

If you’ve played muds for years, can an old mud still be interesting?

I think the last mud I played was ConQUEST (which is back on hiatus it seems). I keep an eye on TMC for new listings but nothing that interesting to me has shown up. Inspired by a tweet from ‘Fmud’ Matt I went back to the listings and from an ‘all original’ + ‘levelless’ search tried Geas.

So, can an old mud still be interesting? Not fun mind you, I have no doubt old muds can be fun. But interesting? According to TMC Geas started in 1998. I think I might have tried it briefly long ago but the memory is old enough that I pretty much was starting from scratch. Can an old mud be interesting when you feel that you’ve played all the old muds have to offer?

Well, a logical question is, ‘what is interesting’, and since I’m using that word a lot I guess it’s on me to define it for the present moment. I admit that interesting is a rather uninteresting, lazy word. But if I tried to define it I wouldn’t be talking about Geas very much, so let’s put that definition aside for a minute. I’ve only played Geas for a couple of hours so this is naturally a first impression rather than a review (though impressions should suffice to say if something is interesting 🙂 ).

Geas is an LP mud, and for me LP muds automatically ‘feel different’. It’s not that I’ve played mostly DIKUs (using the term loosely to encompass all its children in the mud family tree); my first mud was Lost Souls in fact. I think this feel is due to the nature of how people create LPs. Because the LP development tools allow for a great deal of flexibility within areas, the game texture is knottier, more complicated. DIKUs feel more uniform. Maybe LPs are wool, and DIKUs are polyester? I’m worried about what value judgements that might imply, in either direction…

So, Geas feels different, and not always in a good way. For example, some of its command parsing is old fashioned. It doesn’t recognize abbreviations in many cases. It’s a good example of a rich command set that lacks usability.

From my few hours of playing I think this example is an expression of a core property of Geas, and probably of many old muds (and maybe LPs in particular). This is the core property: complicated complexity.

Complexity doesn’t have to be complicated. I think God Wars 2 is a good example. That’s a complex game by most accounts. However the information is laid out cleanly and simply most of the time. Geas seems like the opposite case. However it’s not entirely a fair comparison. GW2 is mostly the work of one developer (who had several other muds to look back on for experience). Geas appears to be a team effort, and it’s twice as old to boot.

On the other hand, many times Geas does feel different in a good way. Your character’s hair grows. You can shave it, or I presume grow a beard (!). This seems like a minor detail, but was quite delightful when I discovered it. The hiding, sneaking, and tracking systems are well developed. There seems to be a generalized climbing mechanic. Again, it’s fun to find this stuff out. The combat system is more slowly paced than most muds (a plus) with multiple tactical options (more plusses). There are no levels or classes, and many skills to learn (by use).

There are many color customization options (good), but limited colors (ansi with some extensions), you have to design your own color theme by hand (no good default packages) and some odd typography like in how the room descriptions are laid out (not good). There are more toggle’able output options than usual (good), but weird design choices where other characters can spam songs or actions like juggling, and it seems like you’re forced to pay attention to it.

This last bit bothered me a little and made me wonder about possible solutions. It’s fairly common to have options to control what combat messages you see (indeed, Geas has some options just like this). I’d like to see a more generalized system where you can control the level of detail your character sees for all actions.

There’s a flexible emote system for RP, it seems like lots of provisions for PC politics, and a somewhat RPI’ish slant toward RP in general (an introduction system, no PCs you don’t know in the who list, no game-wide OOC chat, etcetera), but also an extensive website, and wiki with IC information. It’s an attempt I think to control the IC/OOC split, but from many threads on the OOC web forum I’m not sure how successful that control has been. The web forum has a nifty mud-connected registration process (you generate a key in game to use for registration, presumably to control signups and reduce spam), but there was a bug and it didn’t work for me. Complicated complexity.

Overall I’d say much of this is natural. Muds grow organically. Geas is almost 15 years old, probably older than some of its players. In a way I don’t have a right to criticize it after playing it for a oouple of hours. In the end I found some sewers and fought some rats for a few minutes. It felt very familiar. From what I saw before I’m certain there’s a lot of depth to this game. A lot of complexity. But does it have to be so complicated?