<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>sk89q</title>
	
	<link>http://www.sk89q.com</link>
	<description />
	<lastBuildDate>Tue, 31 Jan 2012 19:15:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/sk89q" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="sk89q" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>On the framework I previously posted about</title>
		<link>http://www.sk89q.com/2012/01/on-the-framework-i-previously-posted-about/</link>
		<comments>http://www.sk89q.com/2012/01/on-the-framework-i-previously-posted-about/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 22:13:33 +0000</pubDate>
		<dc:creator>sk89q</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.sk89q.com/?p=1751</guid>
		<description><![CDATA[The plugin framework I wrote about probably isn&#8217;t going to be released, as I&#8217;ve never really had the time to set out to do that (not to mention writing documentation and what not). However, a lot of my ideas have &#8230; <a href="http://www.sk89q.com/2012/01/on-the-framework-i-previously-posted-about/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.sk89q.com/2011/10/how-i-stay-sane-while-updating-my-minecraft-server/">plugin framework I wrote about</a> probably isn&#8217;t going to be released, as I&#8217;ve never really had the time to set out to do that (not to mention writing documentation and what not). However, a lot of my ideas have already inspired other people&#8217;s work, so you can find:</p>
<ol>
<li>For my <strong>component loading</strong> framework, quite a few people have contacted me about their attempts at re-implementing it. zml2008 has implemented one version in <a href="https://github.com/sk89q/commandbook">CommandBook</a>. I don&#8217;t know the details of it, but I assume it&#8217;s fairly similar to mine.</li>
<li>For my <strong>event handling</strong> framework, a number of people also told me about their work, but you can find a relatively new implementation of my event system in Bukkit, written by zml2008. It uses annotations as described in my system.</li>
<li>For my <strong>command handling</strong> framework, that can be found in <a href="https://github.com/sk89q/worldedit">WorldEdit</a>. I have to admit that this code is around a year old, but it performs fairly well, and it&#8217;s the exact same one I use in my framework.</li>
<li>For my <strong>permissions</strong> framework, which I didn&#8217;t really touch on in the post, at least it lives in the form of perm.issions.nodes, which is something I proposed in January 2011 (Nijiko-kun then wrote the Permissions plugin after he read what I wrote on IRC, many other people wrote later similar versions, and now Bukkit has a different built-in framework). However, if you want to link commands and permissions, you can do that either via WorldEdit&#8217;s command handler or via Bukkit&#8217;s plugin.yml.</li>
<li>For my <strong>configuration system</strong>, which I don&#8217;t think I really mentioned, I am not aware of any implementation of that (then again, I didn&#8217;t go deep into it). The configuration in Bukkit is also based off of my previous work, but it&#8217;s not as streamlined as in my framework.</li>
</ol>
<p>So while I definitely haven&#8217;t posted a lot of my code, many other people have already implemented a lot of my ideas, so it&#8217;s possible to gather the above work into one single framework if you&#8217;re willing to put in a little work. The idea of my framework, as with any framework, was to make rapid development both quick and as bug-free as possible. Java can be a real pain to work with, but these frameworks have made development much easier.</p>
<p>I&#8217;d also like to make a note about avoiding HashMaps in event systems. HashMaps have a definite purpose, but they can be slow, even with proper hash functions, so if you plan to have a high volume of events, you may want to avoid them. The framework I described in my post used HashMaps simply because it&#8217;s a non-issue in the environment I use it in (I recommend profiling instead of prematurely optimizing). &#8220;Fast events&#8221; were discussed by lahwran and I back when we were working on a project together, and although I (unsurprisingly) never posted my code, <a href="https://github.com/lahwran/fastevents">her work can be found on GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sk89q.com/2012/01/on-the-framework-i-previously-posted-about/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Minecraft modding, then and now</title>
		<link>http://www.sk89q.com/2011/12/minecraft-modding-then-and-now/</link>
		<comments>http://www.sk89q.com/2011/12/minecraft-modding-then-and-now/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 11:16:51 +0000</pubDate>
		<dc:creator>sk89q</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Minecraft]]></category>

		<guid isPermaLink="false">http://www.sk89q.com/?p=1738</guid>
		<description><![CDATA[tl;dr: Potentially upcoming crapfest &#38; drama for MC modding! Whooo. Added 12/16: Last paragraph I started making mods not long after the SMP server mod &#8220;hMod&#8221; came out around September 2010. Before hMod, you had either regular hard-coded mods similar &#8230; <a href="http://www.sk89q.com/2011/12/minecraft-modding-then-and-now/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>tl;dr: Potentially upcoming crapfest &amp; drama for MC modding! Whooo.</p>
<p><ins>Added 12/16: Last paragraph</ins></p>
<p>I started making mods not long after the SMP server mod &#8220;hMod&#8221; came out around September 2010. Before hMod, you had either regular hard-coded mods similar to how you have it on single player or simplistic “server wrappers” that didn’t let you do much to the game itself. hMod was different: it was the first time that you could write “plugins” for the server so that you could easily extend it, and because your plugin would mostly access hMod’s code, you wouldn’t have to update your plugin so much whenever Minecraft got updated. With this fantastic new development, I made WorldEdit, WorldGuard, CraftBook, and CommandHelper over the last quarter of the year. Unfortunately, not only was hMod on shaky legal ground, the code was a complete mess. If you wanted to adjust an event and add new features to it, you’d single-handedly break all the plugins that used that event. I felt uneasy about hMod’s future and wrote WorldEdit and WorldGuard in a way where I could easily port it to some new mod in case hMod died.</p>
<p>Well die it did. Only a few months later, towards the end of December 2010, a few guys secretly started up a project called Bukkit as a replacement. It was to borrow its predecessor’s best ideas while fixing its worst faults. The community for hMod was sizable, and Bukkit needed momentum in order to get adopted, especially as most server owners wouldn’t want to completely dump everything to switch to something completely brand new. With that transition, for better or worse, I helped by declaring that all future releases of my plugins would only be for Bukkit. As my plugins were pretty popular (least to say), especially CraftBook, that pretty much put the nail in the coffin for hMod and gave Bukkit life. I had good reasons to back my decision, however. The author of hMod had completely become unreachable for several weeks, and while Minecraft was still getting updated with new versions, no one left had the ability to post new versions of hMod. That wasn’t good, and it was put the future of hMod in deep question. Giving Bukkit a chance seemed like the best idea. This was around the beginning of January 2011.</p>
<p>I was enthusiastic about Bukkit at the time, and I got WorldEdit and WorldGuard ported pretty quickly (CraftBook wasn’t written to be ported easily, and those who are familiar with CraftBook are probably familiar with its fate).  I helped Bukkit by designing the permissions system that everyone uses (with.the.nodes), as well by writing the original configuration classes and vehicle events. For the first month or so, things were rosy, but the frequency of commits to my own projects had started to fall sharply. While I was definitely busier that part of the year, the magic had faded away, and my hope that Bukkit would be the bastion of extensibility had disappeared. While there were technical issues to blame for that, there were also (and arguable still are) very strong opinions among the core team’s members about what people should be able to do and what they shouldn’t be able to do. Politics became an important fact of life suddenly. My frequency of commits to Bukkit fell even sharper. A few months later, unsurprisingly, someone started writing a mod to Bukkit itself to allow you to do things that Bukkit wouldn’t let you do. It was originally named BukkitDev, but later it changed its name to Spout.  The community also changed. Everything had become cutthroat, and everyone wanted to be famous and popular (or small-time rich, as the case may be). People would write plugins to do exactly the same thing as another person’s plugins, and often times these copy-cats would even be inferior. I wouldn’t be surprised if 50% of the Bukkit plugins available right now solely exist to block fire and TNT usage. </p>
<p>Throughout this time, While Notch has been fairly indecisive on several occasions, he did have an opinion that Mojang shouldn’t give any preference to any particular user-made mod, and never really endorsed Bukkit, hMod, or anything else. Bukkit entered in discussions with Mojang in early 2011 in hope that Mojang would embrace Bukkit with official support, but these exchanges did not progress at all. This impartiality was a good thing, but it had its downsides. There was always some fragmentation in the community – not everything was happy with what Bukkit did, and others were definitely not a fan of the person who led Bukkit. Canary was born out of hMod as its direct successor (sometime in early 2011), with several original hMod fans as a part of the team, but it never gained traction against Bukkit. I personally never ported any of my mods to Canary after that split happened (mostly due to a matter of time constraints). However, while Canary had really little traction, it always had the chance at becoming the top server mod through hard work and ingenuity, largely due to Notch’s impartiality.</p>
<p>Sometime earlier this year though, Bukkit gained a corporate partner: Curse.com. They’d host the website and also fund the project, but Curse.com also was the owner of the Minecraft forums, which they had purchased previously from a bunch of Minecraft fans who started it a long time back. This obviously gave them an enormous amount of power to move the community in certain directions, and with them behind Bukkit, that meant that Bukkit had resources that no other project could dream of (recently Bukkit got front page attention on the Minecraft forums <a href="http://www.youtube.com/watch?v=uXhTasEzUmQ">with a video</a> that reeked favoritism for the server, surprise, that Bukkit’s project leader is an administrator on). About this time, I had started to scale back my contributions to Minecraft, as I figure I’d be in for more doom and gloom again. Those who watched me on GitHub closely may have noticed that my contributions to my own plugins and completely evaporated since summer of this year and I’ve been thankful to all the other people who have picked up the slack.</p>
<p>The news now is that, with Notch having moved on and jeb having taken the reins of the project, Bukkit will be responsible for the client modding API. I can’t confirm that particular fact (I’ve been pretty disconnected for the past few months), but I’ve heard that a lot of modders are not happy. Notch is no longer the lead for Minecraft, and so it would not be unreasonable for this decision to have been made. The problem that some modders have with this is that Bukkit has been exceptionally limiting (especially evident by the need for BukkitDev/Spout) and so a number of modders fear that they won’t be able to do all the great and cool mods used to be able to do. The opinions of the core Bukkit team have always been strong in allowing some mods and disallowing others. If this is so, the multiplayer and single player modding communities will finally merge in an official capacity.</p>
<p>When you’ve got two sides with grossly different opinions, there’s a minor chance that the community will fragment. I’ve heard wind of a few plans from various people myself, and we may have a modding community split brewing for the future. If that does happen, it’d be interesting as to whether the other side would be able to muster the clout, as Mojang will control the client and the forums will not be in impartial hands. As for me, I have to say that I have enjoyed Minecraft a lot, a lot more than any other game that I have played. Notch and the Mojang team have done a great job at making such a fantastic game, and I’ve met a lot of great and creative people throughout my time in the community. I’m not disappearing by any means, and I’ll probably be popping in still to manage my plugins, but I’m officially going to watch things settle down, hopefully this time for good, whenever that may be.</p>
<p>I’m not advocating for any option here. I’ve tried to keep politics away from my contributions, as most of us here, including myself, are here to have fun. However, if anyone wanted to see a server-client modding framework that has worked especially well though, you only need to look to the fabulous work in Garry’s Mod. Servers can (safely) send entirely self-contained client mods (written in Lua) to connecting players, which would work wonderfully in tandem with mods on the server. There are completely brand new gamemodes on plenty of servers. Minecraft modding, on the other hand, has been grossly inferior – full of politics and filled with the great rise and fall of many mods.</p>
<p>On another note, I actually worked on a server-client modding framework with lahwran and some other folk many months back (<a href="http://whois.domaintools.com/craftengine.net">we even registered a domain name in June 2011</a>). The idea was that servers would be able to send client mods to clients, and these mods would access a completely abstracted sandbox API. However, when that failed, it was still possible to also load separate client .class mods (not auto-downloaded, however), so you&#8217;d basically have the best of both worlds. Single player mods could also be written under the API. The main issues of the time were that Java is exceptionally un-dynamic, so giving mods the expressive power they needed was difficult. Sandboxing was a difficult matter, and we weren&#8217;t even sure if we should let mods access OpenGL, as there are already webpages that can crash your graphics drivers, simply because they have limited access to OpenGL (though no worse exploits exist, as far as I know). A lot of code and planning got done, but we abandoned it because of both time constraints and the uphill climb that we were facing to achieve adoption (it would require both server and client interaction)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sk89q.com/2011/12/minecraft-modding-then-and-now/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>State of WorldEdit and friends</title>
		<link>http://www.sk89q.com/2011/12/state-of-worldedit-and-friends/</link>
		<comments>http://www.sk89q.com/2011/12/state-of-worldedit-and-friends/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 16:46:02 +0000</pubDate>
		<dc:creator>sk89q</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[CommandBook]]></category>
		<category><![CDATA[Minecraft]]></category>
		<category><![CDATA[WorldEdit]]></category>
		<category><![CDATA[WorldGuard]]></category>

		<guid isPermaLink="false">http://www.sk89q.com/?p=1728</guid>
		<description><![CDATA[Currently everything is still maintained (except perhaps CraftBook, but that&#8217;s not new news), but a lot of it has been passed on to a few others: zml2008 will be managing release for the most part for CommandBook, WorldGuard, and perhaps &#8230; <a href="http://www.sk89q.com/2011/12/state-of-worldedit-and-friends/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Currently everything is still maintained (except perhaps CraftBook, but that&#8217;s not new news), but a lot of it has been passed on to a few others:</p>
<ul>
<li>zml2008 will be managing release for the most part for CommandBook, WorldGuard, and perhaps WorldEdit.</li>
<li>TomyLobo is currently a lead developer on WorldEdit and handles a lot of the cool new features. (He also <a href="https://twitter.com/tomylobo2">has a Twitter account</a>.)</li>
<li>famerdave will be helping on/off with CommandBook.</li>
<li>I will still be around, but sometimes I won&#8217;t know the answers to all your questions :)</li>
</ul>
<p>If you are interested in helping, pop in #sk-dev on irc.esper.net and idle. You may want to get in touch with zml2008 or sk89q to get you started. Please note that you need to be somewhat experienced with Java (or rather programming in general) as I tend to be a pretty strong advocate of <a href="http://en.wikipedia.org/wiki/Abstraction">abstraction</a>. On the other hand, I wrote WorldEdit when my experience with Java was pretty minimal, so you can do it too (just read up on generics and annotations).</p>
<p>We&#8217;re hopefully going to support these projects for as long as possible because I know a lot of people depend on it. Thanks to everyone for supporting us! If you are ever looking for a release and not finding one, you can check out <a href="http://build.sk89q.com">build.sk89q.com</a> for developer builds.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sk89q.com/2011/12/state-of-worldedit-and-friends/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Brand new ICs on the Minecraft server</title>
		<link>http://www.sk89q.com/2011/11/brand-new-ics-on-the-minecraft-server/</link>
		<comments>http://www.sk89q.com/2011/11/brand-new-ics-on-the-minecraft-server/#comments</comments>
		<pubDate>Sun, 13 Nov 2011 18:28:54 +0000</pubDate>
		<dc:creator>sk89q</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Minecraft]]></category>
		<category><![CDATA[SKCraft]]></category>

		<guid isPermaLink="false">http://www.sk89q.com/?p=1706</guid>
		<description><![CDATA[I added some new integrated circuits to the Minecraft server over the past few days. They work like CraftBook but have a number of new features over CraftBook, a lot of them longstanding ideas that never came to fruition. All &#8230; <a href="http://www.sk89q.com/2011/11/brand-new-ics-on-the-minecraft-server/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I added some new integrated circuits to the Minecraft server over the past few days. They work like CraftBook but have a number of new features over CraftBook, a lot of them longstanding ideas that never came to fruition. All old CraftBook ICs will still work (and for eternity if possible)!</p>
<p>To make an IC, use &#8221; =icname&#8221; (with the space in front). The ID numbers are no longer used &#8212; just type the IC name. The text goes on the first line of the wall sign.</p>
<div id="attachment_1707" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.sk89q.com/content/2011/11/2011-11-13_09.59.01.png"><img src="http://www.sk89q.com/content/2011/11/2011-11-13_09.59.01-300x223.png" alt="" title="Creating the IC" width="300" height="223" class="size-medium wp-image-1707" /></a><p class="wp-caption-text">Creating the IC</p></div>
<p>Some helpful information is shown once you&#8217;ve created the IC:</p>
<div id="attachment_1708" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.sk89q.com/content/2011/11/2011-11-13_09.59.12.png"><img src="http://www.sk89q.com/content/2011/11/2011-11-13_09.59.12-300x223.png" alt="" title="After the IC is created" width="300" height="223" class="size-medium wp-image-1708" /></a><p class="wp-caption-text">After the IC is created</p></div>
<p>Setup is like CraftBook. You have your families (SISO, 3ISO, etc.).</p>
<div id="attachment_1709" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.sk89q.com/content/2011/11/2011-11-13_10.00.08.png"><img src="http://www.sk89q.com/content/2011/11/2011-11-13_10.00.08-300x223.png" alt="" title="Setup is like CraftBook" width="300" height="223" class="size-medium wp-image-1709" /></a><p class="wp-caption-text">Setup is like CraftBook</p></div>
<p>However, unlike CraftBook, diodes are detected properly.</p>
<div id="attachment_1710" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.sk89q.com/content/2011/11/2011-11-13_10.00.38.png"><img src="http://www.sk89q.com/content/2011/11/2011-11-13_10.00.38-300x223.png" alt="" title="Unlike CraftBook, diodes work properly" width="300" height="223" class="size-medium wp-image-1710" /></a><p class="wp-caption-text">Unlike CraftBook, diodes work properly</p></div>
<p>Sneaking and right clicking the sign provides debugging information:</p>
<div id="attachment_1711" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.sk89q.com/content/2011/11/2011-11-13_10.01.57.png"><img src="http://www.sk89q.com/content/2011/11/2011-11-13_10.01.57-300x223.png" alt="" title="ICs can have extra debugging information shown when clicked" width="300" height="223" class="size-medium wp-image-1711" /></a><p class="wp-caption-text">ICs can have extra debugging information shown when clicked</p></div>
<p>Access the in-game documentation with: <strong>/reic list</strong>, although you can also right click signs (while not sneaking) to see help.</p>
<div id="attachment_1712" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.sk89q.com/content/2011/11/2011-11-13_10.02.31.png"><img src="http://www.sk89q.com/content/2011/11/2011-11-13_10.02.31-300x223.png" alt="" title="In-game documentation means you don&#039;t have to remember it all" width="300" height="223" class="size-medium wp-image-1712" /></a><p class="wp-caption-text">In-game documentation means you don't have to remember it all</p></div>
<p>For everyone else, you can <a href="https://github.com/sk89q/reic">find the code on GitHub</a>. It&#8217;s not standalone yet so you can&#8217;t use it, but <a href="https://github.com/nevercast">NeverCast</a> is working on fixing that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sk89q.com/2011/11/brand-new-ics-on-the-minecraft-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How I stay sane while updating my Minecraft server</title>
		<link>http://www.sk89q.com/2011/10/how-i-stay-sane-while-updating-my-minecraft-server/</link>
		<comments>http://www.sk89q.com/2011/10/how-i-stay-sane-while-updating-my-minecraft-server/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 21:02:49 +0000</pubDate>
		<dc:creator>sk89q</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Bukkit]]></category>
		<category><![CDATA[Minecraft]]></category>
		<category><![CDATA[Rebar]]></category>
		<category><![CDATA[SKCraft]]></category>

		<guid isPermaLink="false">http://www.sk89q.com/?p=1659</guid>
		<description><![CDATA[For my Minecraft server, I often find myself wanting to add a little feature here and there, additions that don&#8217;t yet exist or are too minor to bother with searching for a pre-existing plugin. For covering the &#8220;last of the mile&#8221; &#8230; <a href="http://www.sk89q.com/2011/10/how-i-stay-sane-while-updating-my-minecraft-server/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For my Minecraft server, I often find myself wanting to add a little feature here and there, additions that don&#8217;t yet exist or are too minor to bother with searching for a pre-existing plugin. For covering the &#8220;last of the mile&#8221; and sometimes a little more, I use a plugin specific for my server, but because it&#8217;s a little of &#8220;everything,&#8221; I can&#8217;t write it like one big plugin &#8212; that makes it difficult for me to maintain it. On the other hand, I don&#8217;t want to create a new Bukkit plugin for every little feature because that requires a lot of work to maintain all of them. To fix this problem, my plugin, Rebar (previously gone by with other names), is a little framework within itself that it helps me add new things very quickly, with little overhead and little effort. This is similar to some Python plugin frameworks that I wrote a long time ago, except Python provides you with much more freedom ;)</p>
<h2>Components</h2>
<p>Pretty much everything is a component. Components know how to initialize themselves as well as shutdown their tasks. They are very light &#8212; most components are confined to only one class. When components are loaded, &#8220;loader helpers&#8221; help initialize the component by automatically linking resources within the class (loader helpers themselves are extensible!). For example, say I want to store sessions in this one component &#8212; I want to remember where the last person performed a command, but I only want to keep the data while the user is still logged in. There&#8217;s a component for that, and selecting it for this new component is easy with the @InjectComponent helper:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MySessionTest <span style="color: #000000; font-weight: bold;">extends</span> AbstractComponent <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; @InjectComponent <span style="color: #000000; font-weight: bold;">private</span> Sessions sessionsManager<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// ...</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>What if I need to access another plugin?</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> WorldGuardTest <span style="color: #000000; font-weight: bold;">extends</span> AbstractComponent <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; @InjectPlugin<span style="color: #009900;">&#40;</span>WorldGuardPlugin.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> LazyPluginReference<span style="color: #339933;">&lt;</span>WorldGuardPlugin<span style="color: #339933;">&gt;</span> worldguard<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// ...</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Because plugins can possibly be unloaded or be made unavailable any time (as opposed to components, which are not outside the world of Rebar), they are accessed through a proxy LazyPluginReference class. We have to specify the class of the plugin in the annotation, sadly, because generics are only known at compile time in Java.</p>
<p>Enabling components is a matter of placing a line in a configuration file. I run two separate servers, a survival and a creative, so often I do not use the same components on both servers.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">components:<br />
- com.sk89q.skcraft.users.UserManager<br />
- com.sk89q.skcraft.FancyName<br />
- com.sk89q.skcraft.GameMechanics<br />
- com.sk89q.skcraft.BetterVehicles<br />
# ...</div></div>
<h2>Events</h2>
<p>Handling events is the bread and butter of most of the features. Those familiar with the event API in Bukkit know that it&#8217;s not a particularly spectacular piece of code though. There&#8217;s a lot of code duplicated <em>everywhere</em>, it takes a lot of code to even initiate an event, registering an event handler is a pain, and custom events are a complete joke. I get around some of the issues by using annotations:</p>
<p><code>@BukkitEvent(type = Event.Type.BLOCK_BREAK)</code></p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BuildProtection <span style="color: #000000; font-weight: bold;">extends</span> AbstractComponent <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> postInitialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Rebar.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">registerEvents</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> BlockListener<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// ...</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">class</span> BlockListener <span style="color: #000000; font-weight: bold;">extends</span> org.<span style="color: #006633;">bukkit</span>.<span style="color: #006633;">event</span>.<span style="color: #006633;">block</span>.<span style="color: #006633;">BlockListener</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @BukkitEvent<span style="color: #009900;">&#40;</span>type <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aevent+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Event</span></a>.<span style="color: #006633;">Type</span>.<span style="color: #006633;">BLOCK_BREAK</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onBlockBreak<span style="color: #009900;">&#40;</span>BlockBreakEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Process event</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Priorities are optionally specified, but it defaults to &#8220;normal.&#8221;</p>
<h2>Custom Events</h2>
<p>Rebar has its own improved and fast event system for custom events, and registering event handlers is even the same as the code above. (Java reflection is not at all used except during initialization.) Below is an example of a custom event to check whether a block can be modified. Because the build protection event dispatcher is only active if the build protection component is running, the requirement has to be stated (that&#8217;s noted by the @RequiresComponent annotation).</p>
<p><code>@RegisteredEvent(type = BlockProtectedEvent.class)</code></p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">@RequiresComponent<span style="color: #009900;">&#40;</span>BuildProtection.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ExampleProtectionTest <span style="color: #000000; font-weight: bold;">extends</span> AbstractComponent <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> postInitialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Rebar.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">registerEvents</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ProtectionListener<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// ...</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ProtectionListener <span style="color: #000000; font-weight: bold;">extends</span> com.<span style="color: #006633;">sk89q</span>.<span style="color: #006633;">rebar</span>.<span style="color: #006633;">components</span>.<span style="color: #006633;">ProtectionListener</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @RegisteredEvent<span style="color: #009900;">&#40;</span>type <span style="color: #339933;">=</span> BlockProtectedEvent.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onEvent<span style="color: #009900;">&#40;</span>BlockProtectedEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Process code here</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Creating an event is easy:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BlockProtectedEvent <span style="color: #000000; font-weight: bold;">extends</span> AbstractEvent<span style="color: #339933;">&lt;</span>ProtectionListener<span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Code for the event</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> call<span style="color: #009900;">&#40;</span>ProtectionListener listener<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; listener.<span style="color: #006633;">onEvent</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>By design, a listener can contain multiple events.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> ProtectionListener <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onEvent<span style="color: #009900;">&#40;</span>BlockProtectedEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onEvent<span style="color: #009900;">&#40;</span>GuestProtectedEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Event priorities are integers, with certain default ones set at certain numbers. This allows for some leeway when setting priority.</p>
<h2>Making Events Work</h2>
<p>Often times multiple events need to be consolidated into one, or made more specific. For example, say you wanted to protect all signs with the text &#8220;[Lock]&#8221; on it from being destroyed. If you had to copy the same protection code to each component, you&#8217;d find it to be a nightmare! Instead in my plugin, the build protection is handled by a <em>event</em> that is raised by a build protection component. It allows other components to not at all worry about how to protect blocks, just which blocks to protect. It handles dependent blocks as well (e.g. wall signs on a back wall) all in one place.</p>
<p>I pass off a BlockProtectedEvent and whichever component feels like protecting another block can easily handle the event. The code for the actual component that fires the event is shown partially below:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BuildProtection <span style="color: #000000; font-weight: bold;">extends</span> AbstractComponent <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> postInitialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Rebar rebar <span style="color: #339933;">=</span> Rebar.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; rebar.<span style="color: #006633;">registerEvents</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> BlockListener<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; rebar.<span style="color: #006633;">registerEvents</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> EntityListener<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// ...</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">boolean</span> canModifyAttached<span style="color: #009900;">&#40;</span>Block from, BlockFace face, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aentity+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Entity</span></a> entity<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// This checks to see if you can modify attached blocks (signs on wall, etc.)</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> canModify<span style="color: #009900;">&#40;</span>Block block, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aentity+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Entity</span></a> entity<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>Rebar.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getEventManager</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">dispatch</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">new</span> BlockProtectedEvent<span style="color: #009900;">&#40;</span>block, entity<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isCancelled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>block.<span style="color: #006633;">getType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> Material.<span style="color: #006633;">AIR</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>canModifyAttached<span style="color: #009900;">&#40;</span>block, BlockFace.<span style="color: #006633;">NORTH</span>, entity<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>canModifyAttached<span style="color: #009900;">&#40;</span>block, BlockFace.<span style="color: #006633;">WEST</span>, entity<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>canModifyAttached<span style="color: #009900;">&#40;</span>block, BlockFace.<span style="color: #006633;">EAST</span>, entity<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>canModifyAttached<span style="color: #009900;">&#40;</span>block, BlockFace.<span style="color: #006633;">SOUTH</span>, entity<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>canModifyAttached<span style="color: #009900;">&#40;</span>block, BlockFace.<span style="color: #006633;">UP</span>, entity<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> canModify<span style="color: #009900;">&#40;</span>Block block<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> canModify<span style="color: #009900;">&#40;</span>block, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">class</span> EntityListener <span style="color: #000000; font-weight: bold;">extends</span> org.<span style="color: #006633;">bukkit</span>.<span style="color: #006633;">event</span>.<span style="color: #006633;">entity</span>.<span style="color: #006633;">EntityListener</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; &nbsp; &nbsp; @BukkitEvent<span style="color: #009900;">&#40;</span>type <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aevent+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Event</span></a>.<span style="color: #006633;">Type</span>.<span style="color: #006633;">ENTITY_EXPLODE</span>, priority <span style="color: #339933;">=</span> Priority.<span style="color: #006633;">Lowest</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onEntityExplode<span style="color: #009900;">&#40;</span>EntityExplodeEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">isCancelled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Block block <span style="color: #339933;">:</span> event.<span style="color: #006633;">blockList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>canModify<span style="color: #009900;">&#40;</span>block, event.<span style="color: #006633;">getEntity</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span style="color: #006633;">setCancelled</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; &nbsp; &nbsp; @BukkitEvent<span style="color: #009900;">&#40;</span>type <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aevent+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Event</span></a>.<span style="color: #006633;">Type</span>.<span style="color: #006633;">ENDERMAN_PICKUP</span>, priority <span style="color: #339933;">=</span> Priority.<span style="color: #006633;">Lowest</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onEndermanPickup<span style="color: #009900;">&#40;</span>EndermanPickupEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">isCancelled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>canModify<span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">getBlock</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, event.<span style="color: #006633;">getEntity</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span style="color: #006633;">setCancelled</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// ...</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// ...</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<h2>Services</h2>
<p>Services actually exist in Bukkit (I wrote it), but not many people are familiar with it, and the code is a bit generics-happy, so it tends to scare off people. However, in Rebar, I use them in order to provide a way to plug and play different parts of code and provide a little interop. </p>
<p>An example of a wallet service is:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> WalletService <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">void</span> beginTransaction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">void</span> commitTransaction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; Wallet getWallet<span style="color: #009900;">&#40;</span>OfflinePlayer player<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">void</span> saveWallet<span style="color: #009900;">&#40;</span>OfflinePlayer player<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>The transaction methods are to ensure the possibility of atomic transactions when dealing with a player&#8217;s currency, which allows threading within the plugin as well as access from outside the server entirely.</p>
<p>Registering and working with services is pretty much the code I wrote in Bukkit, so I won&#8217;t go deeply into that. However, naturally, I have a loader helper for that:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> WalletTest <span style="color: #000000; font-weight: bold;">extends</span> AbstractComponent <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; @InjectService<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> WalletService wallets<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// ...</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Now I can support currency in any component and I don&#8217;t have to care as to what is providing the implementation!</p>
<h2>Commands</h2>
<p>Commands are handled by the command handling code inside of WorldEdit. It features boolean flags as well as flags of other data types (many thanks to TomyLobo), allowing you to do some pretty cool things. Annotations are also used heavily here, with an emphasis on as a little code needed as possible.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> UserManagerCommands <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// ...</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; @Command<span style="color: #009900;">&#40;</span>aliases <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">&quot;update-users&quot;</span> <span style="color: #009900;">&#125;</span>, desc <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Reload the list of users and their permissions&quot;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; @CommandPermissions<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">&quot;skcraft.reload-users&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> reloadUsers<span style="color: #009900;">&#40;</span>CommandContext context, CommandSender sender<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; userManager.<span style="color: #006633;">reload</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ChatUtil.<span style="color: #006633;">msg</span><span style="color: #009900;">&#40;</span>sender, ChatColor.<span style="color: #006633;">YELLOW</span>, <span style="color: #0000ff;">&quot;Users and groups have been reloaded.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>It was this instead of creating a class for each component. I purposely chose not to do that instead back then because WorldEdit had over 100 commands, which would have meant over 100 classes (something I didn&#8217;t want to deal with).</p>
<h2>Permissions</h2>
<p>Permissions are actually handled by <a href="http://wiki.sk89q.com/wiki/WEPIF">WEPIF</a>, which was improved with thanks from zml2008. WEPIF abstracts a lot of the frustrating parts of handling permissions, especially for users of Bukkit&#8217;s convoluted permissions system.</p>
<h2>Example</h2>
<p>Here&#8217;s an example of a component that changes your name color to a random one. I don&#8217;t designate group colors on my server &#8212; everyone gets a random name color so it&#8217;s easy to read chat and it&#8217;s not cluttered.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> FancyName <span style="color: #000000; font-weight: bold;">extends</span> AbstractComponent <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Arandom+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Random</span></a> random <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Arandom+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Random</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> ChatColor<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> NAME_COLORS <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ChatColor<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ChatColor.<span style="color: #006633;">GOLD</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; ChatColor.<span style="color: #006633;">GRAY</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; ChatColor.<span style="color: #006633;">BLUE</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; ChatColor.<span style="color: #006633;">GREEN</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; ChatColor.<span style="color: #006633;">AQUA</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; ChatColor.<span style="color: #006633;">RED</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; ChatColor.<span style="color: #006633;">LIGHT_PURPLE</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; ChatColor.<span style="color: #006633;">YELLOW</span>,<br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> postInitialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Rebar.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">registerEvents</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> PlayerListener<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Player player <span style="color: #339933;">:</span> Rebar.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getServer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getOnlinePlayers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fancifyPlayer<span style="color: #009900;">&#40;</span>player<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> shutdown<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> fancifyPlayer<span style="color: #009900;">&#40;</span>Player player<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; player.<span style="color: #006633;">setDisplayName</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NAME_COLORS<span style="color: #009900;">&#91;</span>random.<span style="color: #006633;">nextInt</span><span style="color: #009900;">&#40;</span>NAME_COLORS.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">+</span> player.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> ChatColor.<span style="color: #006633;">WHITE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> PlayerListener <span style="color: #000000; font-weight: bold;">extends</span> org.<span style="color: #006633;">bukkit</span>.<span style="color: #006633;">event</span>.<span style="color: #006633;">player</span>.<span style="color: #006633;">PlayerListener</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; &nbsp; &nbsp; @BukkitEvent<span style="color: #009900;">&#40;</span>type <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aevent+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Event</span></a>.<span style="color: #006633;">Type</span>.<span style="color: #006633;">PLAYER_JOIN</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onPlayerJoin<span style="color: #009900;">&#40;</span>PlayerJoinEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fancifyPlayer<span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">getPlayer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<h2>Source</h2>
<p>Anyway, I actually hope to release some of this framework in the matter of a few weeks, so be on the look out! I&#8217;ve been slowly cleaning up things, and figuring out how to make some things less hardcoded (there are some limitations on Bukkit I&#8217;ll have to either fix or work around). You can <a href="https://github.com/sk89q">watch me on GitHub</a> if you want. If this article was mostly foreign to you, then you should read up on <a href="http://download.oracle.com/javase/tutorial/java/javaOO/annotations.html">Java annotations</a> and <a href="http://download.oracle.com/javase/tutorial/java/generics/index.html">generics</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sk89q.com/2011/10/how-i-stay-sane-while-updating-my-minecraft-server/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Economy in a game like Minecraft</title>
		<link>http://www.sk89q.com/2011/10/economy-in-a-game-like-minecraft/</link>
		<comments>http://www.sk89q.com/2011/10/economy-in-a-game-like-minecraft/#comments</comments>
		<pubDate>Sat, 01 Oct 2011 18:35:11 +0000</pubDate>
		<dc:creator>sk89q</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[economy]]></category>
		<category><![CDATA[Minecraft]]></category>

		<guid isPermaLink="false">http://www.sk89q.com/?p=1632</guid>
		<description><![CDATA[The economy of a Minecraft world is pretty fascinating because everything about the world is fabricated players using resources mined from the same world, a feature not present in most games. There are no swords that enter the marketplace through &#8230; <a href="http://www.sk89q.com/2011/10/economy-in-a-game-like-minecraft/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The economy of a Minecraft world is pretty fascinating because everything about the world is fabricated players using resources mined from the same world, a feature not present in most games. There are no swords that enter the marketplace through some simulated marketplace, and there isn’t a strong need for such a thing either. Recently, I wrote about an hour’s worth of code for my small Minecraft server in order to allow players to setup shops from chests they owned. They’d place their items to sell in the chest and put a sign above declaring what they’d give for what they’d take. It made trading much easier and an entire trading district blossomed overnight (literally). Because each chest store could only sell up to two items (because two signs can fit above a double-width chest) and each chest took up physical space, it meant that there was a need for players to construct buildings (perhaps large in some cases) for their store. As there was <strong>not</strong> a “global” market that you could access from any in-game location, that meant that factors that you’d find in the real world such as location had an effect (it’s potentially profitable to start up a series of remote outposts to sell food and arrows). The area of the town at spawn doubled that day.</p>
<div id="attachment_1640" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.sk89q.com/content/2011/10/2011-10-01_11.54.45.png"><img src="http://www.sk89q.com/content/2011/10/2011-10-01_11.54.45-300x168.png" alt="" title="A shop with in stock and out of stock chests" width="300" height="168" class="size-medium wp-image-1640" /></a><p class="wp-caption-text">A shop with in stock and out of stock chests</p></div>
<p>But there was no currency. I deliberately avoided establishing currency because a number of friends were adamant about not having one, but their disdain for currency isn’t unreasonable. I’ve been around and how “economy” works on many Minecraft servers (as well as other in other games) is through a combination of periodical welfare payments, game-powered shops with rates set by the game, and in the case of roleplay servers, virtual employment. In the case of the shops, rates for multiple items were set by the server owner manually or through a list of item rarities (generated by finding the distribution of materials in a given world). I find the latter particularly farcical – value is very much <em>not</em> simply determined by rarity. On more than a few servers, it seemed as if <em>everyone’s</em> business was to farm sugar cane en-masse – and it <em>worked</em>, because sugar cane as bought by the server’s shops at a fixed price. I didn’t want that and I got the feeling that my server’s players didn’t want it either.</p>
<p>There was, of course, another choice – have algorithms dictate the exchange rate based on the volume of trades by players. A player had suggested this as well, but that meant that I’d have to dedicate time to researching and tweaking the algorithm (although the player said he had some experience with this), plus it’d be open to market manipulation due to the small volume of trades that happens when you only have a smaller server. If I made an error, it could significantly tip the balance the wrong way and I’d have to deal with the aftermath (and after taking a one or two week leave, as it tends to happen). Instead of all of this, I was anticipating that a currency might develop on its own (commodity money). Two different groups of people did setup currency exchanges, but their exchange ratios were not properly fair. One diamond-for-gold exchange ran out of diamond in an hour because the diamond was too cheap for the amount of gold. Beyond that, there wasn’t enough trust to be had for the exchanges and they didn’t catch on.</p>
<p>While bartering has been enjoyable, trading can be challenging because you may not have the item the seller seeks, and you’re also encouraged to delay trade until the real necessity arises. With bartering, some items are impossible to sell because the effort involved in trading for them (and calculating the right barter ratio) is significantly greater than crafting the item themselves, even if prices are as low as you can go. That leaves us with need for an official currency, and probably one that’s driven by money a la a credit card (to lubricate the process even further). We spent a bit of time discussing what to do about that, and I had considered giving everyone a set amount of credits (perhaps 10,000 per head) – something that I can do because it’s a computer game – but I think the currency would never come into use nor stabilize. What we probably will do is setup a certain number of <strong>one</strong> resource for a certain amount of money at a game-controlled exchange. It’d be a fixed currency backed by gold or something, mostly likely to be something like iron ingots or gold ingots. It seems no one wants fractions either (although decimals is merely a representation), so we’re thinking about having the exchange rate at a large whole number such as $32 for an iron ingot. It has to be high enough to make it possible to trade lower-value items – a great analogy for that, as a friend said, is if the lowest currency denomination suddenly had to be $20 USD, you could no longer trade a large number of objects unless it was in excessive bulk quantities. Another friend suggested using factors of $8, because most items have a stack size that’s 64 or a multiple of 8 – that’s an interesting idea. The question also arises whether we&#8217;d want a floating exchange rate in the future too.</p>
<div id="attachment_1649" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.sk89q.com/content/2011/10/2011-10-01_12.04.28.png"><img src="http://www.sk89q.com/content/2011/10/2011-10-01_12.04.28-300x168.png" alt="" title="One of the currency exchanges" width="300" height="168" class="size-medium wp-image-1649" /></a><p class="wp-caption-text">One of the currency exchanges</p></div>
<div id="attachment_1644" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.sk89q.com/content/2011/10/2011-10-01_11.53.56.png"><img src="http://www.sk89q.com/content/2011/10/2011-10-01_11.53.56-300x168.png" alt="" title="Someone abusing the in-game &quot;MapPad&#039;s&quot; image board to advertise" width="300" height="168" class="size-medium wp-image-1644" /></a><p class="wp-caption-text">Someone abusing the in-game 'tablet' image board app to advertise</p></div>
<p>Overall it’s been pretty fun trying to stimulate trade and there has been many analogies to history and real life. Because new versions of Minecraft also continue to come out, the value of items can change. Gold’s value may change in v1.9 because of new items added, and one could currently move money into or out of gold ingots in anticipation, depending on how they expect the value of gold to trend. There’s also been some clever people really working the market (perhaps quite in an evil manner), by, for example, buying out a shop and reselling  with higher markup. Some of the guys on there are younger too, and some of them have really sharpened lately.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sk89q.com/2011/10/economy-in-a-game-like-minecraft/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Login under someone else’s Minecraft account</title>
		<link>http://www.sk89q.com/2011/09/minecraft-name-spoofing-exploit/</link>
		<comments>http://www.sk89q.com/2011/09/minecraft-name-spoofing-exploit/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 23:01:18 +0000</pubDate>
		<dc:creator>sk89q</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[exploit]]></category>
		<category><![CDATA[Minecraft]]></category>
		<category><![CDATA[name spoof]]></category>

		<guid isPermaLink="false">http://www.sk89q.com/?p=1615</guid>
		<description><![CDATA[There&#8217;s this interesting exploit in Minecraft that lets you login under someone&#8217;s name without ever needing to know the person&#8217;s password. All the attacker needs to do is get you to join his/her server once. This client-side fix patches your game so that &#8230; <a href="http://www.sk89q.com/2011/09/minecraft-name-spoofing-exploit/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s this interesting exploit in Minecraft that lets you <strong>login under someone&#8217;s name <em>without</em> ever needing to know the person&#8217;s password</strong>. All the attacker needs to do is <strong>get you to join his/her server once</strong>. This client-side fix patches your game so that it won&#8217;t let your server tell you to authenticate against a &#8220;blank&#8221; server ID. Lymia and I reported it to Mojang a while ago, and while Jeb just put a fix in 1.8, there&#8217;s a mistake with the fix. You can download a ZIP to install it like any other mod (put the files into minecraft.jar), or Windows users can use the setup program to automatically install the fix:</p>
<ul>
<li><a href="http://www.sk89q.com/content/2011/09/minecraft-spoof-fix-1.8.1.zip">Name spoof fix for 1.8.1 (ZIP)</a></li>
<li><a href="http://www.sk89q.com/content/2011/09/minecraft-spoof-fix-1.8.1.exe">Name spoof fix installer for 1.8.1 (Windows installer)</a></li>
</ul>
<p>A server-side fix has recently made it into a Bukkit, but your account can still be abused to join unpatched servers. This client-side patch prevents <em>any</em> server from exploiting your account. To understand how the exploit works, here&#8217;s a review of how Minecraft would authenticate for &#8220;Frank&#8221;:</p>
<p><span style="font-family: Georgia, 'Bitstream Charter', serif; line-height: 24px;"> </span></p>
<ol>
<li>Client-&gt;Server: Your game tells the server that it wants to join as &#8220;Frank&#8221;</li>
<li>Server-&gt;Client: The server responds with the ID &#8220;afe93b31c&#8221; (randomized)</li>
<li>Your game tells Minecraft.net that &#8220;Frank&#8221; is joining &#8220;afe93b31c&#8221;</li>
<li>Client-&gt;Server: The client tells the server that it&#8217;s ready</li>
<li>The server asks Minecraft.net to see if &#8220;Frank&#8221; has joined &#8220;afe93b31c&#8221; (if not, then the real Frank never joined the server)</li>
</ol>
<p>Here&#8217;s how the exploit works: You get your victim to join your custom server that sends a <em>blank</em> ID. Frank&#8217;s game tells Minecraft.net that Frank is joining &#8220;&#8221; (a blank ID). Frank joins your server, plays around, and has no clue about what&#8217;s going on. You then join Frank&#8217;s server where Frank is an administrator, but you immediately skip to step #4: You tell the server that you already did step #3 and you get in. Why does this work? On the server, the server ID is <em>blank if you never complete step 1</em>, so in step #5, Frank&#8217;s server asks Minecraft.net if &#8220;Frank&#8221; has joined &#8220;&#8221;, which Frank did earlier but on <em>your server</em>.</p>
<p>From a more technical perspective, the hacked client never sends the initial <a href="http://mc.kev009.com/Protocol#Handshake_.280x02.29">handshake packet</a>. The server ID starts out as a blank string, and it&#8217;s only initialized if you send the handshake packet. If you skip the handshake packet and just jump to the <a href="http://mc.kev009.com/Protocol#Login_Request_.280x01.29">login packet</a>, then the server ID stays as a blank string. Before 1.8, your client would freely accept a blank server ID. 1.8 prevents a server from giving you a blank server ID, but Lymia noticed that the game doesn&#8217;t URL-escape the server ID, so a server ID of &#8220;&amp;&#8221; is essentially blank. The patch makes the routine URL-escapes the ID.</p>
<p>Addendum: Someone mentioned a &#8220;man-in-the-middle&#8221; attack that allows for name spoofing, but that&#8217;s a different issue that can only be fixed with significant changes to how Minecraft handles authentication. (A MITM is also more difficult to pull off well.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sk89q.com/2011/09/minecraft-name-spoofing-exploit/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>“Embedding disabled” no more for PlayX</title>
		<link>http://www.sk89q.com/2011/08/embedding-disabled-no-more-for-playx/</link>
		<comments>http://www.sk89q.com/2011/08/embedding-disabled-no-more-for-playx/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 10:06:07 +0000</pubDate>
		<dc:creator>sk89q</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[PlayX]]></category>
		<category><![CDATA[YouTube]]></category>

		<guid isPermaLink="false">http://www.sk89q.com/?p=1605</guid>
		<description><![CDATA[If you&#8217;ve been using PlayX for the past year, you know how often you have come across &#8220;Embedding disabled by request.&#8221; The good news is that 2.6 swaps the JW player for playing YouTube videos with YouTube&#8217;s own player, allowing &#8230; <a href="http://www.sk89q.com/2011/08/embedding-disabled-no-more-for-playx/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve been using PlayX for the past year, you know how often you have come across &#8220;Embedding disabled by request.&#8221; The good news is that 2.6 swaps the JW player for playing YouTube videos with YouTube&#8217;s own player, allowing you to play <em>all YouTube videos</em>, regardless if the owner would like to block the video from being embedded or not. Cross-domain security isn&#8217;t a concern for PlayX, so I was able to pull off some JavaScript trickery to reuse YouTube&#8217;s player and still have all the advantages of the original player. You can still adjust the player volume, seek to a certain point, and still view the data displayed on the radio display. The change also means that annotations will show for videos, for better or worse. I&#8217;m not sure about advertisements though — those may show up but I didn&#8217;t encounter them during testing. The only downside to the change was that there&#8217;s a higher chance now of the mechanism fatally breaking at some point in the future, but that might be a while from now.</p>
<p>If you are curious as to how it&#8217;s done, you can check the Git repository for the commit. I caution you that the code is pretty dirty — my proof of concept code tends to be that way. I dabbled in the fix a few months back, and I forgot its proof-of-concept status when I dropped it into PlayX the other day.</p>
<p>Another cool change is the addition of the &#8220;PlayX Navigator.&#8221; It allows you to browse video sites (presently only YouTube and <a href="http://www.reddit.com/r/videos">/r/videos</a>) to play them in PlayX. If you click on a YouTube URL, it will be redirected to PlayX instead, allowing you to use YouTube.com&#8217;s search page like normal. The browser can also visit any URL, and you can force a link to open a video in PlayX by using either of the following URIs:</p>
<ul>
<li>playx://open/&lt;uri&gt;</li>
<li>playx://open-provider/&lt;provider&gt;/&lt;id&gt;</li>
</ul>
<p>Find PlayX 2.6 in the usual repositories.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sk89q.com/2011/08/embedding-disabled-no-more-for-playx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Looping jQuery animations indefinitely</title>
		<link>http://www.sk89q.com/2011/07/looping-jquery-animations-indefinately/</link>
		<comments>http://www.sk89q.com/2011/07/looping-jquery-animations-indefinately/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 05:44:38 +0000</pubDate>
		<dc:creator>sk89q</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.sk89q.com/?p=1598</guid>
		<description><![CDATA[A friend asked how to loop a jQuery animation after he had attempted to queue the animations using an unending while loop. That doesn&#8217;t work as JavaScript is not threaded and it&#8217;d only end up blocking forever, creating an ever &#8230; <a href="http://www.sk89q.com/2011/07/looping-jquery-animations-indefinately/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A friend asked how to loop a jQuery animation after he had attempted to queue the animations using an unending while loop. That doesn&#8217;t work as JavaScript is not threaded and it&#8217;d only end up blocking forever, creating an ever growing queue of animations that would never be run. Two better ways to loop an animation are (1) to use a timer on an interval that re-queues the animations, or (2) to use a callback on the last animation in the sequence to re-queue the animations. The first solution isn&#8217;t the same as the latter, as the latter will fire immediately after the first run finishes.</p>
<p>However, I suggested that he queue a function as if it was an animation itself, and use that to fire off the animations each run. That is illustrated below.</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#image&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">queue</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>next<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1000</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">delay</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeOut</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">queue</span><span style="color: #009900;">&#40;</span>arguments.<span style="color: #660066;">callee</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; next<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>The snippet is simple &mdash;</p>
<ol>
<li>The list of animations is fired. These will be queued to be executed.</li>
<li>Then the anonymous function itself (arguments.callee refers to the function being executed) is re-queued.</li>
<li>next() progresses the queue. <code>next</code> is passed in as an argument.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.sk89q.com/2011/07/looping-jquery-animations-indefinately/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spotify now open to the US; it’s amazing</title>
		<link>http://www.sk89q.com/2011/07/spotify-now-open-to-the-us-its-amazing/</link>
		<comments>http://www.sk89q.com/2011/07/spotify-now-open-to-the-us-its-amazing/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 04:37:46 +0000</pubDate>
		<dc:creator>sk89q</dc:creator>
				<category><![CDATA[Music]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.sk89q.com/?p=1580</guid>
		<description><![CDATA[Now that Spotify is available in the US and I&#8217;ve gotten to use it, it&#8217;s amazing. It lets you stream any song from its growing music library on demand and instantly. Search is great, the interface is snappy and nice &#8230; <a href="http://www.sk89q.com/2011/07/spotify-now-open-to-the-us-its-amazing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Now that Spotify is available in the US and I&#8217;ve gotten to use it, it&#8217;s <strong>amazing</strong>. It lets you stream any song from its growing music library on demand and <strong>instantly</strong>. Search is great, the interface is snappy and nice looking. It is <em>social</em> &#8212; right now I am collaborating on a playlist with another friend, but you can make read-only playlists that others can subscribe to. The &#8220;unlimited&#8221; account costs $5/month, while premium, which gives extras such as higher bitrate streams and offline play, is $10/month. Spotify has been available for parts of Europe for sometime now &#8212; the company is a Swedish one.</p>
<div style="text-align: center;"><a href="http://www.sk89q.com/content/2011/07/spotify.jpg"><img class="size-medium wp-image-1581" title="Spotify Interface" src="http://www.sk89q.com/content/2011/07/spotify-300x213.jpg" alt="" width="300" height="213" /></a></div>
<p>The nice things about Spotify are:</p>
<ul>
<li>Songs load very quickly. Overall, just click a song or anything and it will be playing right away &#8212; no wait.</li>
<li>The program is <em>fast and looks good</em>. This seems to be a rarity these days.</li>
<li>The music selection is decent. I haven&#8217;t found some more obscure artists, but I&#8217;m satisfied.</li>
<li>The social elements are decent. As I mentioned, you can make playlists, including collaborative ones. A great feature is that you can send a song to a friend &#8212; just drag the song to the friend and it&#8217;ll show in his or her Spotify &#8220;inbox.&#8221;</li>
</ul>
<p>Does it compare to <a href="http://www.pandora.com/">Pandora</a>? No, not really. Pandora doesn&#8217;t let you play songs on demand, but it does have a great music discovery service &#8212; one where you can just sit back and mind your own thing as it chooses songs for you. Spotify has &#8220;similar artists,&#8221; but that&#8217;s about the end of its music discovery service. There are some user-made tools for music discovery with Spotify, but they use Last.fm&#8217;s database, which is based on user contribution and not so much computer algorithms, so it&#8217;s not as &#8220;accurate&#8221; as Pandora. (On a related note, there&#8217;s <a href="http://www.pandora.com/newpandora">a new Pandora interface</a>, finally.) Edit: There&#8217;s a radio service outside the US for Spotify.</p>
<p><a href="http://grooveshark.com/">Grooveshark</a>? Grooveshark&#8217;s qusai-legal database uses uploads from users, so songs are unorganized and the selection is very spotty. Grooveshark also loads songs fairly slowly. The main advantage of Grooveshark is that is more &#8220;free,&#8221; but otherwise Spotify blows Grooveshark out of the water.</p>
<p>What don&#8217;t I like?</p>
<ul>
<li>Everything is excessively tied with Facebook . It doesn&#8217;t seem as if you can even use the social elements unless you&#8217;ve linked your account to Facebook.</li>
<li>The social features could use some work. To add someone to my friends list (not through Facebook), I had to enter <strong>spotify:user:&lt;username&gt;</strong> in the search, which was awkward. (If there&#8217;s a better way, do tell.)</li>
<li>Collaborative playlists can&#8217;t be shared publicly, probably because there&#8217;s no way to change individual editor rights for friends and whatnot. For the social features that are available, they are pretty barebones.</li>
<li>You can&#8217;t actually buy songs to &#8220;own.&#8221; Edit: You can do this outside the US.</li>
</ul>
<p>Hoping to get into Spotify? Right now they&#8217;re <a href="http://www.spotify.com">invite only</a>. If you have an internet presence, you can try getting an invitation through <a href="http://klout.com">Klout.com</a> (whenever it&#8217;s not closed off). No go? You can try <a href="http://gizmodo.com/5821244/how-to-get-spotify-free-without-an-invite">registering an account from a UK internet address</a> (note: this gets you a more restricted European account). If you can&#8217;t get in and don&#8217;t want to wait, you can purchase an <a href="http://www.spotify.com/us/get-spotify/go/unlimited/">unlimited account for $5</a> or <a href="http://www.spotify.com/us/get-spotify/go/premium/">go premium for $10</a> and get in instantly. If you don&#8217;t purchase a subscription, be aware that the &#8220;Free&#8221; version you get will eventually <a href="http://www.pcmag.com/article2/0,2817,2388520,00.asp">become as restricted</a> as the &#8220;Open&#8221; version in Europe.</p>
<p>There&#8217;s only an official Android app, but I haven&#8217;t used it so I can&#8217;t comment on it. My friend has a <a href="http://www.droid-den.com/app-reviews/app-review-spotify">(semi-old) review on Spotify for Android</a> though.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sk89q.com/2011/07/spotify-now-open-to-the-us-its-amazing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 6.696 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-02-04 04:11:03 --><!-- Compression = gzip -->

