<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0">
    <channel>
        <title>Dream Makers' site</title>
        <link>http://www.byond.com/members/DreamMakers</link>
        <description></description>
        <lastBuildDate>Sat, 11 Feb 2012 04:18:20 +0000</lastBuildDate>
        <language>en-us</language>
    
                <item>
            <title>Logrolling and Other Extreme Sports</title>
            <link>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=106449</link>
            <guid>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=106449</guid>
            <pubDate>Fri, 31 Dec 2010 03:09:33 +0000</pubDate>
            
            <comments>http://www.byond.com/members/DreamMakers?command=view_comments&amp;post=106449#comments</comments>
            
            <description>Since people began using BYOND, many games have been plagued with an information problem. Is yours one of them?&lt;br&gt;
&lt;br&gt;
The problem is not a lack of information, but rather too much of it. It arises from an idea that is innocent enough - a game developer just wants to know what's going on in his game. Maybe, for example, to keep track of each battle that happens. So let's say our developer's first idea is to send out a message whenever someone performs an attack.&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob/&lt;span class=&quot;dmkeyword&quot;&gt;verb&lt;/span&gt;/attack(mob/M &lt;span class=&quot;dmkeyword&quot;&gt;as&lt;/span&gt; mob &lt;span class=&quot;dmkeyword&quot;&gt;in&lt;/span&gt; oview(1))&lt;br&gt;            usr &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;You attack &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[M]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;!&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/damage = rand(1,10)&lt;br&gt;            world &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[usr]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; attacks &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[M]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; for &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[damage]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; damage!&amp;quot;&lt;/span&gt;&lt;br&gt;            M.HP -= damage
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
He tests out the code with some friends and is delighted to see that he finds out every time someone is attacked. But soon players start complaining that their chat window is being filled up with useless information about other player's battles! Even the developer realizes that most of the time, he doesn't care about the battle. And annoyingly, whenever he logs out, he loses the whole record!&lt;br&gt;
&lt;br&gt;
Once he realizes that there must be a better solution, our developer - being the diligent and studious programmer that he is - goes straight to the DM Reference. There he finds information on a useful var - &lt;a href=&quot;http://www.byond.com/members/?command=reference&amp;path=world/var/log&quot;&gt;world.log&lt;/a&gt;. With this, he can record a message along with the messages the BYOND may send (like runtime errors) without sending it to the whole world!&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob/&lt;span class=&quot;dmkeyword&quot;&gt;verb&lt;/span&gt;/attack(mob/M &lt;span class=&quot;dmkeyword&quot;&gt;as&lt;/span&gt; mob &lt;span class=&quot;dmkeyword&quot;&gt;in&lt;/span&gt; oview(1))&lt;br&gt;            usr &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;You attack &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[M]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;!&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/damage = rand(1,10)&lt;br&gt;            world.log &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[usr]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; attacks &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[M]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; for &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[damage]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; damage!&amp;quot;&lt;/span&gt;&lt;br&gt;            M.HP -= damage
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
As a bonus, he can set world.log to a file name and have all the messages saved to a file to be read later even if he leaves the game.&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
world.log = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;log.txt&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
This works so well that the developer forgets about it for a while and goes about adding more features to his game. One morning, however, he logs into his game's ad-infested, eyeache-inducing, free PhpBB forums and finds that one player is very upset because another one has been calling him horrid names. The other player denies it. The owner decides that the second player can't be punished because there's no proof he did anything wrong. But he thinks it would be best to keep a chat log to prevent this from happening again. So, he has the game write to the log again, just like he did for the battle log:&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob/&lt;span class=&quot;dmkeyword&quot;&gt;verb&lt;/span&gt;/say(msg &lt;span class=&quot;dmkeyword&quot;&gt;as&lt;/span&gt; text)&lt;br&gt;            world &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[usr]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[msg]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&lt;/span&gt;&lt;br&gt;            world.log &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[usr]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[msg]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
That solves that problem, but soon he hears reports of 10 different admins (nearly a quarter of them!) abusing their powers. To keep track of what they're doing, the developer also writes to the log whenever they perform an administrative action - like banning, kicking, or muting.&lt;br&gt;
&lt;br&gt;
This alls seemed like it would work fine, but eventually he takes a look at the log file. It looks something like this:&lt;br&gt;
&lt;pre style=&quot;height:300px;overflow:auto;&quot;&gt;
&lt;br&gt;someGuy logged in.&lt;br&gt;naruto930284738302392032893820490283 attacked naruto930284738302392032893820490284 for 1 damage!&lt;br&gt;xXYoMamaXx logged in.&lt;br&gt;lulz kicked someGuy.&lt;br&gt;someGuy logged in.&lt;br&gt;naruto930284738302392032893820490284 attacked naruto930284738302392032893820490283 for 2 damage!&lt;br&gt;runtime error: No put usr in proc. Ungh.&lt;br&gt;proc name: GiveSuperPowers (/mob/proc/GiveSuperPowers)&lt;br&gt;  source file: naruto.dm,70&lt;br&gt;  usr: null&lt;br&gt;  src: lulz (/mob)&lt;br&gt;  call stack:&lt;br&gt;lulz (/mob): GiveSuperPowers()&lt;br&gt;lulz kicked someGuy.&lt;br&gt;someGuy logged in.&lt;br&gt;naruto930284738302392032893820490283 attacked naruto930284738302392032893820490284 for 3 damage!&lt;br&gt;someGuy: hey stop it.&lt;br&gt;bleach930284738302392032893820490285 attacked naruto930284738302392032893820490283 for 4 damage!&lt;br&gt;lulz kicked someGuy.&lt;br&gt;SuperGoku9001 logged in.&lt;br&gt;xXYoMamaXx: stop abusing!&lt;br&gt;lulz banned xXYoMamaXx.&lt;br&gt;naruto930284738302392032893820490284 attacked naruto930284738302392032893820490283 for 5 damage!&lt;br&gt;someGuy logged in.&lt;br&gt;someOtherGuy logged in.&lt;br&gt;someOtherGuy attacked SuperGoku9001 for 0 damage!&lt;br&gt;someGuy: hey&lt;br&gt;naruto930284738302392032893820490283 attacked bleach930284738302392032893820490285 for 6 damage!&lt;br&gt;someOtherGuy: hi&lt;br&gt;lulz banned someGuy.&lt;br&gt;SuperGoku9001 attacked someOtherguy for 99999999999999999999999 damage!&lt;br&gt;lulz banned bleach930284738302392032893820490285.&lt;br&gt;naruto930284738302392032893820490284 attacked naruto930284738302392032893820490283 for 7 damage!&lt;br&gt;lulz banned naruto930284738302392032893820490283.&lt;br&gt;runtime error: No put usr in proc. Ungh.&lt;br&gt;proc name: GiveSuperPowers (/mob/proc/GiveSuperPowers)&lt;br&gt;  source file: naruto.dm,70&lt;br&gt;  usr: null&lt;br&gt;  src: SuperGoku9001 (/mob)&lt;br&gt;  call stack:&lt;br&gt;SuperGoku9001 (/mob): GiveSuperPowers()&lt;br&gt;lulz banned someOtherGuy.&lt;br&gt;SuperGoku9001 banned lulz.&lt;br&gt;naruto930284738302392032893820490284 attacked the sheep for 8 damage!&lt;br&gt;SuperGoku9001 unbanned someGuy&lt;br&gt;The cat attacked naruto930284738302392032893820490284 for 9 damage!&lt;br&gt;naruto930284738302392032893820490284: darn it&lt;br&gt;SuperGoku9001 unbanned someOtherGuy.&lt;br&gt;naruto930284738302392032893820490284 logged out.&lt;br&gt;someGuy logged in.&lt;br&gt;SuperGoku9001: wb&lt;br&gt;The sheep attacked someGuy for 10 damage!&lt;br&gt;someOtherGuy logged in.&lt;br&gt;
&lt;/pre&gt;
&lt;br&gt;
You get the idea - it's not the easiest thing to read through. Plus, wouldn't it be nice to know &lt;i&gt;when&lt;/i&gt; all of this happened? The game developer decided that he needed a better way to organize his log in order to be able to find out what happened, when, and who did it to whom.&lt;br&gt;
&lt;h3&gt;An Introduction to n_Log (Finally!)&lt;/h3&gt;
&lt;br&gt;
So by now (assuming you were good and didn't skip the first section of the article) you're probably wondering how to solve this information plague. The answer (or at least &lt;i&gt;one&lt;/i&gt; answer) lies with the &lt;a href=&quot;http://www.byond.com/developer/Nickr5/n_Log&quot;&gt;n_Log&lt;/a&gt; library. What does it do? A few things actually. First it provides procedures that let you easily write to and categorize a log. Things like the date and time are automatically recorded so you don't have to worry about them. Second, by default, it writes your log entries to a structured XML file. If you don't know what that is, don't worry! The library comes with a windows application that will let you view the log - without making your eyes bleed!&lt;br&gt;
&lt;h3&gt;Rolling Logs&lt;/h3&gt;
&lt;br&gt;
The library is pretty simple to use. To log a message, just do this:&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
record(notes = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;Hello, world!&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
Now let's go back to an example of a say verb.&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob/&lt;span class=&quot;dmkeyword&quot;&gt;verb&lt;/span&gt;/say(msg &lt;span class=&quot;dmkeyword&quot;&gt;as&lt;/span&gt; text)&lt;br&gt;            msg = html_encode(msg) &lt;span class=&quot;dmcomment&quot;&gt;// prevent the user from messing with the log... or other users!&lt;/span&gt;&lt;br&gt;            world &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[usr]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[msg]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&lt;/span&gt;&lt;br&gt;            record( action = ACTION_SAY,&lt;br&gt;                    user   = usr.key,&lt;br&gt;                    notes  = msg )
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
ACTION_SAY just categorizes the log message. See the library's documentation for other built-in actions. The user argument logs which user did the speaking. This might seem like a little extra unnecessary code right now, but don't worry - it will pay off later.&lt;br&gt;
For one more example, consider the attack verb. There is no ACTION_ATTACK - what do we do? This isn't a problem, an action is actually just text. So we can just pass &quot;Attack&quot;.&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob/&lt;span class=&quot;dmkeyword&quot;&gt;verb&lt;/span&gt;/attack(mob/M &lt;span class=&quot;dmkeyword&quot;&gt;as&lt;/span&gt; mob &lt;span class=&quot;dmkeyword&quot;&gt;in&lt;/span&gt; oview(1))&lt;br&gt;            usr &amp;lt;&amp;lt; &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;You attack &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[M]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;!&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/damage = rand(1,10)&lt;br&gt;            record( action = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;Attack&amp;quot;&lt;/span&gt;,&lt;br&gt;                    user   = usr.key,&lt;br&gt;                    target = M.key,&lt;br&gt;                    notes  = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[damage]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; damage&amp;quot;&lt;/span&gt; )&lt;br&gt;            M.HP -= damage
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
Notice that the record() proc takes a target parameter for logging which player something happened to, but all four parameters are optional.&lt;br&gt;
If you get these examples running and do some fighting and talking, you'll notice a 'log.xml' file in the dmb folder. When you open it up, it might look even worse than the log you saw earlier! But that's just because you don't have the right tool yet...&lt;br&gt;
&lt;h3&gt;The Log Viewer Application&lt;/h3&gt;
&lt;br&gt;
In order to use the Log Viewer program, go and &lt;a href=&quot;http://www.byond.com/developer/Nickr5/n_Log&quot;&gt;download n_Log&lt;/a&gt; if you haven't already. In Dream Maker, make sure the 'Show All Files' checkbox is checked, expand the 'LogViewer' folder, and double-click 'LogViewer.exe'. Then select File &amp;gt; Open, and find the log.xml file that the library created. The viewer should load the file and look similar to this:&lt;br&gt;
&lt;a target=&quot;_blank&quot; href=&quot;http://www.byond.com/members/Nickr5/files/map%20Screenshot%20-%2012_28_2010%20%2C%203_40_37%20PM.png&quot; rel=&quot;thumbnail&quot;&gt;&lt;img width=&quot;400&quot; height=&quot;295&quot; src=&quot;http://www.byond.com/members/Nickr5/files/map%20Screenshot%20-%2012_28_2010%20%2C%203_40_37%20PM_thumb.jpg&quot;&gt;&lt;/a&gt;&lt;br&gt;
You can hide and reorder columns to your liking by using the Options menu and by clicking and dragging the headers. Notice that the library logged the date and time for every event automatically. Also notice that now you can sort through all of the events by left-clicking a column header. You can already see how it's a great deal more flexible than an ordinary log file. Finally, you can right-click the top of a column to make a textbox appear at the bottom of the window. There, you can filter the columns. For example, if you right-click 'User' and type your key into the box, you will see only the actions that were performed by you. Also the * character is a wildcard, so entering *om* will show Tom, Dantom, Tommy, Mom, etc.&lt;br&gt;
&lt;a target=&quot;_blank&quot; href=&quot;http://www.byond.com/members/Nickr5/files/map%20Screenshot%20-%2012_28_2010%20%2C%203_41_57%20PM.png&quot; rel=&quot;thumbnail&quot;&gt;&lt;img width=&quot;400&quot; height=&quot;295&quot; src=&quot;http://www.byond.com/members/Nickr5/files/map%20Screenshot%20-%2012_28_2010%20%2C%203_41_57%20PM_thumb.jpg&quot;&gt;&lt;/a&gt;&lt;br&gt;
You can have more than one column filtered at a time. So if you filter the Action column for 'Ban' and the User column for 'Dan', you will see all of the times Dan banned someone (similarly if you filter the Target column instead of the User column, you can see all of the times Dan has &lt;i&gt;been&lt;/i&gt; banned). See the program's help menu for more information on the Log Viewer app.&lt;br&gt;
&lt;h3&gt;Advanced Functionality&lt;/h3&gt;
&lt;br&gt;
The n_Log library holds a few more secrets. For example, you don't &lt;i&gt;have&lt;/i&gt; to log to an XML file. Of course, if you don't then you'll lose the ability to read the logs with the Log Viewer.&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
&lt;span class=&quot;dmcomment&quot;&gt;// For some outrageous reason, /output/default is not (usually) the output type used by default!&lt;/span&gt;&lt;br&gt;logger.SetOutput(&lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt;/output/default(world))
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
The code above makes the record() proc log to the world basically as if you were doing &lt;code&gt;world &amp;lt;&amp;lt; &quot;message&quot;&lt;/code&gt;.&lt;br&gt;
&lt;br&gt;
One last problem to solve: have you ever sent debug messages out to the world for debugging, and then accidently forgotten to remove them before having players try your game? The n_Log library provides a debug() proc for this purpose:&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
debug(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;message&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
But the catch is that it is only defined when the game is compiled in DEBUG mode. Otherwise you'll get a compiler error telling you to get rid of your debugging message!</description>
        </item>
                <item>
            <title>Creating a Platformer With BYOND</title>
            <link>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=104440</link>
            <guid>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=104440</guid>
            <pubDate>Thu, 11 Nov 2010 21:18:46 +0000</pubDate>
            
            <comments>http://www.byond.com/members/DreamMakers?command=view_comments&amp;post=104440#comments</comments>
            
            <description>&lt;h1&gt;Creating a Platformer With BYOND&lt;/h1&gt;
&lt;p&gt;BYOND gives you a default movement system. If you open Dream Maker, create a new project, make icons, declare turfs, build a map, and run the game you can walk around. You don't have to program how the movement works, the behavior is built in. My &lt;a href=&quot;http://www.byond.com/developer/Forum_account/Sidescroller&quot;&gt;Sidescroller&lt;/a&gt; library does the same thing except it provides you with a movement system for sidescrolling action/platform games.&lt;/p&gt;
&lt;p&gt;This article explains how the library works and how you can use it to create a game. If you're familiar with Dream Maker and can make a simple game then you can use this library to make a platformer.&lt;/p&gt;
&lt;h3&gt;Contents&lt;/h3&gt;
&lt;p&gt;1. &lt;a href=&quot;#1&quot;&gt;Object Sizes&lt;/a&gt;&lt;br&gt;
2. &lt;a href=&quot;#2&quot;&gt;Ladders&lt;/a&gt;&lt;br&gt;
3. &lt;a href=&quot;#3&quot;&gt;Icon States&lt;/a&gt;&lt;br&gt;
4. &lt;a href=&quot;#4&quot;&gt;Bounding Boxes and Centered Icons&lt;/a&gt;&lt;br&gt;
5. &lt;a href=&quot;#5&quot;&gt;Jumping&lt;/a&gt;&lt;br&gt;
6. &lt;a href=&quot;#6&quot;&gt;Ramps&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Using the Library&lt;/h2&gt;
&lt;p&gt;The library is very easy to set up. &lt;a href=&quot;http://files.byondhome.com/Forumaccount/sidescroller-tutorial.html&quot;&gt;Here are step-by-step instructions for setting up the library&lt;/a&gt;. If you're familiar with the Dream Maker program you can have a working sidescroller in just a few minutes. This tutorial assumes you've completed those steps to set up the library and create a basic game. If you want to follow along with this tutorial and try code snippets out you should complete those steps now.&lt;/p&gt;
&lt;p&gt;We'll now look at how you can utilize more features of the library and add some new features of your own.&lt;/p&gt;
&lt;a name=&quot;1&quot;&gt;&lt;/a&gt;
&lt;h2&gt;Object Sizes&lt;/h2&gt;
&lt;p&gt;In the world you've created all objects are 32x32 boxes. In a real game your mob's icon will probably be a picture of a person. The mob's icon is 32x32 but the mob only occupies part of that box. To handle this we can modify the mob's &lt;tt&gt;pwidth&lt;/tt&gt; and &lt;tt&gt;pheight&lt;/tt&gt; vars.&lt;/p&gt;
&lt;p&gt;Open up mob.dmi and change the icon state. Instead of being a 32x32 blue box make it a 24x24 blue box, like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://files.byondhome.com/Forumaccount/tut-1.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Then add this to the code:&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob&lt;br&gt;    pwidth = 24&lt;br&gt;    pheight = 24
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Now run the game. The mob now occupies a smaller space than before.&lt;/p&gt;
&lt;a name=&quot;2&quot;&gt;&lt;/a&gt;
&lt;h2&gt;Ladders&lt;/h2&gt;
&lt;p&gt;The library has support for ladders. A ladder is a non-dense tile that a mob can climb. To create a ladder you need to draw an icon state for it, then add this code:&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
turf&lt;br&gt;    ladder&lt;br&gt;        is_ladder = 1&lt;br&gt;        icon_state = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;ladder&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;tt&gt;is_ladder&lt;/tt&gt; variable tells the library that the turf can be climbed. Place some ladders on the map and run the game:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://files.byondhome.com/Forumaccount/tut-2.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Use the up and down arrow keys to climb ladders.&lt;/p&gt;
&lt;a name=&quot;3&quot;&gt;&lt;/a&gt;
&lt;h2&gt;Icon States&lt;/h2&gt;
&lt;p&gt;With BYOND's default movement system it's often sufficient for a mob to have a single, 4-directional icon state. When the player moves the direction is updated so the proper image is shown. In an action/platform game you can perform different kinds of actions, like running or jumping, so you need different icon states. The library handles this for you.&lt;/p&gt;
&lt;p&gt;You set the mob's &lt;tt&gt;icon&lt;/tt&gt; var and the library will automatically update the mob's &lt;tt&gt;icon_state&lt;/tt&gt; based on what the mob is doing. If you're standing still your &lt;tt&gt;icon_state&lt;/tt&gt; will be set to &quot;standing&quot;. If you're moving (on the ground) it'll be set to &quot;moving&quot;. If you're hanging on a ladder it'll be set to &quot;climbing&quot;. And if you're in the air (but not on a ladder) it'll be set to &quot;jumping&quot;.&lt;/p&gt;
&lt;p&gt;Let's create these icon states (or you can &lt;a href=&quot;http://files.byondhome.com/Forumaccount/mob.dmi&quot;&gt;download this icon&lt;/a&gt;, you might need to right click the link and pick &quot;Save As...&quot;):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://files.byondhome.com/Forumaccount/tut-3.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Note: These states are all 4-directional. The library automatically sets your direction to EAST or WEST so you need to make sure those states have images. For reference, here's what the standing state looks like:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://files.byondhome.com/Forumaccount/tut-4.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;You don't need to add any code. When you run the demo your mob will use these new icon states.&lt;/p&gt;
&lt;a name=&quot;4&quot;&gt;&lt;/a&gt;
&lt;h2&gt;Bounding Boxes and Centered Icons&lt;/h2&gt;
&lt;p&gt;A mob's bounding box is the space that the mob occupies. The size of the box is determined by the &lt;tt&gt;pwidth&lt;/tt&gt; and &lt;tt&gt;pheight&lt;/tt&gt; variables. The position of the box is assumed to be in the lower-left corner of the mob's icon. However, this isn't always the case. Consider this poorly drawn person:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://files.byondhome.com/Forumaccount/tut-5.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;The mob is roughly 16 pixels wide. If we set the mob's &lt;tt&gt;pwidth&lt;/tt&gt; var to 16, here's what happens:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://files.byondhome.com/Forumaccount/tut-6.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;The mob appears to be partially inside the wall. This is because the mob's bounding box is assumed to be in the lower left corner of the icon but we drew the mob in the center of the icon. To compensate for this we need to shift the mob's icon to the left 8 pixels when the game is running so that the part of the icon that represents the mob is inside the bounding box. We can do this with the mob's &lt;tt&gt;pixel_x&lt;/tt&gt; var:&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob&lt;br&gt;    pwidth = 16&lt;br&gt;    pheight = 19&lt;br&gt;    pixel_x = -8
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Now here's what you'll see when you run the game:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://files.byondhome.com/Forumaccount/tut-7.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;The icon is shifted to the left so the mob cannot appear to be inside walls anymore.&lt;/p&gt;
&lt;a name=&quot;5&quot;&gt;&lt;/a&gt;
&lt;h2&gt;Jumping&lt;/h2&gt;
&lt;p&gt;The library keeps track of the mob's motion as a velocity. A velocity is like a speed but it also has a direction assigned to it. Saying that the mob is moving four pixels per second is a speed, but saying that it's moving upwards at four pixels per second is a velocity. The library uses the &lt;tt&gt;vel_x&lt;/tt&gt; and &lt;tt&gt;vel_y&lt;/tt&gt; vars to keep track of the mob's velocity in the x (horizontal) and y (vertical) directions.&lt;/p&gt;
&lt;p&gt;This sounds complicated but it actually makes things easy. When you jump, all that happens is your upwards velocity (&lt;tt&gt;vel_y&lt;/tt&gt;) is increased. To handle jumping the library calls the mob's &lt;tt&gt;jump&lt;/tt&gt; proc, here's the default behavior:&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
jump()&lt;br&gt;    vel_y = 10
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;This means that when you jump your mob will move upwards at a rate of 10 pixels per second. Due to gravity it'll slow down and begin to fall. If we wanted to make the mob jump higher we can override the &lt;tt&gt;jump&lt;/tt&gt; proc to create a different behavior. We can add this to our code:&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
mob&lt;br&gt;    jump()&lt;br&gt;        vel_y = 12
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;An upwards velocity of 12 is enough to jump two tiles high. Don't get too carried away - the height of the jump increases a lot with each increase to the velocity. Setting &lt;tt&gt;vel_y = 14&lt;/tt&gt; is enough to jump three tiles high and 16 is enough to jump four tiles high.&lt;/p&gt;
&lt;a name=&quot;6&quot;&gt;&lt;/a&gt;
&lt;h2&gt;Ramps&lt;/h2&gt;
&lt;p&gt;You can also create ramps. Open turfs.dmi and make an icon that looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://files.byondhome.com/Forumaccount/tut-8.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Call it &quot;ramp&quot;. Then add this code:&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
turf&lt;br&gt;    ramp&lt;br&gt;        pleft = 0&lt;br&gt;        pright = 32&lt;br&gt;        density = 1&lt;br&gt;        icon_state = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;ramp&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;tt&gt;pleft&lt;/tt&gt; and &lt;tt&gt;pright&lt;/tt&gt; vars are used to define ramps. The &lt;tt&gt;pleft&lt;/tt&gt; var tells the library the height of the turf at its left side. The &lt;tt&gt;pright&lt;/tt&gt; var tells the library the height of the turf at its right side. We drew the ramp as being low on the left side and high on the right side so we set its &lt;tt&gt;pleft&lt;/tt&gt; and &lt;tt&gt;pright&lt;/tt&gt; to match. The height at its right side is 32 because the tiles are 32 pixels tall.&lt;/p&gt;
&lt;p&gt;Place the ramp on the map and run the game.&lt;/p&gt;</description>
        </item>
                <item>
            <title>Web Service: Mediator server for BYOND authentication</title>
            <link>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=103749</link>
            <guid>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=103749</guid>
            <pubDate>Tue, 26 Oct 2010 21:11:19 +0000</pubDate>
            
            <comments>http://www.byond.com/members/DreamMakers?command=view_comments&amp;post=103749#comments</comments>
            
            <description>&lt;p&gt;In the past, authentication with a BYOND key was only possible if you used DMCGI to do it. There was simply no way to get the login details any other way. Some people have &lt;a href=&quot;http://www.byond.com/members/DreamMakers?command=view_tracker_issue&amp;tracker_issue=1251&quot; target=&quot;_blank&quot;&gt;requested a new feature&lt;/a&gt; to allow any program to authenticate BYOND keys.&lt;/p&gt;
&lt;p&gt;That feature might not be here, but I offer the next best thing: authentication using a mediator server (which is pretty much what the feature request suggests anyway, so I guess I did the work for them!).&lt;/p&gt;
&lt;p&gt;Without further ado I would like to present:&lt;/p&gt;
&lt;h3&gt;The &lt;s&gt;McKay-Carter Intergalactic Bridge&lt;/s&gt; dta_auth BYOND authentication system&lt;/h3&gt;
&lt;p&gt;Let's get on with the technical details, as I'm sure most of you are looking straight for it.&lt;/p&gt;
&lt;p&gt;The following steps are taken to authenticate a user:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The user arrives at &lt;em&gt;http://www.yoursite.com/login.php&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;At this point your script redirects the user to &lt;em&gt;http://home.androiddata.net/auth.cgi&lt;/em&gt; and passes along two variables:
&lt;ul&gt;
&lt;li&gt;A &lt;u&gt;session id&lt;/u&gt; which is a variable only your server and the real client share. Upon receival this is immediately taken out of the loop to minimize the possibility of eavesdropping. In my example it is derived from the current time.&lt;/li&gt;
&lt;li&gt;A &lt;u&gt;return URL&lt;/u&gt; which is usually back to your script. In my example it will be &lt;em&gt;http://www.yoursite.com/login.php&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The user is taken to &lt;em&gt;http://secure.byond.com&lt;/em&gt; where they can login..&lt;/li&gt;
&lt;li&gt;Once the user successfully logs in with a valid BYOND key they are redirected back to &lt;em&gt;http://home.androiddata.net/auth.cgi&lt;/em&gt; where the magic happens.&lt;/li&gt;
&lt;li&gt;My script redirects the user back to &lt;em&gt;http://www.yoursite.com/login.php&lt;/em&gt; where you receive a certificate ID. You then pass this value back and confirm the validity of the certificate, after which the authentication is completed.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The security measures taken:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A unique ID pinpoints the exact certificate that contains the authentication request.&lt;/li&gt;
&lt;li&gt;A session ID verifies that the certificate was indeed requested by your server.&lt;/li&gt;
&lt;li&gt;A hash is sent with the client to ensure that they have access to that certificate and to ensure other domains can't read your certificates.&lt;/li&gt;
&lt;li&gt;The BYOND key and ckey are both stored in the certificate and cross-referenced with what you receive to prevent spoofing of keys.&lt;/li&gt;
&lt;li&gt;You may optionally specify an IP address (or other unique means of verification) to verify that as well.&lt;/li&gt;
&lt;li&gt;Finally, the certificate is destroyed immediately after you've checked it to prevent it from being re-used in the future.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In addition to the above clients are expected to always log-in with a new set of credentials, so it's not possible for a client to re-use someone else's log-in on your site.&lt;/p&gt;
&lt;p&gt;And now a code sample (because nobody on BYOND listens to you unless you post one!):&lt;/p&gt;
&lt;tt&gt;index.php&lt;/tt&gt;&lt;br&gt;
&lt;code style=&quot;display: block; margin: 16px; padding: 8px; background-color: #FFF; border: 1px solid #000;&quot;&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&amp;nbsp;session_start&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br&gt;
&lt;br&gt;
if(isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'byond_key'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;])){&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'You&amp;nbsp;are&amp;nbsp;logged&amp;nbsp;in&amp;nbsp;as&amp;nbsp;'&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'byond_key'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]&amp;nbsp;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'!&amp;nbsp;&amp;lt;a&amp;nbsp;href=&quot;login.php?logout=1&quot;&amp;gt;Logout&amp;lt;/a&amp;gt;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br&gt;
}else{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'You&amp;nbsp;are&amp;nbsp;NOT&amp;nbsp;logged&amp;nbsp;in.&amp;nbsp;&amp;lt;a&amp;nbsp;href=&quot;login.php&quot;&amp;gt;Login&amp;lt;/a&amp;gt;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br&gt;
}&lt;br&gt;&lt;/span&gt; &lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
&lt;tt&gt;login.php&lt;/tt&gt;&lt;br&gt;
&lt;code style=&quot;display: block; margin: 16px; padding: 8px; background-color: #FFF; border: 1px solid #000;&quot;&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&amp;nbsp;session_start&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br&gt;
&lt;br&gt;&lt;/span&gt; &lt;span style=&quot;color: #FF8000&quot;&gt;//the&amp;nbsp;URL&amp;nbsp;that&amp;nbsp;the&amp;nbsp;mediator&amp;nbsp;server&amp;nbsp;should&amp;nbsp;reroute&amp;nbsp;the&amp;nbsp;user&amp;nbsp;to&amp;nbsp;once&amp;nbsp;authentication&amp;nbsp;finishes&amp;nbsp;goes&amp;nbsp;here&lt;br&gt;&lt;/span&gt; &lt;span style=&quot;color: #0000BB&quot;&gt;define&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'URL'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'http://www.cowed.org/auth/login.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;
&lt;br&gt;
if(!isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'byond_key'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;])){&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;//we&amp;nbsp;are&amp;nbsp;not&amp;nbsp;logged&amp;nbsp;in&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;if(isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_GET&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'id'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;])&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_GET&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'key'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;])&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_GET&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'ckey'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;])&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_GET&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'hash'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;])){&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;//looks&amp;nbsp;like&amp;nbsp;we&amp;nbsp;received&amp;nbsp;a&amp;nbsp;response&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$crl&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;curl_init&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;curl_setopt&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$crl&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;CURLOPT_URL&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'http://home.androiddata.net/auth.cgi?id='&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_GET&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'id'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]&amp;nbsp;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;amp;sid='&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'sid'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]&amp;nbsp;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;amp;hash='&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_GET&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'hash'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]&amp;nbsp;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;amp;ckey='&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_GET&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'ckey'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]&amp;nbsp;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;amp;key='&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_GET&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'key'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;curl_setopt&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$crl&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;CURLOPT_RETURNTRANSFER&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;curl_setopt&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$crl&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;CURLOPT_CONNECTTIMEOUT&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$ret&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;curl_exec&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$crl&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;curl_close&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$crl&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$ret&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;==&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;){&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'byond_key'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_GET&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'key'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;header&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Location:&amp;nbsp;index.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}else{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'ERROR:&amp;nbsp;Received&amp;nbsp;return&amp;nbsp;code&amp;nbsp;'&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$ret&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;nbsp;from&amp;nbsp;the&amp;nbsp;mediator&amp;nbsp;server.'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}else{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;//redirect&amp;nbsp;the&amp;nbsp;user&amp;nbsp;to&amp;nbsp;the&amp;nbsp;mediator&amp;nbsp;server&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'sid'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;time&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;header&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Location:&amp;nbsp;http://home.androiddata.net/auth.cgi?sid='&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_SESSION&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'sid'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]&amp;nbsp;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;amp;returnurl='&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;URL&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}else{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;//we're&amp;nbsp;already&amp;nbsp;logged&amp;nbsp;in,&amp;nbsp;so&amp;nbsp;continue&amp;nbsp;unless&amp;nbsp;explicitly&amp;nbsp;instructed&amp;nbsp;to&amp;nbsp;logout&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;if(isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_GET&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'logout'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;])){&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_SESSION&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;array();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;session_destroy&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;header&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Location:&amp;nbsp;index.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;&lt;/span&gt; &lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;
&lt;p&gt;Please note: The example requires that you have the &quot;curl&quot; extension installed for PHP and assumes an installation of PHP5.2 or higher. If it doesn't work for you try &lt;a href=&quot;http://nadeausoftware.com/articles/2007/07/php_tip_how_get_web_page_using_fopen_wrappers&quot; target=&quot;_blank&quot;&gt;these instructions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope that this web service will open up more BYOND-powered websites and services.&lt;/p&gt;
&lt;p&gt;Thanks!&lt;br&gt;
-D&lt;/p&gt;</description>
        </item>
                <item>
            <title>JRUtils - Numbers</title>
            <link>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=101236</link>
            <guid>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=101236</guid>
            <pubDate>Wed, 01 Sep 2010 04:53:48 +0000</pubDate>
            
            <comments>http://www.byond.com/members/DreamMakers?command=view_comments&amp;post=101236#comments</comments>
            
            <description>&lt;p&gt;A few weeks ago I saw a library floating around that claimed to convert numbers to their spelled-out form. Having done this before, I was curious how the author went about implementing it themselves. As it turned out, the result wasn't all that great. But since I already happened to have Perl code lying around for just such an occasion, I thought, why not convert it to DM?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.byond.com/developer/LummoxJR/jruNumbers&quot;&gt;JRUtils - Numbers&lt;/a&gt; was born out of a plugin I wrote for the Movable Type blog system several years ago. The original plugin was designed to do several things: Change a word to its plural form depending on a number it was given, spell out numbers, and add commas as desired. In a blog environment this was a nice thing to have. Movable Type, at least at the time, was based all around setting up templates and it used pseudo-HTML tags to do its work. My plugin created some new tags to use, so if someone wanted their posts to show &quot;three comments&quot; they could do so, but &quot;3 lunches&quot; would have been just as easy. This gave a lot of stylistic freedom to blog authors.&lt;/p&gt;
&lt;p&gt;This library can be used in a variety of different games, but will fit in particularly well in board games, MUDs, strategy games, etc. And as a bonus, it's one of the libraries on the no-penalty list for the &lt;a href=&quot;http://www.byond.com/members/LummoxJR?command=view_post&amp;post=100695&quot;&gt;Cartridge Classic II&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Plurals&lt;/h3&gt;
&lt;p&gt;The DM language already includes a very handy macro for pluralizing words, the \s macro. But as I discovered in Incursion, this isn't always ideal. Not every word has a plural form ending in -s. Some have unusual plural forms, like &quot;deer&quot;, but most words follow a few basic rules.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If a word ends in s, ch, sh, or x, the plural should have -es added.&lt;/li&gt;
&lt;li&gt;If a word ends in z, the plural should have -es added, but the z should be doubled if it isn't already.&lt;/li&gt;
&lt;li&gt;If a word ends in y, and the y is not preceded by a vowel, the -y should be replaced with -ies.&lt;/li&gt;
&lt;li&gt;All other words, with only specific exceptions, should have -s added.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A common rule, but one that does not apply to every such word, is that words ending in -o also get an -es instead of just an -s. But even though this is more than norm than the exception, it isn't applied here. A few other common but not universal rules, like -lf to -lves, and -is to -es, are also left out. You're on your own with those.&lt;/p&gt;
&lt;p&gt;Now there's a proc that follows those rules, and it leaves the capitalization of the original word intact (as best it can).&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
jru_Pluralize(word, n=0)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;If you pass in a word and a number, you'll get the plural version of the word. You don't have to pass in a number; it's just there so that if the number is 1, the word doesn't get changed.&lt;/p&gt;
&lt;p&gt;If the word you want to pluralize doesn't have a &quot;normal&quot; plural form, you can add it to the &lt;tt&gt;jru_plurals&lt;/tt&gt; list at runtime like so:&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
jru_plurals[&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;cactus&amp;quot;&lt;/span&gt;] = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;cacti&amp;quot;&lt;/span&gt;&lt;br&gt;jru_plurals[&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;half&amp;quot;&lt;/span&gt;] = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;halves&amp;quot;&lt;/span&gt;&lt;br&gt;jru_plurals[&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;person&amp;quot;&lt;/span&gt;] = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;people&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Always add the words to the list in lowercase form. Any word in this associative list will be pluralized to the correct form you supply, but with its original capitalization intact.&lt;/p&gt;
&lt;p&gt;There's one other bonus here, which is that the number &lt;tt&gt;n&lt;/tt&gt; may be a text string. It doesn't have to be a &quot;true&quot; number.&lt;/p&gt;
&lt;p&gt;For longer stretches of text, there is another proc available:&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
jru_PlurlizeText(txt)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;This proc will look for any instance of &quot;[number] [word]&quot; in a block of text and try to pluralize the word if necessary.&lt;/p&gt;
&lt;h3&gt;Commas&lt;/h3&gt;
&lt;p&gt;It's common to see commas inserted into numbers in formal writing, like 1,000 for a thousand instead of the blunt 1000 that is spit out if you just stick the number directly into the output. Even worse, if you're using large numbers they may just look like &quot;1.0e6&quot; instead of 1000000 or 1,000,000.&lt;/p&gt;
&lt;p&gt;While this is easy to soft-code by yourself, why reinvent the wheel?&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
jru_Commafy(n)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;This proc returns &lt;tt&gt;n&lt;/tt&gt; with commas inserted. The number &lt;tt&gt;n&lt;/tt&gt; may be a number, or it may be a number in text form like &lt;tt&gt;&quot;1234&quot;&lt;/tt&gt; instead of &lt;tt&gt;1234&lt;/tt&gt;. Decimal points and negatives are left intact.&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
jru_CommafyText(txt)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;This applies the commafication to a whole block of text, converting any numbers within to comma form.&lt;/p&gt;
&lt;h3&gt;Spelling out&lt;/h3&gt;
&lt;p&gt;Converting numbers to their spelled-out, textual representation is a tricky business because there are so many rules to follow. Fortunately, this routine takes all the guesswork out.&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
jru_NumberText(n, th)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;This returns the number &lt;tt&gt;n&lt;/tt&gt; (which again, may be represented as a text string instead of a true number) in a spelled-out format. If the &lt;tt&gt;th&lt;/tt&gt; argument is true, the result will be in an ordinal form (e.g., &quot;first&quot; instead of &quot;one&quot;). The routine only works with whole, positive numbers, so it will discard everything after a decimal point and turn negatives to positives.&lt;/p&gt;
&lt;p&gt;Here are some examples:&lt;/p&gt;
&lt;table border=&quot;1&quot; cellpadding=&quot;3&quot; cellspacing=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;th&gt;&lt;tt&gt;n&lt;/tt&gt;&lt;/th&gt;
&lt;th&gt;result (&lt;tt&gt;th=0&lt;/tt&gt;)&lt;/th&gt;
&lt;th&gt;result (&lt;tt&gt;th=1&lt;/tt&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;one&lt;/td&gt;
&lt;td&gt;first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;thirteen&lt;/td&gt;
&lt;td&gt;thirteenth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;twenty-five&lt;/td&gt;
&lt;td&gt;twenty-fifth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;one hundred&lt;/td&gt;
&lt;td&gt;hundredth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;140&lt;/td&gt;
&lt;td&gt;one hundred forty&lt;/td&gt;
&lt;td&gt;one hundred fortieth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1234&lt;/td&gt;
&lt;td&gt;one thousand, two hundred thirty-four&lt;/td&gt;
&lt;td&gt;one thousand, two hundred thirty-fourth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9001&lt;/td&gt;
&lt;td&gt;nine thousand one&lt;/td&gt;
&lt;td&gt;nine thousand first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1000000&lt;/td&gt;
&lt;td&gt;one million&lt;/td&gt;
&lt;td&gt;millionth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1000002&lt;/td&gt;
&lt;td&gt;one million two&lt;/td&gt;
&lt;td&gt;one million second&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;The routine is smart enough to throw away unnecessary commas, as in &quot;nine thousand one&quot; instead of &quot;nine thousand, one&quot;. Also in an ordinal form, it will omit a leading &quot;one&quot; if there is only one other word, like &quot;hundredth&quot;.&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
&lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;/jru_NumbersText(txt)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;This routine will convert all numbers in a block of text to their spelled-out equivalents. If the number is followed by st, nd, rd, or th, it will be converted to ordinal form. So &quot;My 1st victory earned 9 points!&quot; would become &quot;My first victory earned nine points!&quot; instead.&lt;/p&gt;
&lt;h3&gt;Utility&lt;/h3&gt;
&lt;p&gt;A few other routines are included for various helpful purposes.&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
jru_Leading(n, places=1, fill=&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;0&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Takes a number n, in numerical or string format, and pads it out to the number of places you want with a leading digit or character. This is good for timers, for instance, so you can call &lt;tt&gt;&quot;[hours]:[jru_Leading(minutes,2)]:[jru_Leading(seconds,2)]&quot;&lt;/tt&gt; to output to your timer display.&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
jru_SplitText(txt, delimit=&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;This splits a line of text into a list. It's used internally to reduce the number of strings that get compiled with your project. Unlike params2list() it will work well with duplicate values, since the result is not an associative list.&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
jru_SanitizeNum(n, no_negative=0, no_decimal=0)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;The number n, in numerical or string format, is converted to a string. If negatives or decimals are not allowed they can be removed. Unlike just using &lt;tt&gt;&quot;[n]&quot;&lt;/tt&gt;, this will correctly output a number like &lt;tt&gt;1e6&lt;/tt&gt; as &lt;tt&gt;&quot;1000000&quot;&lt;/tt&gt;. It's like a version of &lt;tt&gt;text2num()&lt;/tt&gt; that always gets all the digits it can, but it also can take bogus input and clean it up.&lt;/p&gt;
&lt;h3&gt;Rule Your Numbers!&lt;/h3&gt;
&lt;p&gt;Hopefully this library will provide just the routines you need to tame numbers in your games, providing classier output and jazzing up your statpanels, grids, and text. What can you do with numbers once they're tamed down?&lt;/p&gt;</description>
        </item>
                <item>
            <title>It works, so it must be right!</title>
            <link>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=95390</link>
            <guid>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=95390</guid>
            <pubDate>Wed, 12 May 2010 19:56:23 +0000</pubDate>
            
            <comments>http://www.byond.com/members/DreamMakers?command=view_comments&amp;post=95390#comments</comments>
            
            <description>&lt;div style='font-size: 20pt; text-align: center;'&gt;You're Wrong.&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
There's a certain mentality that I've noticed a lot of users within our ranks have. This is mostly common to inexperienced programmers who have managed to throw out what can be considered barely passable games and who now suddenly think they're top dog because they've done so.&lt;br&gt;
&lt;br&gt;
The mentality I'm referring too is pretty much summed up in the title of this post, if at any time recently you've said: &quot;it works, so I'm doing it right&quot;, &quot;you do it differently than I do, that doesn't make you right&quot; or any variation there of, then chances are you fall into this category. And this post is aimed directly between your eyes.&lt;br&gt;
&lt;br&gt;
You see, there are many ways to do lots of things. And anyone with any life experience can tell you, even though they work, it doesn't make them safe, advisable and least of all, correct.&lt;br&gt;
&lt;br&gt;
For a quick analogy: I can drive the wrong way down a motorway. By the logic of those targeted at this post, I'm doing it right, because I'm still getting to my desired destination. By the logic of all other experienced motorists not on any form of narcotic, I'm being an absolute tool by driving recklessly and putting the lives of other people in my obviously foolish hands.&lt;br&gt;
&lt;br&gt;
In a real life scenario, I'd probably get my license revoked for dangerous driving and there might also be some jail time depending on my reaction towards the judge. If programming required a license, everyone this post is targeted at would by theory, also get their licenses revoked and no longer be allowed to make games. And I dare say a few of you would also be looking at jail time for your reactions towards those who attempt to help you by telling you you're doing it wrong.&lt;br&gt;
&lt;br&gt;
Now lets move onto a code example. One &lt;a href='http://www.byond.com/members/Garthor'&gt;Garthor&lt;/a&gt; corrected me on recently; just to show that even I am not infallible when it comes to programming. You can view the thread &lt;a href='http://www.byond.com/developer/forum/?id=730525&amp;view=1#730525'&gt;here&lt;/a&gt;. Please note my reaction, or lack there of, as that is pretty much what this entire post is about. Instead of arguing that I'm correct because it works, I conferred with my colleagues and then accepted the words of a superior programmer silently, and am now no longer making that mistake.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Wrong:&lt;/b&gt;&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
&lt;span class=&quot;dmpreprocessor&quot;&gt;#define SECOND 10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;dmpreprocessor&quot;&gt;#define MINUTE (SECOND * 60)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;dmpreprocessor&quot;&gt;#define HOUR (MINUTE * 60)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;dmpreprocessor&quot;&gt;#define DAY (HOUR * 24)&lt;/span&gt;&lt;br&gt;&lt;br&gt;client&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;        SaveProc()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;//Some random save proc for clients.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;    recursive_save_or_something()&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;for&lt;/span&gt;(&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/client/C) C.SaveProc()&lt;br&gt;        sleep(HOUR) &lt;br&gt;        .()
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Better:&lt;/b&gt;&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
&lt;span class=&quot;dmpreprocessor&quot;&gt;#define SECOND 10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;dmpreprocessor&quot;&gt;#define MINUTE (SECOND * 60)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;dmpreprocessor&quot;&gt;#define HOUR (MINUTE * 60)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;dmpreprocessor&quot;&gt;#define DAY (HOUR * 24)&lt;/span&gt;&lt;br&gt;&lt;br&gt;client&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;        SaveProc()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;//Some random save proc for clients.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;    recursive_save_or_something()&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;while&lt;/span&gt;(TRUE)&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;for&lt;/span&gt;(&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/client/C) C.SaveProc()&lt;br&gt;            sleep(HOUR)&lt;br&gt;        
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
(Come to think of it, that proc should probably have a &lt;tt&gt;set background = TRUE&lt;/tt&gt; in it.)&lt;br&gt;
&lt;br&gt;
As you can see, my original example still worked, but that didn't mean I was right, at the end of the line, a place you can't reach in two minute testing sessions of new features, I'd have eventually crashed my game entirely. And we all know what that means.&lt;br&gt;
&lt;br&gt;
I'd have gone running to the developer forums crying: &quot;why oh why sweet merciful gods of programming does my game fail so?&quot; They would have eventually given me an answer if anyone cared enough to stick around long enough to debug it, and I'd have been left with &lt;i&gt;a lot&lt;/i&gt; of reworking to do, simply because I never learned my lesson and undoubtedly made lots more of these mistakes.&lt;br&gt;
&lt;br&gt;
Now let's take a trip down memory lane, way back in 2005 when I was a way more inexperienced programmer than I am now and dared to ask the question a lot of you refuse to ask and stick to your &quot;I'm right&quot; mentality: &lt;a href='http://www.byond.com/developer/forum/?id=362322&amp;view=1#362322'&gt;Why does which way matter?&lt;/a&gt;. This thread should explain to you why we go out of our way to tell you why your examples are incorrect. Don't let the attitude a lot of us have fool you, our goal is to help you. But we're not certified teachers and a lot of us don't have the patience to hold your hand through everything. Which is why we often link to reference material that we hope you will read and understand.&lt;br&gt;
&lt;br&gt;
I hope this article has been enlightening for you. And I also hope that it's also opened a few peoples eyes. You don't learn by getting it right first time every time, but if you're doing it wrong, you will learn by simply asking the right questions and learning from what better programmers have to say. If I had not listened to &lt;a href='http://www.byond.com/members/LummoxJR'&gt;Lummox JR&lt;/a&gt;, &lt;a href='http://www.byond.com/members/Wizkidd0123'&gt;Wizkidd0123&lt;/a&gt;, &lt;a href='http://www.byond.com/members/xooxer'&gt;Xooxer&lt;/a&gt;, &lt;a href='http://www.byond.com/members/crispy'&gt;Crispy&lt;/a&gt;, &lt;a href='http://www.byond.com/members/ymihere'&gt;YMIHere&lt;/a&gt; or &lt;a href='http://www.byond.com/members/Garthor'&gt;Garthor&lt;/a&gt;, I'd still be making horrendous mistakes that would ultimately cost me the stability of my game.&lt;br&gt;
&lt;br&gt;
That's not to say I'm still not making mistakes, as humans, we are doomed to forever make mistakes. Hell, the previous example I used in this post probably has a better way to go about it (ten points for someone who comes up with a working theory as to why). Which is precisely what &lt;a href='http://www.byond.com/developer/forum/?forum=5'&gt;Design Philosophy&lt;/a&gt; is for: Asking people if how you're doing something is right, and whether or not there's a better method to go about it.&lt;br&gt;
&lt;br&gt;
If this post reminds you of yourself, I also recommend reading &lt;a href='http://www.byond.com/members/DreamMakers?command=view_post&amp;post=32633'&gt;How to Fail at Game Programming&lt;/a&gt; by &lt;a href='http://www.byond.com/members/Deadron'&gt;Deadron&lt;/a&gt;. Well worth it, if only for the entertainment value.</description>
        </item>
                <item>
            <title>Novice Programmer Guide To Success #1</title>
            <link>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=91907</link>
            <guid>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=91907</guid>
            <pubDate>Wed, 14 Apr 2010 02:00:08 +0000</pubDate>
            
            <comments>http://www.byond.com/members/DreamMakers?command=view_comments&amp;post=91907#comments</comments>
            
            <description>&lt;u&gt;I&lt;/u&gt;ntroduction...&lt;br&gt;
&lt;br&gt;
Taking the step from simply being a gamer, and going into the world of programming and development is a large step. It requires the willingness to learn, experiment, and take advice and criticism. It may be confusing at first, but as you learn you will be able to look back at your previous attempts and laugh. One of the most important things for the new programmer is how to ask for help, and learn from it. You should only ask for help after you have checked for examples of what you want to do in the resources section.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;u&gt;I&lt;/u&gt; need the code...&lt;br&gt;
&lt;br&gt;
When asking for help you want to explain what you are trying to do, and what parts you are having trouble with. Below are examples of the right and wrong way to ask for something. This is a common question I have come across, along with a snippet of code I would provide to each question.&lt;br&gt;
&lt;br&gt;
(R = Right, W = Wrong)&lt;br&gt;
&lt;br&gt;
W: I want a GM code.&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
&lt;span class=&quot;dmcomment&quot;&gt;// The GM code.&lt;/span&gt;&lt;br&gt;GM
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
R: I would like to know how to give certain people in my game special verbs and stats.&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
&lt;span class=&quot;dmcomment&quot;&gt;// A global list containing the keys of our game masters, separated by commas.&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/list/GMs=list(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;Ulterior Motives&amp;quot;&lt;/span&gt;)&lt;br&gt;&lt;br&gt;&lt;span class=&quot;dmcomment&quot;&gt;// A global list of out players, GMs should not be in this list.&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/list/players=list()&lt;br&gt;&lt;br&gt;&lt;span class=&quot;dmcomment&quot;&gt;// Create a datum type to hold all of our special verbs.&lt;/span&gt;&lt;br&gt;GM&lt;br&gt;  &lt;br&gt;  &lt;span class=&quot;dmcomment&quot;&gt;// Kick people out of your world.&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;dmkeyword&quot;&gt;verb&lt;/span&gt;/Boot()&lt;br&gt;    &lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;// Let the person using the verb pick a player out of our list. &lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;del&lt;/span&gt;(input(&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;Which player would you like to boot?&amp;quot;&lt;/span&gt;,&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;Boot&amp;quot;&lt;/span&gt;) &lt;span class=&quot;dmkeyword&quot;&gt;in&lt;/span&gt; (players))&lt;br&gt;&lt;br&gt;&lt;span class=&quot;dmcomment&quot;&gt;// The mob type of our human players.&lt;/span&gt;&lt;br&gt;mob/player&lt;br&gt;    &lt;br&gt;  &lt;span class=&quot;dmcomment&quot;&gt;//Give them some variables.&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;&lt;br&gt;    health = 10&lt;br&gt;    strength = 3&lt;br&gt;  &lt;br&gt;  &lt;span class=&quot;dmcomment&quot;&gt;//When they connect to a mob, this is not the same as New().&lt;/span&gt;&lt;br&gt;  Login()&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;//Place them on the first non-dense tile.&lt;/span&gt;&lt;br&gt;    ..()&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;//If they are an admin give them our special verbs and stats.&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(src.key &lt;span class=&quot;dmkeyword&quot;&gt;in&lt;/span&gt; GMs)&lt;br&gt;      src.verbs += typesof(/GM/&lt;span class=&quot;dmkeyword&quot;&gt;verb&lt;/span&gt;)&lt;br&gt;      src.health += 20&lt;br&gt;      src.strength += 10&lt;br&gt;      &lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;//Otherwise add them to the list players.&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;else&lt;/span&gt;&lt;br&gt;      players.Add(src)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
As you can see explaining what you want, instead of asking for the code gives you much better results. This goes beyond just getting some snippet of code however. Now that you have &quot;the code&quot; what are you going to do with it? Typically the new programmer will copy and paste the code into their project. This is wrong, and you won't learn anything, nor will you be able to change it to fit your needs. Most of the time when asking for help you will get examples of how to do something, so you can learn how to do it yourself.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;u&gt;W&lt;/u&gt;hat are those double slashes for...?&lt;br&gt;
&lt;br&gt;
Every programming language provides a way for programmer to add comments to their code to explain how it works. Why would they do such a crazy thing if they already know what it does? Sometimes programmers might forget how something works after going back to look at it later, but this isn't their only use. In the example the comments are used to help you learn what the code does. I can guarantee if you read these comments, and try to understand what the code does and write your own you will learn how to program much faster.&lt;br&gt;
&lt;br&gt;
When I first started learning and asking for help, comments helped me more than anything. Gathor is the one who typically helped me with my problems on the forums, and reading his comments made learning how to program much easier. If I didn't understand something I would ask how it works, this is how to succeed at asking for help and learning from it.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;u&gt;P&lt;/u&gt;rojects and goals...&lt;br&gt;
&lt;br&gt;
Most new programmers read a tutorial like one of the great &lt;a href=&quot;http://www.byond.com/members/DreamMakers?command=view_post&amp;post=36143&quot;&gt;ZBTs&lt;/a&gt;, and they think they can jump in and create and start on a large RPG or some other massive project. This is an extremely terrible idea. You need to start small, and build on to that. Create a variety of small games to advance your skills and learn new techniques and ways of programming. Release this to the general BYOND community and announce it on the forums. Now people can comment on what you have done, and give you more ideas to add on. This way you can keep adding to this small project, and learn new things along the way.&lt;br&gt;
&lt;br&gt;
Always set goals to achieve when starting a project(see also &lt;a href=&quot;http://www.byond.com/members/DreamMakers?command=view_post&amp;post=83278&quot;&gt;Functional Specifications&lt;/a&gt; for designing your project). For instance if you read &lt;a href=&quot;http://www.byond.com/members/DreamMakers?command=view_post&amp;post=36143&quot;&gt;ZBT #1&lt;/a&gt; about creating RPGs, she has goals at the end for you to add onto the project. Try to complete these goals, then add your own. The more things to do the more you will learn, after doing this your programming problem solving skills will increase. Goals for &lt;a href=&quot;http://www.byond.com/members/DreamMakers?command=view_post&amp;post=36143&quot;&gt;ZBT #1&lt;/a&gt; could include, making an NPC walk around, making an enemy drop a random item only 25% of the time when they are killed, creating random server messages that go to the players, or anything. Just stick with that one goal until it is completed.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;u&gt;S&lt;/u&gt;ummary...&lt;br&gt;
&lt;br&gt;
How fast or slow you learn to program, and how well you learn to program all depends on you. If you are willing to learn and don't get discouraged you will learn quickly. If you use the resources provided to you and take help as a learning experience you will learn how to do this the right way.&lt;br&gt;
&lt;br&gt;
Just remember one of the most basic rules of programming, if you are repeatedly doing the same thing over and over with if statements and what not, then you are doing something wrong. This is where your programing problem solving should kick in. The more you know the easier this will be to do. At first though you might need to post it in the developer how-to and ask how to take out the repetitiveness. After a few weeks to a month you should be able to look at it and learn on your own how to do this.&lt;br&gt;
&lt;br&gt;
If this helps even one newcomer break away from the typical fate of the new programmer, then my goal was successful. I will be around to help any new programmer as long as they are trying to learn and following this guide. Programming can be very fun and rewarding once you get the hang of it. Breathing air into and creating a project yourself is a good feeling.&lt;br&gt;
&lt;br&gt;
I'll leave you with a quote by a very inspirational man that explains what I'm trying to say.&lt;br&gt;
&lt;br&gt;
&quot;When the race gets hard to run. It means you just can't take the pace.&quot; -- Bob Marley</description>
        </item>
                <item>
            <title>Decent Game Design, Part 1 - Player Entry</title>
            <link>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=91199</link>
            <guid>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=91199</guid>
            <pubDate>Fri, 12 Feb 2010 10:48:53 +0000</pubDate>
            
            <comments>http://www.byond.com/members/DreamMakers?command=view_comments&amp;post=91199#comments</comments>
            
            <description>Welcome to part one of the decent game design series. This series expects you to have a basic knowledge of the BYOND Interface, and to have read the &lt;a href='http://www.byond.com/members/DreamMakers?command=view_keyword_posts&amp;keyword=skins'&gt;Making skins in BYOND 4.0&lt;/a&gt; series by &lt;a href='http://www.byond.com/members/LummoxJR'&gt;Lummox JR&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
Please keep in mind, the integrity of the series may be undermined by the fact I'm absolutely horrible at graphics. Just be aware that where my graphics are terrible, hopefully, others wont be, and thus the tricks and tips that so very few people seem to know and use will not only help you advertise within BYOND, but also outside of BYOND.&lt;br&gt;
&lt;br&gt;
First and foremost, let's look at at what most games that aren't taking advantage of the skins look like to the casual new user. To avoid offending users, I've recreated the look I get when I joined the better most of games.&lt;br&gt;
&lt;br&gt;
&lt;a href='http://www.byond.com/members/DMRC/files/tiberath/professional/entry/professional_design_1%2D01.png' rel=&quot;thumbnail&quot;&gt;&lt;img src='http://www.byond.com/members/DMRC/files/tiberath/professional/entry/professional_design_1%2D01.png' width='380' height='240'&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
As you can see, rushed appearance of my graphics aside, that is pretty poor. There's a lot of information on that which really doesn't need to be there. If I was some random new player who found your game outside of BYOND, I probably wouldn't give it the time of day. Let's break down what's wrong with it.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Unnecessary Stat() Tabs&lt;/b&gt;:&lt;br&gt;
Let's face it, I haven't made or loaded a character yet. So there's absolutely no reason why I should be able to see it's name, race, inventory and other stats (hp, mp, exp etc). This stuff is utterly useless. Remove it.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Unnecessary Verbs&lt;/b&gt;:&lt;br&gt;
Much like the stats, I'm not in a character, so I shouldn't have access to verbs like &quot;Chop Wood&quot; or even, &quot;say&quot;. You can argue the OOC tab possibly, but to be honest, how many games have you played outside of BYOND that allow you communicate with the users &lt;i&gt;before&lt;/i&gt; you've entered the game. None I'm aware of (there's probably a small few, but we're going with majorities here). This just looks tacky and, if you haven't actually protected any of your verbs from misuse, can lead to bugs in your games.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Load/Create/Delete/Quit Verbs&lt;/b&gt;:&lt;br&gt;
These are buttons on the map itself. Completely pointless having these in view like that. You might as well have not included the splash screen itself, all it appears to be is a pretty (ugly...) face to an otherwise ugly layout.&lt;br&gt;
&lt;br&gt;
So, let's work on improving this. Firstly, what does that interface screen actually have? A background picture and three buttons. Seems easy enough. To give you an example, we'll make this work in a new project, you can later adapt it to your own projects if you want.&lt;br&gt;
&lt;br&gt;
So, make an interface file. We're given a set of default marcos, a default menu and a default window. The default window is where the tricky stuff is going to happen.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Setting up your default window&lt;/b&gt;:&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;Rename the default window to window_default.&lt;br&gt;&lt;/li&gt;
&lt;li&gt;Place a child control on very top left of the window, name it &quot;child_main&quot; and use the &quot;Fill Window&quot; button. Also set it's anchors to Top Left and Bottom Right.&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
&lt;br&gt;
Now we have the basis of our main window done. Now we need to make two new windows in the interface, we're going to set them their ids &quot;pane_splash&quot; and &quot;pane_main&quot; respectively, do this now. Remember to check the &quot;This is a pane&quot; checkbox.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Setting up your splash pane&lt;/b&gt;:&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;Edit the pane and set it's background image to our splash screen image.&lt;br&gt;&lt;/li&gt;
&lt;li&gt;Add a button to the splash pane. Give it the ID &quot;button_new_character&quot; and set it's text to &quot;New Character&quot;. Change the button type to &quot;Push Box&quot; and check the box &quot;Flat&quot;. Then set it's command to &quot;NewCharacter&quot;. Be sure to set any background images necessary.&lt;br&gt;&lt;/li&gt;
&lt;li&gt;Copy the above button and past it two more times. Editing the values of the pasted buttons to &quot;button_load_character&quot;, &quot;button_load_quit&quot; and add their respective text values and commands.&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Setting up the main pane&lt;/b&gt;:&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;Add an output control to the pane and set it's id &quot;output_default&quot; and check the &quot;default&quot; check box. Resize it to take up a majority of the window and set it's anchors to &quot;Top Left&quot; and &quot;Bottom Right&quot;&lt;br&gt;&lt;/li&gt;
&lt;li&gt;Add an input control to the pane and set it's id to &quot;input_default&quot; and check the default check box. Resize it to take up the minority of the bottom of the pane and set it's anchors to &quot;Bottom Left&quot; and &quot;Bottom Right&quot;.&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
&lt;br&gt;
Now we have our splash screen and main pane done.&lt;br&gt;
&lt;br&gt;
&lt;a href='http://www.byond.com/members/DMRC/files/tiberath/professional/entry/professional_design_1%2D02.png' rel=&quot;thumbnail&quot;&gt;&lt;img src='http://www.byond.com/members/DMRC/files/tiberath/professional/entry/professional_design_1%2D02.png' width='380' height='240'&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
Now it's time to write the code for this little beauty. We'll need two code files (well, one, but I believe in being neat). These will be named &quot;datum_entry.dm&quot; and &quot;client&quot;. Each one reflects what they're going to contain. &quot;datum_entry.dm&quot; will contain the code to make this splash screen stuff work and &quot;client.dm&quot; will contain any code relating to the client.&lt;br&gt;
&lt;br&gt;
To setup the code files, they'll look like this:&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
&lt;span class=&quot;dmcomment&quot;&gt;// client.dm&lt;/span&gt;&lt;br&gt;client&lt;br&gt;    New()&lt;br&gt;        . = ..()&lt;br&gt;&lt;br&gt;&lt;span class=&quot;dmcomment&quot;&gt;// datum_entry.dm&lt;/span&gt;&lt;br&gt;player_entry&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;verb&lt;/span&gt;&lt;br&gt;        NewCharacter()&lt;br&gt;        &lt;br&gt;        LoadCharacter()&lt;br&gt;        &lt;br&gt;        QuitGame()
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
For starters, we need to edit the client file so they can view the splash screen and set the proper window specifics as we want. To do this, we'll use winset(). For starters, we don't want the user to resize the window, nor do we want it to have a title bar, a status bar, any menus or any macros. We also want the user to have access to the verbs we made (or will make) for player entry.&lt;br&gt;
&lt;br&gt;
This is all pretty basic stuff:&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
client&lt;br&gt;    New()&lt;br&gt;        . = ..()&lt;br&gt;        winset(src, null, &lt;span class=&quot;dmstring&quot;&gt;{&amp;quot;&lt;br&gt;            window_default.child_main.left  = &amp;quot;pane_splash&amp;quot;;&lt;br&gt;            window_default.can-resize       = &amp;quot;false&amp;quot;;&lt;br&gt;            window_default.statusbar        = &amp;quot;false&amp;quot;;&lt;br&gt;            window_default.titlebar     = &amp;quot;false&amp;quot;;&lt;br&gt;            window_default.macro        = null;&lt;br&gt;            window_default.menu         = null&lt;br&gt;        &amp;quot;}&lt;/span&gt;)&lt;br&gt;        src.verbs += typesof(/player_entry/&lt;span class=&quot;dmkeyword&quot;&gt;verb&lt;/span&gt;)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
Now we want to configure the datum_entry.dm to handle the logins of player mobs and whatnot. As well as change the splash screen. Character handling comes in Part 2 of this series, so we can pretty much skip this part and just use some generic interface altering code.&lt;br&gt;
&lt;br&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
player_entry&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;verb&lt;/span&gt;&lt;br&gt;        NewCharacter()&lt;br&gt;            generic_interface_changing_code(usr.client)&lt;br&gt;        &lt;br&gt;        LoadCharacter()&lt;br&gt;            generic_interface_changing_code(usr.client)&lt;br&gt;            &lt;br&gt;        QuitGame()&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;del&lt;/span&gt; usr&lt;br&gt;        &lt;br&gt;&lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;    generic_interface_changing_code(client/C)&lt;br&gt;        winset(C, null, &lt;span class=&quot;dmstring&quot;&gt;{&amp;quot;&lt;br&gt;            window_default.child_main.left  = &amp;quot;pane_main&amp;quot;;&lt;br&gt;            window_default.can-resize       = &amp;quot;true&amp;quot;;&lt;br&gt;            window_default.statusbar        = &amp;quot;true&amp;quot;;&lt;br&gt;            window_default.titlebar     = &amp;quot;true&amp;quot;;&lt;br&gt;            window_default.macro        = &amp;quot;macro&amp;quot;;&lt;br&gt;            window_default.menu         = &amp;quot;menu&amp;quot;;&lt;br&gt;        &amp;quot;}&lt;/span&gt;)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
When this is executed, we get the following result:&lt;br&gt;
&lt;a href='http://www.byond.com/members/DMRC/files/tiberath/professional/entry/professional_design_1%2D03.png' rel=&quot;thumbnail&quot;&gt;&lt;img src='http://www.byond.com/members/DMRC/files/tiberath/professional/entry/professional_design_1%2D03.png' width='380' height='240'&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
Both the New Character and Load Character buttons do the same thing at the moment, mostly because I wanted to beak this tutorial up into parts.&lt;br&gt;
&lt;br&gt;
Now you have a basic understanding of writing a splash screen in BYOND. Your tasks for the end of this lesson is a rather simple one: Centre the window. Who ever heard of a splash screen appearing in some random place on the users screen? As such, your job is to centre the window using whatever means you deem necessary and wherever you find necessary.&lt;br&gt;
&lt;br&gt;
Part 2 will contain methods to handle character creation. For a clue at what I'm getting at, think of every game that uses input() to create characters, and imagine how much you hated that process.</description>
        </item>
                <item>
            <title>Introducing dta_admin</title>
            <link>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=90361</link>
            <guid>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=90361</guid>
            <pubDate>Mon, 25 Jan 2010 21:30:38 +0000</pubDate>
            
            <comments>http://www.byond.com/members/DreamMakers?command=view_comments&amp;post=90361#comments</comments>
            
            <description>I've been lurking in the shadows for quite some time but I believe it's time to come forward with a new initiative: creating a new system to help administrate your game.&lt;br&gt;
&lt;br&gt;
The goal of this library is to replace the old &quot;s_admin&quot; by Spuzzum which was made in the stone age, back when we were ecstatic that we could play MIDI files and we were happy if we could find a Javascript exploit for our browser windows.&lt;br&gt;
&lt;br&gt;
&lt;h1&gt;Introducing dta_admin&lt;/h1&gt;
&lt;br&gt;
&lt;br&gt;
&lt;center&gt;&lt;img width=&quot;527&quot; height=&quot;245&quot; src=&quot;http://www.byond.com/members/AndroidData/files/2010%2D01/AndroidData%2D0003/adminpanel.PNG&quot;&gt;&lt;br&gt;&lt;/center&gt;
&lt;br&gt;
&lt;br&gt;
dta_admin is a new library created and maintained by me. It aims to create an easy-to-use, extensible administrator panel so you can focus on your game instead of having to finish a system most of your players won't ever get to see apart from perhaps the trolls.&lt;br&gt;
&lt;br&gt;
What makes dta_admin so different from any other admin library created is that it's built for BYOND 4.0 and it's modular, meaning you can extend its functionality easily.&lt;br&gt;
&lt;br&gt;
&lt;h1&gt;Modules&lt;/h1&gt;
&lt;br&gt;
dta_admin starts out with a simple &quot;show panel&quot; verb. This brings up a panel which - if no modules are present - will appear to be empty.&lt;br&gt;
&lt;br&gt;
However it is with the modules that this library gains its true power. You can define new modules &lt;em&gt;within your project&lt;/em&gt; without ever having to touch the the libraries' code. Granted, this is the bonafide intention of any good library, but I haven't seen any libraries around for BYOND4+ that allow you to administrate your game &lt;em&gt;and&lt;/em&gt; allow you to extend it easily for whatever you've got cooked up in that game of yours.&lt;br&gt;
&lt;br&gt;
Not only can you define modules for your project, but you can also help out by creating extensions (modules) that can be implemented in future versions of dta_admin. Not only can you extend the library for your own game, but you can also help &lt;s&gt;me&lt;/s&gt; the community by &lt;s&gt;doing my work for me&lt;/s&gt; writing useful modules.&lt;br&gt;
&lt;br&gt;
&lt;h1&gt;Features&lt;/h1&gt;
&lt;br&gt;
The basics of the library work: you can create modules, mess with permissions and there exists a few samples to help you get started.&lt;br&gt;
&lt;br&gt;
However the library does not have a lot of modules yet, and that's where you come in: if you're feeling up to it, you may want to help out writing modules for this library to make it even better!&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.byond.com/developer/AndroidData/dta_admin&quot;&gt;See the hub entry of this library at hub://AndroidData.dta_admin!&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;http://www.byond.com/members/AndroidData/files/dta_admin.htm&quot;&gt;Documentation for dta_admin&lt;/a&gt;</description>
        </item>
                <item>
            <title>Distributing your game outside of BYOND.</title>
            <link>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=90318</link>
            <guid>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=90318</guid>
            <pubDate>Sat, 23 Jan 2010 06:09:58 +0000</pubDate>
            
            <comments>http://www.byond.com/members/DreamMakers?command=view_comments&amp;post=90318#comments</comments>
            
            <description>So you've finally made your game, what a feeling of triumph you must have burning deep inside you. With your game complete, you're ready to distribute it to the masses of potentially interested players both inside, and outside of BYOND.&lt;br&gt;
&lt;br&gt;
You might remember another article by one cunning young programmer entitled: &quot;&lt;a href='http://www.byond.com/members/DreamMakers?command=view_post&amp;post=82099'&gt;Get a hold of your target audience&lt;/a&gt;&quot;. Since that covered methods of gaining interest in your game within the BYOND site, lets discuss ways of getting people outside of BYOND to be interested.&lt;br&gt;
&lt;br&gt;
As of BYOND &lt;a href='http://www.byond.com/docs/notes/461.html'&gt;461&lt;/a&gt;, we've been able to distribute BYOND without the installation of the program, but undoubtedly, a lot of people have been asking how to do that. So let's discuss this now.&lt;br&gt;
&lt;br&gt;
First and foremost, the release notes say if we place a folder named &quot;byond&quot; in our distribution, the program will default to that. So lets set up out folder. Go to your desktop and make a new folder with the same name as your game. Then download and unzip &lt;a href='http://www.byond.com/download/build/462.1057_byond.zip'&gt;the latest BYOND zip&lt;/a&gt;. Cut the &quot;byond&quot; folder from the zip location, and paste it into your new folder. Now we have the game folder ready.&lt;br&gt;
&lt;br&gt;
&lt;div style='text-align: center;'&gt;&lt;img src='http://files.byondhome.com/DMRC/tiberath/distribution_outside/001.png'&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
Back in Dream Maker, we need to prepare our game. First, we need to go to &quot;Build&quot; then &quot;Make EXE&quot;. By default the executable will be the same name as your .DME file, so there's no need to change that. The Hub/Command ID is what we need to focus on.&lt;br&gt;
&lt;br&gt;
Seeing as we're distributing outside of BYOND, chances are, none (or very, very few) of the people we hand the game out too will have a BYOND Key. With this in mind, first we need to set the Hub/Command ID to the name of our .DMB file. In my case, I'll link it to &quot;file://MyGame.dmb&quot;. Then, we need to append ##guest. This will deliberately bypass the BYOND Pager, and automatically log the user in as a guest. If you want to add a touch of professionalism to it, you can add an Icon file to the executable. (The icon files are limited to .ICO. If you don't have a converter or don't wish to look for one, you can use &lt;a href='http://www.convertico.com/'&gt;this handy tool&lt;/a&gt; to convert from PNG to ICO via a web interface, neat yeah?)&lt;br&gt;
&lt;br&gt;
&lt;div style='text-align: center;'&gt;&lt;img src='http://files.byondhome.com/DMRC/tiberath/distribution_outside/002.png'&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
Once you've received the message confirming your .EXE was built, we need to copy the necessary files out of our game folder (.exe, .dmb and .rsc). We'll paste these in the new folder we made on our desktop.&lt;br&gt;
&lt;br&gt;
&lt;div style='text-align: center;'&gt;&lt;img src='http://files.byondhome.com/DMRC/tiberath/distribution_outside/003.png'&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
There, now we have everything we need to freely distribute our game to users who don't have BYOND installed. All you have to do is Zip the folder, and send it in the direction of people who might be interested.&lt;br&gt;
&lt;br&gt;
&lt;div style='text-align: center;'&gt;&lt;img src='http://files.byondhome.com/DMRC/tiberath/distribution_outside/004.png'&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
For the fun of it, I've released the &lt;a href='http://www.byond.com/members/DMRC/files/tiberath/distribution_outside/MyGame.zip'&gt;zipped version of my test project&lt;/a&gt;. Try it on a computer that doesn't have BYOND installed and see how you fair. =)&lt;br&gt;
&lt;br&gt;
--&lt;br&gt;
&lt;br&gt;
Make EXE also has a few other tricks up it's sleeve. You're not limited to just distributing the DMB and RSC of your game for the user to play locally. The user is also able to play on your 24/7 server (if you have one). Provided of course your game allows the use of guest keys.&lt;br&gt;
&lt;br&gt;
To do this, just change &quot;file://MyGame.dmb##guest&quot; to &quot;byond://server_ip:port##guest&quot;. This also removes the need for you to distribute the DMB and RSC with your executable (you'll still need the byond folder, however). There's no sense in including the host files if the user isn't going to need them, right?&lt;br&gt;
&lt;br&gt;
--&lt;br&gt;
&lt;br&gt;
For other tips and tricks concerning Make EXE, you can review the article &lt;a href='http://www.byond.com/members/DreamMakers?command=view_post&amp;post=45444'&gt;A Beginners' Guide to Publishing BYOND Games&lt;/a&gt;. Which contains a list and description of all possible appendices to the command URL. (##local, ##host, ##hub, ##remote, ##live, ##info, ##guest and ##version=X).</description>
        </item>
                <item>
            <title>Your First Isometric World</title>
            <link>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=85501</link>
            <guid>http://www.byond.com/members/DreamMakers?command=view_post&amp;post=85501</guid>
            <pubDate>Wed, 11 Nov 2009 22:22:14 +0000</pubDate>
            
            <comments>http://www.byond.com/members/DreamMakers?command=view_comments&amp;post=85501#comments</comments>
            
            <description>&lt;p&gt;Isometric is a type of projection that gives the illusion of 3D without actually using true 3D. BYOND lets you make isometric games while taking out a lot of the hassle of determining how to arrange the graphics and draw them in the right order. That's a big help because the math and logic involved can be complex, and it just gets in the way of making the best game you can.&lt;/p&gt;
&lt;p&gt;In BYOND's isometric system, north points toward the upper right of the player's screen, and east points to the lower right. It's as if the whole map was rotated 45&amp;deg; clockwise, and then instead of looking at it straight down you're looking at it at only a slight downward angle of 30&amp;deg;. This makes every map square into a squashed diamond shape. BYOND uses 2:1 isometric graphics, meaning that the angle the map is &quot;tilted&quot; makes every diamond half as tall as it is wide.&lt;/p&gt;
&lt;p&gt;The first step to using isometric graphics is to set up your project by defining world.map_format and world.icon_size.&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
world&lt;br&gt;    map_format = ISOMETRIC_MAP&lt;br&gt;    icon_size = 64
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;I picked an icon_size of 64, which means we'll be using 64&amp;times;64-pixel icons, because it's a good size to work with in isometric. The width of the diamond tiles is always the same as the width of the icons we use, so each diamond will be 64&amp;times;32, and there will be 32 pixels left over at the top of each icon for vertical structures. Whatever size you choose for an isometric game, be sure the width is always a multiple of 4--otherwise the math will be subject to some rounding errors and you'll see seams between the tiles.&lt;/p&gt;
&lt;p&gt;In Dream Maker, create a new icon and give it a size of 64&amp;times;64. Create a new pixmap, and choose a color for the base tile, let's say a nice shade of gray. Then you'll see a menu option called &lt;b&gt;Icon | Create isometric tile&lt;/b&gt;. Select that, and you'll see a diamond shape appear at the bottom half of the icon.&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;&lt;img width=&quot;128&quot; height=&quot;128&quot; src=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_floor1.png&quot;&gt; &lt;img width=&quot;128&quot; height=&quot;128&quot; src=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_floor2.png&quot;&gt;&lt;/div&gt;
&lt;p&gt;Take a look at that diamond and you'll notice a few things. The pixels on the very left and very right are blank. This is because of the way the diamonds will be fitted together. The lines along the edges however follow a perfect 2:1 ratio, with 2 pixels horizontally for every 1 pixel vertically. Select the line tool and then draw in some lighter and darker lines along the edges for shading. This will be a good base tile.&lt;/p&gt;
&lt;p&gt;Now let's create a new icon for a wall. Let's say we want the walls to be red blocks, about 24 pixels high. Make a new icon and follow the same steps to make a plain diamond shape, in a light shade of red. Now use the selection tool to move that up to near the top of the icon. There should be 8 pixels of space above the diamond and 24 below. This will be the top of the wall. Hit Ctrl+X to cut this image and put it on the clipboard. Now choose a neutral color like white and create a diamond again, but leave it where it is. Hit Ctrl+V to paste the red diamond back over it.&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;&lt;img width=&quot;128&quot; height=&quot;128&quot; src=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_wall1.png&quot;&gt; &lt;img width=&quot;128&quot; height=&quot;128&quot; src=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_wall2.png&quot;&gt;&lt;/div&gt;
&lt;p&gt;Next, choose a medium red and draw a vertical line from just to the left of the top diamond (1,40) to just left of the bottom diamond (1,17). Draw another line like this at just left of the center, from 32,1 to 32,24. Switch to the fill tool and fill in everything between the two vertical lines so there's a solid color face there. Now repeat the process on the right, in a darker shade of red. Bingo; we have a red block. You can decorate it further if you like.&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;&lt;img width=&quot;128&quot; height=&quot;128&quot; src=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_wall3.png&quot;&gt; &lt;img width=&quot;128&quot; height=&quot;128&quot; src=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_wall4.png&quot;&gt;&lt;/div&gt;
&lt;p&gt;If you're wondering why the wall has the far left and far right pixels filled in, which wasn't the case for the floor or for the top of the wall, it's because gaps would show up if two of these walls were right next to each other. Notice that by doing it this way, the left side of the block is 32 pixels wide, as is the right side. By placing two walls next to each other they should form a solid unbroken surface.&lt;/p&gt;
&lt;p&gt;Finally we'll need a mob icon, so just draw a circle about 32&amp;times;32 and put it in the center of the icon. If it's 16 pixels from the bottom it will look like it's touching the ground at the middle of the diamond tile, which is perfect. Add some quick smiley features and there's a basic mob icon.&lt;/p&gt;
&lt;p&gt;Now we can define some objects in the world.&lt;/p&gt;
&lt;div class=&quot;dmcode&quot;&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class=&quot;dmcode&quot;&gt;
turf&lt;br&gt;    icon = &lt;span class=&quot;dmstring&quot;&gt;'floor.dmi'&lt;/span&gt;&lt;br&gt;&lt;br&gt;turf/wall&lt;br&gt;    density = 1&lt;br&gt;    icon = &lt;span class=&quot;dmstring&quot;&gt;'wall.dmi'&lt;/span&gt;&lt;br&gt;&lt;br&gt;mob&lt;br&gt;    icon = &lt;span class=&quot;dmstring&quot;&gt;'player.dmi'&lt;/span&gt;&lt;br&gt;    pixel_step_size = 16
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;That's enough to get started, so let's build a map. Create a new map--nothing fancy, maybe just a 10&amp;times;10&amp;times;1. You'll notice the map editor has already laid out everything in isometric form--that's because world.map_format was set to ISOMETRIC_MAP earlier. Plunk down some of those red walls, then hit Ctrl+R to compile and run your project.&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;&lt;a rel=&quot;thumbnail&quot; href=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_map.png&quot;&gt;&lt;img width=&quot;320&quot; height=&quot;176&quot; src=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_map.png&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Try moving around for a bit. Probably the first thing you'll see is that hitting the up arrow actually moves your mob up and to the right; that's normal. Remember, that's the way north faces, and you're moving north. If this seems a little weird at first, don't worry about it--you and your players will get used to this quickly, and this control scheme has actually been around since Q*Bert.&lt;/p&gt;
&lt;p&gt;The other thing you'll see that if the mob stands behind a wall, the wall will be drawn in front. This could also seem odd if you're used to thinking top-down, because in a topdown map the lower layers are always drawn behind the higher ones. But in isometric maps, you have to think in three dimensions even though the map isn't truly 3D. Tiles that are nearer to the viewer should always be drawn over tiles that are farther away regardless of their layer, right? So layers only matter for things that are on the same tile.&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;&lt;a rel=&quot;thumbnail&quot; href=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_play.png&quot;&gt;&lt;img width=&quot;320&quot; height=&quot;160&quot; src=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_play.png&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Moving around in this system should look pretty fluid, with one exception. If you move diagonally behind a wall, you'll see your mob temporarily drawn on top of the wall.&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;&lt;a rel=&quot;thumbnail&quot; href=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_layer_issue.png&quot;&gt;&lt;img width=&quot;320&quot; height=&quot;160&quot; src=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_layer_issue.png&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Like I said at the beginning, BYOND is only giving you an illusion of 3D. In order to draw everything properly it has to make some calculations and educated guesses about which order to draw tiles in. Nearer tiles get drawn on top of tiles that are further away, but what happens when your mob is between two tiles? In those cases, it has to be drawn in front of the nearer tile so that the floor of the near tile won't cover it up. So the reason you see the mob on top of the wall while moving diagonally behind it is that, as far as BYOND's isometric engine is concerned, the mob is temporarily on the same tile as the wall.&lt;/p&gt;
&lt;p&gt;There are two ways to deal with this. One is to not allow players to &quot;cut corners&quot;. After all if you did this in a topdown game, mobs would temporarily appear on top of wall icons while squeezing through a corner, and that looks bad too. Another way is to simply give the wall a layer that's higher than the mob. The layer will matter only when the mob and the wall are on the same tile, so it will cover up those visual gaffes nicely.&lt;/p&gt;
&lt;p&gt;With a simple 10&amp;times;10 map, the whole thing should show up on your map at any given time, since by default world.view is 6, which covers 13&amp;times;13 tiles. For bigger maps, world.view or client.view (whichever you use) will determine the &lt;i&gt;minimum&lt;/i&gt; number of tiles you'll see, with other tiles filling in to pad out the whole viewing area. This means two things: You can probably get away with using a smaller world.view, and if you use a HUD it's going to be smaller than it would be in a topdown game. The HUD is only as big as it has to be. In this tutorial the map is 10x10 and fills the whole screen. That makes a diamond 640 pixels wide, and 320 pixels high--plus there will be an extra 32 pixels for vertical stuff like the walls, so it's 352 pixels high in total. Every icon in the HUD is a 64&amp;times;64 tile, so the HUD will be 10 tiles wide, and 6 tiles high. The Reference has a formula for calculating this if you need to, but with a HUD you can always use a relative screen_loc like &quot;EAST,NORTH-1&quot;, so for most games you won't have to worry about that.&lt;/p&gt;
&lt;p&gt;Now you know the basics of making an isometric game. There are more issues out there to explore, like how to handle big icons (and how not to), and the fact that you can use pixel_z to give your icons some vertical height. But the basics covered here should be enough for you to make a board game, strategy game, or RPG without any trouble. If you want to learn more about making isometric graphics, visit the &lt;a href=&quot;http://www.byond.com/members/PixelArt&quot;&gt;BYOND Art Society&lt;/a&gt; or read some of the many pixel art tutorials available online.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;The &lt;a href=&quot;http://www.byond.com/members/DreamMakers/files/2009%2D11/LummoxJR%2D0001/iso_tutorial_src.zip&quot;&gt;source files&lt;/a&gt; for this tutorial are available to download.&lt;/i&gt;&lt;/p&gt;</description>
        </item>
            
    </channel>
</rss>


