<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Kooneiform</title>
	<atom:link href="https://kooneiform.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://kooneiform.wordpress.com</link>
	<description>writing  +  text  +  games</description>
	<lastBuildDate>Fri, 22 Mar 2013 05:22:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<site xmlns="com-wordpress:feed-additions:1">108553</site><cloud domain='kooneiform.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>https://s0.wp.com/i/buttonw-com.png</url>
		<title>Kooneiform</title>
		<link>https://kooneiform.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="https://kooneiform.wordpress.com/osd.xml" title="Kooneiform" />
	<atom:link rel='hub' href='https://kooneiform.wordpress.com/?pushpress=hub'/>
	<item>
		<title>making roguelikes with Clojure</title>
		<link>https://kooneiform.wordpress.com/2013/03/21/making-roguelikes-with-clojure/</link>
					<comments>https://kooneiform.wordpress.com/2013/03/21/making-roguelikes-with-clojure/#respond</comments>
		
		<dc:creator><![CDATA[georgek]]></dc:creator>
		<pubDate>Fri, 22 Mar 2013 05:22:56 +0000</pubDate>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[roguelike]]></category>
		<guid isPermaLink="false">http://kooneiform.wordpress.com/?p=774</guid>

					<description><![CDATA[Just a quick post to remind me and anyone else what writing RLs in Clojure looks like today (of course the Java landscape here is vast, so I&#8217;ll just cherry pick a couple of Java libraries). libs (for Clojurescript) http://tapiov.net/unicodetiles.js/ http://ondras.github.com/rot.js/hp/ (for Clojure) https://code.google.com/p/blacken/ https://github.com/SquidPony/SquidLib https://github.com/sjl/clojure-lanterna/ https://github.com/mikera/orculje games https://github.com/thomcc/dunjeon http://stevelosh.com/blog/2012/07/caves-of-clojure-01/ https://github.com/mikera/alchemy (see the README for [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Just a quick post to remind me and anyone else what writing RLs in Clojure looks like today (of course the Java landscape here is vast, so I&#8217;ll just cherry pick a couple of Java libraries). </p>
<p><strong>libs</strong></p>
<p><em>(for Clojurescript)<br />
</em><br />
<a href="http://tapiov.net/unicodetiles.js/" rel="nofollow">http://tapiov.net/unicodetiles.js/</a></p>
<p><a href="http://ondras.github.com/rot.js/hp/" rel="nofollow">http://ondras.github.com/rot.js/hp/</a></p>
<p><em>(for Clojure)<br />
</em><br />
<a href="https://code.google.com/p/blacken/" rel="nofollow">https://code.google.com/p/blacken/</a></p>
<p><a href="https://github.com/SquidPony/SquidLib" rel="nofollow">https://github.com/SquidPony/SquidLib</a></p>
<p><a href="https://github.com/sjl/clojure-lanterna/" rel="nofollow">https://github.com/sjl/clojure-lanterna/</a></p>
<p><a href="https://github.com/mikera/orculje" rel="nofollow">https://github.com/mikera/orculje</a></p>
<p><strong>games<br />
</strong><br />
<a href="https://github.com/thomcc/dunjeon" rel="nofollow">https://github.com/thomcc/dunjeon</a></p>
<p><a href="http://stevelosh.com/blog/2012/07/caves-of-clojure-01/" rel="nofollow">http://stevelosh.com/blog/2012/07/caves-of-clojure-01/</a></p>
<p><a href="https://github.com/mikera/alchemy" rel="nofollow">https://github.com/mikera/alchemy</a> (see the README for a link to the blog and a great series of blog posts in media 7DRL)</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kooneiform.wordpress.com/2013/03/21/making-roguelikes-with-clojure/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">774</post-id>
		<media:content url="https://2.gravatar.com/avatar/230e7eabd23df9bd7a5d67e335878848f30fef31651d3e52e0ffa1c7e3321821?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">georgek</media:title>
		</media:content>
	</item>
		<item>
		<title>Who was Rolindar?</title>
		<link>https://kooneiform.wordpress.com/2013/03/10/who-was-rolindar/</link>
					<comments>https://kooneiform.wordpress.com/2013/03/10/who-was-rolindar/#comments</comments>
		
		<dc:creator><![CDATA[georgek]]></dc:creator>
		<pubDate>Mon, 11 Mar 2013 02:35:48 +0000</pubDate>
				<category><![CDATA[muds]]></category>
		<guid isPermaLink="false">http://kooneiform.wordpress.com/?p=769</guid>

					<description><![CDATA[I&#8217;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 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I&#8217;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. </p>
<p>In my experience Rolindar&#8217;s areas are not to everyone&#8217;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&#8217;re curious you can search for some of his areas here, <a href="http://www.smaugmuds.org/index.php?a=files&#038;s=search" rel="nofollow">http://www.smaugmuds.org/index.php?a=files&#038;s=search</a> . </p>
<p>There must be other builders, past (and perhaps) present of Rolindar&#8217;s caliber; there surely are thousands of original mud areas out there. I wonder who would be in the &#8216;top 5 builders of all time&#8217;. 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&#8217;t a necessary question to answer in a hobby like this. No (well, let&#8217;s say <em>most</em>) builders don&#8217;t create areas to make a name for themselves, but out of a sense of contributing to a greater whole.</p>
<p>It does seem lacking though to have to create without a past. </p>
]]></content:encoded>
					
					<wfw:commentRss>https://kooneiform.wordpress.com/2013/03/10/who-was-rolindar/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">769</post-id>
		<media:content url="https://2.gravatar.com/avatar/230e7eabd23df9bd7a5d67e335878848f30fef31651d3e52e0ffa1c7e3321821?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">georgek</media:title>
		</media:content>
	</item>
		<item>
		<title>server in Clojure, fourth attempt</title>
		<link>https://kooneiform.wordpress.com/2013/03/03/server-in-clojure-fourth-attempt/</link>
					<comments>https://kooneiform.wordpress.com/2013/03/03/server-in-clojure-fourth-attempt/#respond</comments>
		
		<dc:creator><![CDATA[georgek]]></dc:creator>
		<pubDate>Mon, 04 Mar 2013 02:11:42 +0000</pubDate>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[muds]]></category>
		<guid isPermaLink="false">http://kooneiform.wordpress.com/?p=766</guid>

					<description><![CDATA[Getting closer! Manipulating ByteBuffers is a little tricky but also quite satisfying! Slowly adding error handling but also punting on a lot of stuff at the moment. The big breakthrough here is echo&#8217;ing input to all connected clients. The functions that do that, get-lines, write-lines, and echo-all, definitely need work though. I also borrowed a [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Getting closer! <span id="more-766"></span></p>
<pre class="brush: clojure; title: ; notranslate">
(ns exvarcis.core
  (:import [java.net InetAddress InetSocketAddress Socket]
           [java.nio ByteBuffer]
           [java.nio.charset Charset]
           [java.nio.channels
            ServerSocketChannel SocketChannel Selector SelectionKey]))

(defn buf-seq
  ([buf] (buf-seq buf 0))
  ([buf i]
   (lazy-seq  
      (when (&lt; i (.limit buf))
        (cons (.get buf i) (buf-seq buf (inc i)))))))

(let [c (atom 0)]
  (defn new-connection []
    {:id (swap! c inc)
     :writebuf (ByteBuffer/allocate 8096)
     :readbuf (ByteBuffer/allocate 8096)}))

(defmulti select-op
  (fn [k] (.readyOps k)))

(defmethod select-op :default [k]
  (println &quot;Default op.&quot;))

(defmethod select-op (SelectionKey/OP_ACCEPT) [k]
  (-&gt; 
    (.accept (.channel k))
    (.configureBlocking false)
    (.register (.selector k) (SelectionKey/OP_READ))
    (.attach (new-connection)))
  (println &quot;Client registered&quot;))

(defn close-connection [k]
  (println &quot;closing connection&quot; (.channel k))
  (.cancel k)
  (.close (.channel k)))

(defmethod select-op (SelectionKey/OP_READ) [k]
  (let
      [readbuf (-&gt; (.attachment k) (:readbuf))
       bytes-read (.read (.channel k) readbuf)]
    (when (= bytes-read -1)
      (close-connection k))))

(defn select! [selector]
  (.select selector)
  (let [ks (.selectedKeys selector)]
    (doseq [k ks]
      (select-op k))
    (.clear ks)))

(defn get-lines [buf]
  (let
    [dup-buf (.duplicate buf)
     original-limit (-&gt; dup-buf .flip .limit)
     last-newline (.lastIndexOf (vec (buf-seq dup-buf)) 10)]
    (when-not (= last-newline -1)
      (.flip buf)
      (.limit buf (inc last-newline))
      (let
        [lines (-&gt;&gt;
                  buf
                  (.decode (Charset/defaultCharset))
                  .toString
                  clojure.string/split-lines)]
        (.limit buf original-limit)
        (.compact buf)
        lines))))

(defn write-lines [lines k]
  (let
      [encoded-lines (-&gt;&gt; lines (.encode (Charset/defaultCharset)))
       buf (-&gt; (.attachment k) (:writebuf))]
    (when (&gt; (.limit encoded-lines) 0)
      (.put buf encoded-lines)
      (.flip buf)
      (.write (.channel k) buf)
      (.compact buf))))

(defn echo-all [ks]
  (let
    [readbufs (map #(-&gt; (.attachment %) (:readbuf)) ks)
     lines (mapcat get-lines readbufs)
     lines-with-crlf (str (clojure.string/join &quot;\r\n&quot; lines) &quot;\r\n&quot;)]
    (doseq [k ks]
      (write-lines lines-with-crlf k))))

(defn run [selector]
 (while true
   (select! selector)
   (echo-all (filter #(and (.isValid %) (.attachment %)) (.keys selector)))
   (Thread/sleep 3000)))

(defn start [handler]
  (let [selector (Selector/open)
        acceptor (-&gt;
                  (ServerSocketChannel/open)
                  (.configureBlocking false)
                  (.bind (InetSocketAddress. &quot;127.0.0.1&quot; 0)))]
    (.register acceptor selector (SelectionKey/OP_ACCEPT))
    (println &quot;Starting Ex v Arcis on&quot; (.getLocalAddress acceptor))
    (handler selector)))

(defn -main []
  (start run)
)</pre>
<p>Manipulating ByteBuffers is a <em>little </em>tricky but also quite satisfying! Slowly adding error handling but also punting on a lot of stuff at the moment. The big breakthrough here is echo&#8217;ing input to all connected clients. The functions that do that, <strong>get-lines</strong>, <strong>write-lines</strong>, and <strong>echo-all</strong>, definitely need work though. I also borrowed a coercion function, <strong>buf-seq</strong>, from Paul Stadig&#8217;s <a href="https://github.com/pjstadig/nio" rel="nofollow">https://github.com/pjstadig/nio</a> to make it easy to scan the buffer for newlines. Thanks Paul!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kooneiform.wordpress.com/2013/03/03/server-in-clojure-fourth-attempt/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">766</post-id>
		<media:content url="https://2.gravatar.com/avatar/230e7eabd23df9bd7a5d67e335878848f30fef31651d3e52e0ffa1c7e3321821?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">georgek</media:title>
		</media:content>
	</item>
		<item>
		<title>server in Clojure, third attempt, solely for posterity&#8217;s sake</title>
		<link>https://kooneiform.wordpress.com/2013/03/03/server-in-clojure-third-attempt-solely-for-posteritys-sake/</link>
					<comments>https://kooneiform.wordpress.com/2013/03/03/server-in-clojure-third-attempt-solely-for-posteritys-sake/#respond</comments>
		
		<dc:creator><![CDATA[georgek]]></dc:creator>
		<pubDate>Sun, 03 Mar 2013 17:15:01 +0000</pubDate>
				<category><![CDATA[clojure]]></category>
		<guid isPermaLink="false">http://kooneiform.wordpress.com/?p=762</guid>

					<description><![CDATA[This is not what you want to do.]]></description>
										<content:encoded><![CDATA[<p>This is <strong>not </strong>what you want to do. </p>
<pre class="brush: clojure; title: ; notranslate">
(ns exvarcis.core
  (:import [java.net InetAddress InetSocketAddress Socket]
           [java.nio ByteBuffer]
           [java.nio.charset Charset]
           [java.nio.channels
            ServerSocketChannel SocketChannel Selector SelectionKey]))

(defn buf-seq
  ([buf] (buf-seq buf 0))
  ([buf i]
   (lazy-seq  
      (when (&lt; i (.limit buf))
        (cons (.get buf i) (buf-seq buf (inc i)))))))

(let [c (atom 0)]
  (defn new-connection []
    {:id (swap! c inc)
     :writebuf (ByteBuffer/allocate 8096)
     :readbuf (ByteBuffer/allocate 8096)}))

(defmulti select-op
  (fn [k] (.readyOps k)))

(defmethod select-op :default [k]
  (println &quot;Default op.&quot;))

(defmethod select-op (SelectionKey/OP_ACCEPT) [k]
  (-&gt; 
    (.accept (.channel k))
    (.configureBlocking false)
    (.register (.selector k) (SelectionKey/OP_READ))
    (.attach (new-connection)))
  (println &quot;Client registered&quot;))

(defn close-connection [k]
  (println &quot;closing connection&quot; (.channel k))
  (.cancel k)
  (.close (.channel k)))

(defmethod select-op (SelectionKey/OP_READ) [k]
  (let
    [readbuf (-&gt; (.attachment k) (:readbuf))]
    (.read (.channel k) readbuf)
    (.flip readbuf)
    (when (= (.limit readbuf) 0)
      (close-connection k))))

(defn select! [selector]
  (.select selector)
  (let [ks (.selectedKeys selector)]
    (doseq [k ks]
      (select-op k))
    (.clear ks)))

(defn get-lines [buf]
  (let
    [original-limit (.limit buf)
    last-newline (.lastIndexOf (vec (buf-seq buf)) 10)]
    (when-not (= last-newline -1)
      (.limit buf (inc last-newline))
      (let
        [lines (-&gt;&gt;
                  buf
                  (.decode (Charset/defaultCharset))
                  .toString
                  clojure.string/split-lines)]
        (.limit buf original-limit)
        (.compact buf)
        lines))))

(defn write-lines [lines buf k]
  (let
      [encoded-lines (-&gt;&gt; lines (.encode (Charset/defaultCharset)))]
    (when (&gt; (.limit encoded-lines) 0)
      (.put buf encoded-lines)
      (.flip buf)
      (.write (.channel k) buf)
      (.compact buf)
      (println buf))))

(defn write-all [ks]
  (let
    [bufs (map #(-&gt; (.attachment %) (:readbuf)) ks)
     lines (mapcat get-lines bufs)
     lines-with-crlf (str (clojure.string/join &quot;\r\n&quot; lines) &quot;\r\n&quot;)
     bufs (map #(-&gt; (.attachment %) (:writebuf)) ks)]
    (doseq [[buf k] (map list bufs ks)]
      (write-lines lines-with-crlf buf k))))

(defn run [selector]
 (while true
   (select! selector)
   (write-all (filter #(.attachment %) (.keys selector)))
   (Thread/sleep 3000)))

(defn start [handler]
  (let [selector (Selector/open)
        acceptor (-&gt;
                  (ServerSocketChannel/open)
                  (.configureBlocking false)
                  (.bind (InetSocketAddress. &quot;127.0.0.1&quot; 0)))]
    (.register acceptor selector (SelectionKey/OP_ACCEPT))
    (println &quot;Starting Ex v Arcis on&quot; (.getLocalAddress acceptor))
    (handler selector)))

(defn -main []
  (start run)
)</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://kooneiform.wordpress.com/2013/03/03/server-in-clojure-third-attempt-solely-for-posteritys-sake/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">762</post-id>
		<media:content url="https://2.gravatar.com/avatar/230e7eabd23df9bd7a5d67e335878848f30fef31651d3e52e0ffa1c7e3321821?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">georgek</media:title>
		</media:content>
	</item>
		<item>
		<title>server in Clojure, second attempt</title>
		<link>https://kooneiform.wordpress.com/2013/02/12/server-in-clojure-second-attempt/</link>
					<comments>https://kooneiform.wordpress.com/2013/02/12/server-in-clojure-second-attempt/#respond</comments>
		
		<dc:creator><![CDATA[georgek]]></dc:creator>
		<pubDate>Wed, 13 Feb 2013 05:23:27 +0000</pubDate>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[muds]]></category>
		<guid isPermaLink="false">http://kooneiform.wordpress.com/?p=757</guid>

					<description><![CDATA[Getting better &#8212; shortened -main by moving logic into multimethods. I like how those work; you don&#8217;t need a conditional branch to test which operation to do, which makes the doseq nice. In the case of a select call it&#8217;s not that big a deal since there are only a few operations, but what the [&#8230;]]]></description>
										<content:encoded><![CDATA[<pre class="brush: clojure; title: ; notranslate">
(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 (-&gt; 
        (.accept (:acceptor server))
        (.configureBlocking false)
        (.register (:selector server) (SelectionKey/OP_READ)))
      (println &quot;Client registered&quot;)))

(defmethod select-op :default [chkey server]
  (println &quot;Default op.&quot;))

(defn start []
  (let [acc (-&gt; (ServerSocketChannel/open) (.configureBlocking false) (.bind (InetSocketAddress. &quot;127.0.0.1&quot; 0)))
        sel (Selector/open)]
    (.register acc sel (SelectionKey/OP_ACCEPT))
    {:selector sel :acceptor acc}))

(defn -main []
  (let [server (start)
        sel (:selector server)]
    (println &quot;Starting Ex v Arcis on&quot; (.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)))))
</pre>
<p>Getting better &#8212; shortened -main by moving logic into multimethods. I like how those work; you don&#8217;t need a conditional branch to test which operation to do, which makes the <em>doseq </em>nice. In the case of a <em>select </em>call it&#8217;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 <em>Thread/sleep</em> is just there so I have time to watch stuff in the repl by the way &#8212; I&#8217;ll have to put a stop condition in the <em>while </em>there eventually too, right now I just interrupt it at the repl. </p>
<p>The <em>while </em> is just a macro for a <em>loop/when/recur</em>. I keep thinking that there&#8217;s some way to do that with an infinite lazy sequence, but maybe not. </p>
<p><span id="more-757"></span><br />
<strong>edit</strong>: couldn&#8217;t resist some refactoring:</p>
<pre class="brush: clojure; title: ; notranslate">
(ns exvarcis.core
  (:import [java.net InetAddress InetSocketAddress Socket]
           [java.nio ByteBuffer]
           [java.nio.channels ServerSocketChannel SocketChannel Selector SelectionKey]))

(defn selector []
  (Selector/open))

(defn acceptor []
  (-&gt; (ServerSocketChannel/open) (.configureBlocking false) (.bind (InetSocketAddress. &quot;127.0.0.1&quot; 0))))

(defmulti select-op
  (fn [k] (.readyOps k)))

(defmethod select-op (SelectionKey/OP_ACCEPT) [k]
  (do (-&gt; 
        (.accept (.channel k))
        (.configureBlocking false)
        (.register (.selector k) (SelectionKey/OP_READ)))
      (println &quot;Client registered&quot;)))

(defmethod select-op :default [k]
  (println &quot;Default op.&quot;))

(defn start! []
  (let [selector (selector)
        acceptor (acceptor)]
    (.register acceptor selector (SelectionKey/OP_ACCEPT))
    {:selector selector :acceptor acceptor}))

(defn -main []
  (let [{:keys [selector acceptor]} (start!)]
    (println &quot;Starting Ex v Arcis on&quot; (.getLocalAddress acceptor))
    (while true
      (.select selector)
      (let [ks (.selectedKeys selector)]
        (doseq [k ks]
          (select-op k))
        (.clear ks)
        (Thread/sleep 3000)))))
</pre>
<p><strong>Refactoring: can&#8217;t stop won&#8217;t stop<br />
</strong></p>
<pre class="brush: clojure; title: ; notranslate">
(ns exvarcis.core
  (:import [java.net InetAddress InetSocketAddress Socket]
           [java.nio ByteBuffer]
           [java.nio.channels ServerSocketChannel SocketChannel Selector SelectionKey]))

(defn selector []
  (Selector/open))

(defn acceptor []
  (-&gt; (ServerSocketChannel/open) (.configureBlocking false) (.bind (InetSocketAddress. &quot;127.0.0.1&quot; 0))))

(defmulti select-op
  (fn [k] (.readyOps k)))

(defmethod select-op (SelectionKey/OP_ACCEPT) [k]
  (do (-&gt; 
        (.accept (.channel k))
        (.configureBlocking false)
        (.register (.selector k) (SelectionKey/OP_READ)))
      (println &quot;Client registered&quot;)))

(defmethod select-op :default [k]
  (println &quot;Default op.&quot;))

(defn handler [selector]
 (while true
      (.select selector)
      (let [ks (.selectedKeys selector)]
        (doseq [k ks]
          (select-op k))
        (.clear ks)
        (Thread/sleep 3000))))

(defn create-server [handler]
  (let [selector (selector)
        acceptor (acceptor)]
    (.register acceptor selector (SelectionKey/OP_ACCEPT))
    (println &quot;Starting Ex v Arcis on&quot; (.getLocalAddress acceptor))
    (handler selector)))

(defn -main []
  (create-server handler))
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://kooneiform.wordpress.com/2013/02/12/server-in-clojure-second-attempt/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">757</post-id>
		<media:content url="https://2.gravatar.com/avatar/230e7eabd23df9bd7a5d67e335878848f30fef31651d3e52e0ffa1c7e3321821?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">georgek</media:title>
		</media:content>
	</item>
		<item>
		<title>A single-threaded multiplexing server in Clojure, first attempt</title>
		<link>https://kooneiform.wordpress.com/2013/02/04/a-single-threaded-multiplexing-server-in-clojure-first-attempt/</link>
					<comments>https://kooneiform.wordpress.com/2013/02/04/a-single-threaded-multiplexing-server-in-clojure-first-attempt/#comments</comments>
		
		<dc:creator><![CDATA[georgek]]></dc:creator>
		<pubDate>Tue, 05 Feb 2013 06:17:31 +0000</pubDate>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[muds]]></category>
		<guid isPermaLink="false">http://kooneiform.wordpress.com/?p=748</guid>

					<description><![CDATA[No doubt due to the influence of the recent MudBytes thread about &#8220;keeping it simple&#8221; I&#8217;m currently having a go with writing Ex v Arcis from the ground up, more or less&#8230;hmm, I may have misinterpreted that thread. But anyway, here&#8217;s the first attempt. It&#8217;s very bad, but it gets the job done. Well, sort [&#8230;]]]></description>
										<content:encoded><![CDATA[<pre class="brush: clojure; title: ; notranslate">
(ns exvarcis.core
  (:import [java.net InetAddress InetSocketAddress Socket]
           [java.nio ByteBuffer]
           [java.nio.channels ServerSocketChannel SocketChannel Selector SelectionKey]))

(defn start []
  (let [acc (-&gt; (ServerSocketChannel/open) (.configureBlocking false) (.bind (InetSocketAddress. &quot;127.0.0.1&quot; 0)))
        sel (Selector/open)]
    (.register acc sel (SelectionKey/OP_ACCEPT))
    {:selector sel :acceptor acc}))

(defn -main []
  (let [server (start)]
    (println &quot;Starting Ex v Arcis on&quot; (.getLocalAddress (:acceptor server)))
    (while true
      (.select (:selector server))
      (let [sel-keys (.selectedKeys (:selector server))]
        (doseq [ch-key sel-keys]
          (cond
           (.isAcceptable ch-key)
           (do (-&gt;
                (.accept (:acceptor server))
                (.configureBlocking false)
                (.register (:selector server) (SelectionKey/OP_READ)))
               (println &quot;Client registered&quot;))))
        (.clear (.selectedKeys (:selector server))))
      (Thread/sleep 3000))))
</pre>
<p>No doubt due to the influence of the recent MudBytes thread about &#8220;keeping it simple&#8221; I&#8217;m currently having a go with writing Ex v Arcis from the ground up, more or less&#8230;hmm, I may have misinterpreted that thread. But anyway, here&#8217;s the first attempt. It&#8217;s very bad, but it gets the job done. Well, sort of &#8212; all it does at the moment is accept new connections.</p>
<p>What&#8217;s awful about it? I could be wrong as I&#8217;m just learning Clojure and barely know Java, but I don&#8217;t think I have a good handle on the Java interop yet. It&#8217;s a bit hard to figure out as at the moment it&#8217;s mostly <em>all </em>Java interop. Dealing with mutable Java collections (the <em>selectedKeys </em>for example of the <strong>Selector</strong>) with Clojure collection functions (like <em>doseq</em>) is still a little beyond my grasp. But it&#8217;s a start. </p>
<p>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. </p>
<p><a href="http://onjava.com/pub/a/onjava/2002/09/04/nio.html?page=1" rel="nofollow">http://onjava.com/pub/a/onjava/2002/09/04/nio.html?page=1</a></p>
<p><a href="http://rox-xmlrpc.sourceforge.net/niotut/index.html" rel="nofollow">http://rox-xmlrpc.sourceforge.net/niotut/index.html</a></p>
<p><a href="http://www.owlmountain.com/tutorials/NonBlockingIo.htm#_Toc524339526" rel="nofollow">http://www.owlmountain.com/tutorials/NonBlockingIo.htm#_Toc524339526</a></p>
<p>For Java interop with Clojure the standard Java docs are of course indispensable:</p>
<p><a href="http://docs.oracle.com/javase/7/docs/api/java/nio/channels/ServerSocketChannel.html" rel="nofollow">http://docs.oracle.com/javase/7/docs/api/java/nio/channels/ServerSocketChannel.html</a></p>
<p>Finally, if you had to look at one mud as an example, I think I would choose Miniboa:</p>
<p><a href="http://code.google.com/p/miniboa/" rel="nofollow">http://code.google.com/p/miniboa/</a></p>
<p>The file async.py (<a href="http://code.google.com/p/miniboa/source/browse/trunk/miniboa/async.py" rel="nofollow">http://code.google.com/p/miniboa/source/browse/trunk/miniboa/async.py</a> ) is what you want, though the Telnet implementation is a great reference too. </p>
<p>I would be remiss if I did not mention Mire, <a href="https://github.com/technomancy/mire/blob/master/src/mire/server.clj" rel="nofollow">https://github.com/technomancy/mire/blob/master/src/mire/server.clj</a> , 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&#8217;s concurrency story. Perhaps in the end that&#8217;ll be the way to go. But I had a hankering to write a single-threaded non-blocking server, so for now that&#8217;s the path I&#8217;ll take. </p>
<p>edit: </p>
<p>Somehow I missed this: </p>
<p><a href="http://pepijndevos.nl/2011/06/18/nio-in-clojure.html" rel="nofollow">http://pepijndevos.nl/2011/06/18/nio-in-clojure.html</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://kooneiform.wordpress.com/2013/02/04/a-single-threaded-multiplexing-server-in-clojure-first-attempt/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">748</post-id>
		<media:content url="https://2.gravatar.com/avatar/230e7eabd23df9bd7a5d67e335878848f30fef31651d3e52e0ffa1c7e3321821?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">georgek</media:title>
		</media:content>
	</item>
		<item>
		<title>First, there was the wheel. Then there was another wheel.</title>
		<link>https://kooneiform.wordpress.com/2013/01/31/first-there-was-the-wheel-then-there-was-another-wheel/</link>
					<comments>https://kooneiform.wordpress.com/2013/01/31/first-there-was-the-wheel-then-there-was-another-wheel/#respond</comments>
		
		<dc:creator><![CDATA[georgek]]></dc:creator>
		<pubDate>Fri, 01 Feb 2013 03:30:01 +0000</pubDate>
				<category><![CDATA[muds]]></category>
		<guid isPermaLink="false">http://kooneiform.wordpress.com/?p=742</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[<pre class="brush: clojure; title: ; notranslate">
(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 (-&gt;
         (ServerSocketChannel/open)
         (.configureBlocking false)
         (.bind nil 0))}))

(defn -main []
  (do
    (.register (:ch @acceptor) @selector (SelectionKey/OP_ACCEPT))
    (println &quot;Starting Ex V Arcis on&quot; (InetAddress/getLocalHost))))
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://kooneiform.wordpress.com/2013/01/31/first-there-was-the-wheel-then-there-was-another-wheel/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">742</post-id>
		<media:content url="https://2.gravatar.com/avatar/230e7eabd23df9bd7a5d67e335878848f30fef31651d3e52e0ffa1c7e3321821?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">georgek</media:title>
		</media:content>
	</item>
		<item>
		<title>a micro mud?</title>
		<link>https://kooneiform.wordpress.com/2013/01/27/a-micro-mud/</link>
					<comments>https://kooneiform.wordpress.com/2013/01/27/a-micro-mud/#respond</comments>
		
		<dc:creator><![CDATA[georgek]]></dc:creator>
		<pubDate>Mon, 28 Jan 2013 00:36:15 +0000</pubDate>
				<category><![CDATA[muds]]></category>
		<guid isPermaLink="false">http://kooneiform.wordpress.com/?p=738</guid>

					<description><![CDATA[Inspired by a recent thread at MudBytes I&#8217;ve been thinking about what it would take to put out a small, playable, fun mud. I slimmed down an idea I&#8217;ve been sketching on recently and this is what I have so far. You, a champion warrior, fight for dominance within a dark and mysterious castle prison. [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Inspired by <a href="http://www.mudbytes.net/topic-4140">a recent thread at MudBytes</a> I&#8217;ve been thinking about what it would take to put out a small, playable, fun mud. I slimmed down an idea I&#8217;ve been sketching on recently and this is what I have so far. </p>
<p><a href="https://kooneiform.wordpress.com/wp-content/uploads/2013/01/exvarcis_header.png"><img data-attachment-id="739" data-permalink="https://kooneiform.wordpress.com/2013/01/27/a-micro-mud/exvarcis_header/" data-orig-file="https://kooneiform.wordpress.com/wp-content/uploads/2013/01/exvarcis_header.png" data-orig-size="468,60" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="exVarcis_header" data-image-description="" data-image-caption="" data-medium-file="https://kooneiform.wordpress.com/wp-content/uploads/2013/01/exvarcis_header.png?w=300" data-large-file="https://kooneiform.wordpress.com/wp-content/uploads/2013/01/exvarcis_header.png?w=468" src="https://kooneiform.wordpress.com/wp-content/uploads/2013/01/exvarcis_header.png?w=480" alt="exVarcis_header"   class="aligncenter size-full wp-image-739" srcset="https://kooneiform.wordpress.com/wp-content/uploads/2013/01/exvarcis_header.png 468w, https://kooneiform.wordpress.com/wp-content/uploads/2013/01/exvarcis_header.png?w=150&amp;h=19 150w, https://kooneiform.wordpress.com/wp-content/uploads/2013/01/exvarcis_header.png?w=300&amp;h=38 300w" sizes="(max-width: 468px) 100vw, 468px" /></a></p>
<p>You, a champion warrior, fight for dominance within a dark and mysterious castle prison.</p>
<p>* every character gets a home room which you can&#8217;t lose.<br />
* you win control of new rooms.<br />
* you have one stat, dominus.<br />
* you&#8217;re ranked on a leaderboard by (number of rooms won) * dominus<br />
* you find wards to use battling other players, and to set as defenses on rooms.<br />
* wards are single-use and usually have a timed delay.<br />
* when you win a number of rooms greater than dominus, you reincarnate.<br />
* 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.<br />
* 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).<br />
* 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.<br />
* every character can have one piece of gear that will affect ward effects in some way.<br />
* as your won rooms approach max dominus, your chance to warp increases. You warp in order, so pure -&gt; twisted -&gt; reversed -&gt; inverted.<br />
* once warped, you may revert to a prior warp, or push to a higher warp, using warping wards.<br />
* the more wards in a single location, the higher chance of wards going off with unpredictable results. </p>
]]></content:encoded>
					
					<wfw:commentRss>https://kooneiform.wordpress.com/2013/01/27/a-micro-mud/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">738</post-id>
		<media:content url="https://2.gravatar.com/avatar/230e7eabd23df9bd7a5d67e335878848f30fef31651d3e52e0ffa1c7e3321821?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">georgek</media:title>
		</media:content>

		<media:content url="https://kooneiform.wordpress.com/wp-content/uploads/2013/01/exvarcis_header.png" medium="image">
			<media:title type="html">exVarcis_header</media:title>
		</media:content>
	</item>
		<item>
		<title>Good advice</title>
		<link>https://kooneiform.wordpress.com/2013/01/25/good-advice/</link>
					<comments>https://kooneiform.wordpress.com/2013/01/25/good-advice/#respond</comments>
		
		<dc:creator><![CDATA[georgek]]></dc:creator>
		<pubDate>Fri, 25 Jan 2013 19:38:16 +0000</pubDate>
				<category><![CDATA[>]]></category>
		<category><![CDATA[muds]]></category>
		<category><![CDATA[mud]]></category>
		<guid isPermaLink="false">http://kooneiform.wordpress.com/?p=734</guid>

					<description><![CDATA[1) Start it yourself, and be prepared to do it yourself. This doesn&#8217;t mean you will be doing everything yourself, and it doesn&#8217;t mean you can&#8217;t give things to other people. It means that if you don&#8217;t have anyone else to do something, you have to be prepared to do it yourself. 2) Get something [&#8230;]]]></description>
										<content:encoded><![CDATA[<blockquote>
<p>1) Start it yourself, and be prepared to do it yourself. This doesn&#8217;t mean you will be doing everything yourself, and it doesn&#8217;t mean you can&#8217;t give things to other people. It means that if you don&#8217;t have anyone else to do something, you have to be prepared to do it yourself.</p>
<p>2) Get something working, even if it&#8217;s simple and sucks, as quickly as possible. If you have something that works and sucks, you&#8217;ll want to improve it and make it suck less, which is good motivation.</p>
<p>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&#8217;re doing and why.</p>
<p>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.</p>
<p>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.</p>
<p>5) If something needs to get done, sit down and do it. Don&#8217;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&#8217;t want to, the result will be poor.</p>
</blockquote>
<p> </p>
<p>(thanks <a href="http://mudconnect.com/discuss/discuss.cgi?mode=MSG&amp;area=positions&amp;message=37420#37420">dentin</a>)</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kooneiform.wordpress.com/2013/01/25/good-advice/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">734</post-id>
		<media:content url="https://2.gravatar.com/avatar/230e7eabd23df9bd7a5d67e335878848f30fef31651d3e52e0ffa1c7e3321821?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">georgek</media:title>
		</media:content>
	</item>
		<item>
		<title>on the banks of the O-rontes</title>
		<link>https://kooneiform.wordpress.com/2012/12/06/on-the-banks-of-the-o-rontes/</link>
					<comments>https://kooneiform.wordpress.com/2012/12/06/on-the-banks-of-the-o-rontes/#comments</comments>
		
		<dc:creator><![CDATA[georgek]]></dc:creator>
		<pubDate>Fri, 07 Dec 2012 06:45:43 +0000</pubDate>
				<category><![CDATA[muds]]></category>
		<guid isPermaLink="false">http://kooneiform.wordpress.com/?p=730</guid>

					<description><![CDATA[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 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I just wanted to highlight a rather interesting MOO-like project I came across on Github, <a href="https://github.com/philchristensen/antioch" title="Antioch on Github" target="_blank">Antioch</a>. According to the readme, </p>
<blockquote><p>
Django-powered, standards-compliant web interface using Bootstrap, jQuery, REST and COMET</p>
<p>Sandboxed Pure-Python execution enables live programming of in-game code</p>
<p>PostgreSQL-backed object store scales to million of objects and provides transactional security during verb execution</p>
<p>Flexible plugin system, highly scalable messaging using RabbitMQ
</p></blockquote>
<p>I can&#8217;t say how far along it is but it looks pretty impressive. The author&#8217;s name, Phil Christensen, rang a bell &#8212; 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! </p>
]]></content:encoded>
					
					<wfw:commentRss>https://kooneiform.wordpress.com/2012/12/06/on-the-banks-of-the-o-rontes/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">730</post-id>
		<media:content url="https://2.gravatar.com/avatar/230e7eabd23df9bd7a5d67e335878848f30fef31651d3e52e0ffa1c7e3321821?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">georgek</media:title>
		</media:content>
	</item>
	</channel>
</rss>
