<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0">
    <channel>
        <title>Popisfizzy's site</title>
        <link>http://www.byond.com/members/Popisfizzy</link>
        <description></description>
        <lastBuildDate>Sat, 11 Feb 2012 04:41:52 +0000</lastBuildDate>
        <language>en-us</language>
    
                <item>
            <title>The Art of Code: Namespaces and Inheritance</title>
            <link>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=287671</link>
            <guid>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=287671</guid>
            <pubDate>Fri, 10 Feb 2012 23:16:42 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Popisfizzy?command=view_comments&amp;post=287671#comments</comments>
            
            <description>I'm a programmer. As such, I'm &lt;a href=&quot;http://en.wikipedia.org/wiki/Larry_Wall#Virtues_of_a_programmer&quot;&gt;impatient&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
Many people don't understand the true complexities of programming. There is more to code than just writing code. Programming is a unique field, a crossroads that few other fields dare to travel: It's where mathematics meets engineering meets art. A good programmer must know the mathematics of what they're doing, of how to analyze algorithms to understand what works best for them. A good programmer must be a knowledgeable engineer, able to write robust, reliable, efficient code in a way, and documented in a way, that is precise, concise, and clear. A good programmer must be an artist, able to write code that is elegant, extensible, maintainable, and usable. The first and second are clear to many users. But what about the art of programming?&lt;br&gt;
&lt;br&gt;
I am impatient. People who do not understand good design principles, people who can not write elegant code, extensible code, maintainable code, useable code. They annoy me. People who can not &lt;i&gt;design&lt;/i&gt; good code. And, thus, I grow weary of helping them, sometimes going so far as to just outright stop. But this shouldn't be so. There should be no reasons why the average user of BYOND, the average DM programmer, can not write code that implements good design principles. The Art of Code is my attempt to help users with this, to understand the art of programming, and the beauty of code. These tutorials will be aimed at a slightly more-advanced audience than my So You Want To Program tutorials, but will be written as clear as possible nonetheless. So, let's begin, shall we?&lt;br&gt;
&lt;br&gt;
My first tutorial on this series is going to focus on namespaces and inheritance as applied to DM. These two language features are dinstinct in most object-oriented programming language, but this isn't so in DM. In fact, the language muddles the two so much that few people recognize the difference that exists. Nonetheless, the distinction is still present, and not even that far from the surface.&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;Inheritance&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
First off, let's discuss inheritance. To most DM programmers, this should be a topic you are already familiar with. Inheritance is one of the main features of object-oriented programming languages. Certain types of programming constructs, called classes, can inherit their features from other classes. The inheriting classes are called subclasses, and the inherited class is called a superclass. For example, below is a typical example of classes and inheritance.&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;
animal&lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;/*&lt;br&gt;     * This defines the animal superclass. We define a few variables and procs for the&lt;br&gt;     * subclasses to use.&lt;br&gt;     */&lt;/span&gt;&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;&lt;br&gt;        hunger&lt;br&gt;        thirst&lt;br&gt;&lt;br&gt;        bathroom&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;        Speak()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// How the animal 'speaks', or vocalizes. Some animals just don't.&lt;/span&gt;&lt;br&gt;&lt;br&gt;        Eat()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// Some animals eat meat, others eat plants. Others do both.&lt;/span&gt;&lt;br&gt;            hunger ++&lt;br&gt;&lt;br&gt;        Drink()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// How the animal drinks. Some sea animals basically do it when they eat.&lt;/span&gt;&lt;br&gt;            thirst ++&lt;br&gt;&lt;br&gt;        Bathroom()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// How the animals uses the bathroom.&lt;/span&gt;&lt;br&gt;            bathroom --&lt;br&gt;&lt;br&gt;        Move()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// How the animal moves.&lt;/span&gt;&lt;br&gt;&lt;br&gt;        Die()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// Called when the animal dies.&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;del&lt;/span&gt; src&lt;br&gt;&lt;br&gt;animal/dog&lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;/*&lt;br&gt;     * A dog is a type of animal, so we'll use it.&lt;br&gt;     */&lt;/span&gt;&lt;br&gt;&lt;br&gt;   Speak()&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;[src]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; barks!&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;br&gt;   Eat(animal/a)&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;[src]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; eats &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[a]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;.&amp;quot;&lt;/span&gt;&lt;br&gt;       a.Die()&lt;br&gt;&lt;br&gt;       ..()&lt;br&gt;&lt;br&gt;  Move()&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;[src]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; walks.&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;br&gt;animal/fish&lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;/*&lt;br&gt;     * A fish is a type of animal, but one quite different from a dog.&lt;br&gt;     */&lt;/span&gt;&lt;br&gt;&lt;br&gt;    Speak()&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// Fish don't really have a vocalization, so nothing happens.&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; null&lt;br&gt;&lt;br&gt;    Eat(animal/a)&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// We have a carniverous fish here.&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;[src]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; eats &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[a]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;.&amp;quot;&lt;/span&gt;&lt;br&gt;        a.Die()&lt;br&gt;&lt;br&gt;        Drink() &lt;span class=&quot;dmcomment&quot;&gt;// It drinks when it eats.&lt;/span&gt;&lt;br&gt;        ..()&lt;br&gt;&lt;br&gt;    Move()&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;[src]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; swims.&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;br&gt;animal/bird&lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;/*&lt;br&gt;     * Another type of animal, different from a fish and a dog.&lt;br&gt;     */&lt;/span&gt;&lt;br&gt;&lt;br&gt;    Speak()&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;[src]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; chirps.&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;br&gt;    Eat(plant/berry)&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// This is a berry-eating bird.&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;[src]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; eats &lt;/span&gt;&lt;span class=&quot;dmbrace&quot;&gt;[berry]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt;&amp;quot;&lt;/span&gt;&lt;br&gt;        berry.Eaten()&lt;br&gt;&lt;br&gt;        ..()&lt;br&gt;&lt;br&gt;    Bathroom()&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;[src]&lt;/span&gt;&lt;span class=&quot;dmstring&quot;&gt; goes to the bathroom on a nice, clean car.&amp;quot;&lt;/span&gt;&lt;br&gt;        ..()
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
And there we have a small example of how inheritance can work in DM. This is the way most people work with, but as we'll see later, this isn't the only option available to DM programmers. It's still simple, and intuitive, but not always the kind of thing we want.&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;Namespaces&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
At first glance, namespaces are a feature that does not appear to be present in DM. Before I go any further, let me explain what a namespace is. Think of a namespace as an abstract kind of 'container' that holds a lot of similar things together. For example, if you have a Gun, maybe you'll have a few different things associated with it. There might be the Gun itself, ammunition, and maybe Magazines or Clips. You could hold all of this together in a Weapons or Guns namespace. Why is this useful? Maybe there is ambiguity in your code. Maybe your code also has other types of magazines, like the kind that you can read, or other kinds of clips, the kind that you can use to hold two things together.&lt;br&gt;
&lt;br&gt;
Without a namespace, this becomes ambiguous. Obviously the Magazine or Clip can't inherit from a Gun. That makes no sense, as they don't share any features with a gun. Thus, what are your options? You could rename them, but that's not a good choice. With namespaces, you can store the Clip and Magazine away under the Guns or Weapons namespace, and you have absolutely no conflict. Your readable Magazine and your holds-things-together Clip can exist and there doesn't have to be any conflict whatsoever.&lt;br&gt;
&lt;br&gt;
But as I said, it doesn't appear that BYOND has namespaces. So, why am I talking about this at all, then? Well, the thing is, BYOND does have them. In fact, you use them all the time. It's just that they are not immediately obvious. In most other programming languages, the separation between inheritance and namespaces are immediately apparent, because the way they are both handled is entirely different. BYOND, though, combines both of these things in its typepath system. A typepath, by default, indicates inheritance, but it is &lt;i&gt;not the same inheritance&lt;/i&gt;. In fact, inheritance in BYOND can be overwritten. How?&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;The &lt;tt&gt;parent_type&lt;/tt&gt; Variable&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
You may have used the &lt;tt&gt;&lt;a href=&quot;http://www.byond.com/docs/ref/index.html&quot;&gt;parent_type&lt;/a&gt;&lt;/tt&gt; variable before. Most people use it to see what the typepath of the parent is. For example, in our example above, the &lt;tt&gt;parent_type&lt;/tt&gt; of each &lt;tt&gt;/animal/dog&lt;/tt&gt;, &lt;tt&gt;/animal/fish&lt;/tt&gt;, and &lt;tt&gt;/animal/bird&lt;/tt&gt; is just &lt;tt&gt;/animal&lt;/tt&gt;. When your code is compiled, this variable is automatically set to what the superclass is. The thing is, this isn't the only way to use this variable, and in fact this is more of a minor way of using it.&lt;br&gt;
&lt;br&gt;
Here's the best thing about the &lt;tt&gt;parent_type&lt;/tt&gt; variable: It can be set by the programmer at compile time, and this changes what the class inherits from. Thus, the programmer has the ability to entirely change the default method of inheritance in DM. Why is this useful? Because it can simultaneously be used to create namespaces. As I mentioned above, the notions of inheritance and namespaces in DM are tied together through the typepath system. Without explicitly overriding it, when you have something like &lt;tt&gt;/foo/bar&lt;/tt&gt;, by default &lt;tt&gt;/bar.parent_type&lt;/tt&gt; = /foo. But, by using the &lt;tt&gt;parent_type&lt;/tt&gt; variable it is possible to turn &lt;tt&gt;/foo&lt;/tt&gt; into a namespace. In fact, unlike any other programming language that I know of, &lt;tt&gt;/foo&lt;/tt&gt; simultaneously becomes both a class and a namespace.&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;Implementing Namespaces&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
Now, back to the gun example I mentioned earlier. How would you implement this in DM? Below is one possible way.&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;
gun&lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;/*&lt;br&gt;     * Here we implement the gun namespace/class. It inherits from /obj, but it becomes a top-&lt;br&gt;     *level class. Thus, to create a new gun object we just have to wrote new /gun. It is&lt;br&gt;     * not necessary to know that the /gun&lt;br&gt;     * is a type of /obj, and thus this information can be left out, if a user&lt;br&gt;     * so wishes.&lt;br&gt;     */&lt;/span&gt;&lt;br&gt;&lt;br&gt;    parent_type = /obj&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// The name of the gun.&lt;/span&gt;&lt;br&gt;        name&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// The type of ammunition the gun uses.&lt;/span&gt;&lt;br&gt;        ammunition_type&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// The type of magazine the gun uses.&lt;/span&gt;&lt;br&gt;        magazine_type&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// The magazine currently being used. May be switched out.&lt;/span&gt;&lt;br&gt;        gun/magazine/magazine&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// The mob holding the gun.&lt;/span&gt;&lt;br&gt;        mob/holder&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;        Load(magazine/m)&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(!istype(m))&lt;br&gt;                &lt;span class=&quot;dmcomment&quot;&gt;// If it's not at all a magazine type, just return.&lt;/span&gt;&lt;br&gt;                &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 0&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(!istype(m, src.magazine_type))&lt;br&gt;                &lt;span class=&quot;dmcomment&quot;&gt;// If it's a magazine, but the wrong kind, temporarily Jam() the gun.&lt;/span&gt;&lt;br&gt;                src.Jam()&lt;br&gt;                &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 0&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(!istype(m.ammunition, src.ammunition_type))&lt;br&gt;                &lt;span class=&quot;dmcomment&quot;&gt;// If it's the wrong type of ammunition, jam the gun.&lt;/span&gt;&lt;br&gt;                src.Jam()&lt;br&gt;                &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 0&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// If everything goes well, load the magazine.&lt;/span&gt;&lt;br&gt;            src.magazine = m&lt;br&gt;            src.magazine.gun = src&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 1&lt;br&gt;&lt;br&gt;        Jam()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// Not actually implementing this, as the way it jams could really vary, and&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// it isn't really necessary to actually implement it.&lt;/span&gt;&lt;br&gt;&lt;br&gt;        Fire(angle)&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// Attempts to fire a bullet in the given angle. This can be overwritten to,&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// for example, result in an inaccurate or unreliable gun.&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; src.magazine.Fire(angle)&lt;br&gt;&lt;br&gt;    magazine&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;/*&lt;br&gt;         * Now we implement the magazine.&lt;br&gt;         */&lt;/span&gt;&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// As with /gun, /gun/magazine derives from /obj.&lt;/span&gt;&lt;br&gt;        parent_type = /obj&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// The type of ammunition the magazine stores. Just store a&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// typepath here.&lt;/span&gt;&lt;br&gt;            gun/ammunition/ammunition&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// The gun the magazine is loaded into.&lt;/span&gt;&lt;br&gt;            gun/gun&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// The amount a magazine holds. Should be an integer greater than zero.&lt;/span&gt;&lt;br&gt;            max_size&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// The amount currently being held.&lt;/span&gt;&lt;br&gt;            size&lt;br&gt;&lt;br&gt;        New()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// Create a new ammunition, as indicated by src.ammunition, and set&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// src as its magazine.&lt;/span&gt;&lt;br&gt;            src.ammunition = &lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt; src.ammunition(src)&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; ..()&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;            Reload()&lt;br&gt;                &lt;span class=&quot;dmcomment&quot;&gt;// Reloads the magazine.&lt;/span&gt;&lt;br&gt;&lt;br&gt;                &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(size &amp;lt; max_size)&lt;br&gt;                    src.size ++&lt;br&gt;                    &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 1&lt;br&gt;&lt;br&gt;                &lt;span class=&quot;dmkeyword&quot;&gt;else&lt;/span&gt;&lt;br&gt;                    &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 0&lt;br&gt;&lt;br&gt;            Fire(angle)&lt;br&gt;                &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(src.size &amp;gt; 0)&lt;br&gt;                    &lt;span class=&quot;dmcomment&quot;&gt;// The amount of ammunition in the magazine.&lt;/span&gt;&lt;br&gt;                    src.size --&lt;br&gt;&lt;br&gt;                    &lt;span class=&quot;dmcomment&quot;&gt;// The bullet fires.&lt;/span&gt;&lt;br&gt;                    &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; src.ammunition.Fire(angle)&lt;br&gt;&lt;br&gt;                &lt;span class=&quot;dmkeyword&quot;&gt;else&lt;/span&gt;&lt;br&gt;                    &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 0&lt;br&gt;&lt;br&gt;    ammunition&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;/*&lt;br&gt;         * And now we implement the ammunition.&lt;br&gt;         */&lt;/span&gt;&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// A type of datum. Ammunition only says how to model individual bullets, rather&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// than being something that exists in the world.&lt;/span&gt;&lt;br&gt;        parent_type = /datum&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// The damage the bullet does.&lt;/span&gt;&lt;br&gt;            damage&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// The stability of the bullet. How much it wobbles in the air. A percentage.&lt;/span&gt;&lt;br&gt;            stability&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// The magazine the gun is attached to.&lt;/span&gt;&lt;br&gt;            gun/magazine/magazine&lt;br&gt;&lt;br&gt;        New(gun/magazine/magazine)&lt;br&gt;            src.magazine = magazine&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;            Fire(angle)&lt;br&gt;                &lt;span class=&quot;dmcomment&quot;&gt;// Whatever happens here. Presumably, a bullet object would be&lt;/span&gt;&lt;br&gt;                &lt;span class=&quot;dmcomment&quot;&gt;// created (perhaps as a /gun/bullet, or an /obj/bullet, or whatever&lt;/span&gt;&lt;br&gt;                &lt;span class=&quot;dmcomment&quot;&gt;// solution works best).&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
And here we have a very basic namespace for guns, with a top-level &lt;tt&gt;/gun&lt;/tt&gt; object and a few classes in the namespace that handle actually firing and etc. the gun. Note that neither &lt;tt&gt;/gun/magazine&lt;/tt&gt; or /gun/ammunition are subclasses of &lt;tt&gt;/gun&lt;/tt&gt;: &lt;tt&gt;/gun/magazine&lt;/tt&gt; is a sublcass of &lt;tt&gt;/obj&lt;/tt&gt; and &lt;tt&gt;/gun/ammunition&lt;/tt&gt; is a subclass of &lt;tt&gt;/datum&lt;/tt&gt;. While it may be confusing at first, and is an example of BYOND's muddling of the difference between inheritance and namespaces in its typepath system, it can result in far better organization of code. Below is one potential example of how we could utilize this namespace to implement a weapon.&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;
gun/RPGLauncher&lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;/*&lt;br&gt;     * This implement a Rocket Propelled Grenade launcher.&lt;br&gt;     */&lt;/span&gt;&lt;br&gt;&lt;br&gt;    name = &lt;span class=&quot;dmstring&quot;&gt;&amp;quot;SP4NK3R&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;br&gt;    ammunition_type = /gun/ammunition/RocketPropelledGrenade&lt;br&gt;    magazine_type = /gun/magazine/RPGMagazine&lt;br&gt;&lt;br&gt;    Fire(angle)&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(prob(5))&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// The gun is kind of unreliable. There is a 5% chance that the gun&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// will explode rather than fire an RPG.&lt;/span&gt;&lt;br&gt;            src.Explode()&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; 0&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;else&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;return&lt;/span&gt; ..()&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;proc&lt;/span&gt;&lt;br&gt;        Explode()&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// Do explosion stuff here.&lt;/span&gt;&lt;br&gt;&lt;br&gt;gun/magazine/RPGMagazine&lt;br&gt;&lt;br&gt;    max_size = 2&lt;br&gt;    ammunition = /gun/ammunition/RocketPropelledGrenade&lt;br&gt;&lt;br&gt;gun/ammunition/RocketPropelledGrenade&lt;br&gt;&lt;br&gt;    damage = 50&lt;br&gt;&lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;// 85% stable.&lt;/span&gt;&lt;br&gt;    stability = 0.85&lt;br&gt;&lt;br&gt;    Fire(angle)&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// Fires a new rocket in the angle indicated.&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;new&lt;/span&gt; /bullet/rocket(angle, src.magazine.gun.holder.loc, damage, stability)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
And, with this model would could extend the &lt;tt&gt;/gun/magazine/RPGMagazine&lt;/tt&gt; class, to create subclasses that are special types of RPGs. For example, maybe there is a Napalm RPg or an Acid RPG. These would, presumably, still exist in the gun namespace to avoid any conflict outside it.&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;Summary&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
In conclusion, BYOND's typepath system is simply a highly-complex namespace system. The system &lt;i&gt;can&lt;/i&gt; influence inheritance and such hierarchy, but this is only a default, overwriteable behavior, albeit one that simplifies things a great bit, but one that is not at all necessary. Sometimes, overwriting this behavior is useful, and even necessary, to write elegant, extensible, and easily-maintainable. Namespaces and inheritance are both powerful language features, even more powerful when used together, and while they can be confusing, they can also be one of the most powerful tools for defeating ambiguity and increasing clarity when designing code.&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;Beyond The Tutorial&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
As an aside, note that the typepath system makes it simple for their to be namespaces within other namespaces, allowing there to be a hierarchal system that breakdown differently at each level. This can be useful for extremely complex systems, where things are tied together and where collisions or ambiguity are a very conceivable and real possibility.&lt;br&gt;
&lt;br&gt;
Namespaces are also very useful in libraries. They allow for the possibility of a number of different classes to be packaged under one namespace to avoid annoying and difficult-to-resolve collisions between a library and a user's own code. When a collision occurs, typically the only real solution is for a user to rewrite all of their own code to fix it, which is often more difficult than just implementing the library themselves! This makes namespaces a very useful tool in library development.</description>
        </item>
                <item>
            <title>So You Want A Tutorial: Doors and Teleporation</title>
            <link>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=281611</link>
            <guid>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=281611</guid>
            <pubDate>Wed, 08 Feb 2012 21:00:04 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Popisfizzy?command=view_comments&amp;post=281611#comments</comments>
            
            <description>I'm a programmer. As such, I am &lt;a href=&quot;http://en.wikipedia.org/wiki/Larry_Wall#Virtues_of_a_programmer&quot;&gt;lazy&lt;/a&gt;. I also help people a lot on these forums. But I'm also lazy.&lt;br&gt;
&lt;br&gt;
This is a conundrum. To solve this, I have decided to write a series of tutorials regarding common questions on these forums, so that I can link to them for convenience. See, I already do this quite often, but also quite often I have to expand on the topic. Thus, I wish to make detailed, instructional tutorials that will need little more expansion.&lt;br&gt;
&lt;br&gt;
My first topic is on teleportion, and specifically door-like teleportion. That is, when something steps on a tile and is immediately transported to another place. This is a relatively simple topic, but one that can have numerous errors associated with it, despite the fact there is one well-known, fairly-uniform, simple result.&lt;br&gt;
&lt;br&gt;
To start off, let's look at where things can go wrong.&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;How Not To Do It&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
First off, let's take a look at the wrong way to do it. Below is extremely simple, but it is also wrong in a good number of ways.&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;
turf/Enter(mob/m)&lt;br&gt;    m.loc = locate(4, 30, 1)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
There we go. Simple enough, right? When something tries to enter the turf, their location is to the location at (4, 30, 1). Only two lines, so this seems like a good choice, right? Wrong. In just two lines, I can identify four major flaws: It's not robust, it's not dynamic, it's not easily-modifiable, and it does not follow the interface set out for it.&lt;br&gt;
&lt;br&gt;
What do I mean by robust? I mean it doesn't handle errors well. There are two very simple examples in this code. The first is the assumption that the argument is in fact a mob. While it will also handle well whether it's a mob or an obj, it will typically not handle well for anything else. For example, if somehow a turf or area were to be passed as arguments, this would crash, as their loc variable can not be changed at runtime. Additionally, if it happens that the object at (4, 30, 1) doesn't exist (perhaps the map was changed). This won't cause a runtime error, but it will likely delete the object being moved. If this object happens to be the player's mob, then they'll also be disconnected! Not good.&lt;br&gt;
&lt;br&gt;
What do I mean by not dynamic? In order for this method to work, there has to be a specific object created for every possible door. If you want to go just one block over, for example, to (4, 31, 1), you have to create an entirely new object. This is ridiculous! There is no need for a new type of object for every door that can exist. There must be a better way.&lt;br&gt;
&lt;br&gt;
What do I mean by not easily-modifiable? Well, assume you rearrange your map. Now your old coordinates don't work. You have to go through every object in your code and change their coordinates. On top of that, because it is not dynamic (as mentioned above), you also might have to delete a bunch of objects (if you don't want your code to get bloated).&lt;br&gt;
&lt;br&gt;
Lastly, what do I mean by the code not following the interface set out of it? This is the most difficult to explain. Under the normal system of movement in DM. The &lt;tt&gt;Enter()&lt;/tt&gt; proc should only ever take a movable atom (&lt;tt&gt;/atom/movable&lt;/tt&gt;) and return true or false as to whether it can move to that location. The code within the &lt;tt&gt;Enter()&lt;/tt&gt; function should not actually have any effect on the world, just return true or false as to whether something happened. The &lt;tt&gt;Entered()&lt;/tt&gt; method, instead, should be used when something has successfully entered the turf. This is the interface that BYOND sets out for these procs. Other languages have stricter ways of enforcing an interface, but DM unfortunately does not. Thus, there are a lot of cases of people messing it up. To follow the interface, this type of code should actually be moved into the &lt;tt&gt;Entered()&lt;/tt&gt; function.&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;Getting There&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
Well, now we know a few things. We need to use &lt;tt&gt;Entered()&lt;/tt&gt;. We need to make it more robust and capable of dealing with potential errors. We need to make it more dynamic so we have less useless repetition. We need to make it more easily-modifiable, so that we don't need to go through a lot of work when we want to change something. How can we manage this?&lt;br&gt;
&lt;br&gt;
Well, below is one possible way, which may have occurred to you.&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;
turf&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// The x, y, and z coordinates of the turf you're being&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// transported to.&lt;/span&gt;&lt;br&gt;        to_x&lt;br&gt;        to_y&lt;br&gt;        to_z&lt;br&gt;&lt;br&gt;    Entered(mob/m)&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// We're using Entered() now, to follow DM's interface&lt;/span&gt;&lt;br&gt;        &lt;span class=&quot;dmcomment&quot;&gt;// for movement.&lt;/span&gt;&lt;br&gt;&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(istype(m))&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// Check that m is a mob,&lt;/span&gt;&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(locate(to_x, to_y, to_z) != null)&lt;br&gt;                &lt;span class=&quot;dmcomment&quot;&gt;// If locate moves the player to a valid location,&lt;/span&gt;&lt;br&gt;                &lt;span class=&quot;dmcomment&quot;&gt;// then move them.&lt;/span&gt;&lt;br&gt;&lt;br&gt;                m.loc = locate(to_x, to_y, to_z)
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
This seems like a much better solution, doesn't it? It uses &lt;tt&gt;Entered()&lt;/tt&gt;, so BYOND's movement interface is preserved, we do type checking and value checking to help prevent errors, and we now have variables that allow us to be a bit more dynamic with our objects, keeping down bloat, and it makes it a lot easier to modify a map. Now, instead of setting the coordinates inside the code, we can just use the map editor to edit a turf's &lt;tt&gt;to_x&lt;/tt&gt;, &lt;tt&gt;to_y&lt;/tt&gt;, and &lt;tt&gt;to_z&lt;/tt&gt; variables. The downside is that we're still stuck to our coordinate system, so if we re-arrange the map we might have a lot of coordinate sto change. Still, this seems like it could be the best we could do without getting a lot more complex, doesn't it? Well, not quite. There's a feature of DM that makes this a bit simpler.&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;The &lt;tt&gt;tag&lt;/tt&gt; Variable&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
The &lt;tt&gt;tag&lt;/tt&gt; variable is a special variable in DM that is used in conjunction with the &lt;tt&gt;locate()&lt;/tt&gt; proc. If you set the tag variable of an object, then &lt;tt&gt;locate(tag)&lt;/tt&gt; will return that object. Note that tag can not be set at compile-time, and multiple objects should not have the same tag variable. Thus, using the tag variable we can separate our system from the coordinate sysetm of the map, simplifying re-arranging it.&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;How To Do It&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
Taking all we have, we can now produce the following 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;
turf&lt;br&gt;    &lt;span class=&quot;dmcomment&quot;&gt;// This is the tag of the location we're moving to.&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/moveto_tag&lt;br&gt;&lt;br&gt;    Entered(atom/movable/a)&lt;br&gt;        &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(istype(a))&lt;br&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// This stores the turf we're moving to. Note that tag&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// isn't only on turfs, but all /atom types. Therefore,&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// it's entirely possible that this is not a turf.&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// I do not typecheck here, though, because it is&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// up to the map designer to put a tag on the right&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// object, and they could have a reason for moving&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmcomment&quot;&gt;// the player to a non-turf.&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt;/turf/t = locate(moveto_tag)&lt;br&gt;            &lt;span class=&quot;dmkeyword&quot;&gt;if&lt;/span&gt;(t)&lt;br&gt;                a.loc = t
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
And there we have it. I've changed &lt;tt&gt;mob/m&lt;/tt&gt; to &lt;tt&gt;atom/movable/a&lt;/tt&gt; to allow &lt;tt&gt;/obj&lt;/tt&gt; objects to pass through the door now, too. This gives us the most robust, most dynamic, most easily-modifiable solution that fit's BYOND's movement interface and is, at the same time, simple. This is the solution that the average user needs. Now, in order to set up a 'portal' between two doors (or whatever you have), you just need to edit the entry point's &lt;tt&gt;moveto_tag&lt;/tt&gt; variable, and the exit point's &lt;tt&gt;tag&lt;/tt&gt; variable.&lt;br&gt;
&lt;br&gt;
&lt;span style=&quot;font-size: large&quot;&gt;Beyond The Basics&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
We could conceivably go well beyond this, though. For example, under the standard BYOND movement interface, when movement occurs, it is because the moving object's &lt;tt&gt;Move()&lt;/tt&gt; proc was called, with their new location as the argument. Then the current location and the new location determine whether the user should move. Rather than directly modifying the moving object's loc variable, we could use the &lt;tt&gt;Move()&lt;/tt&gt; proc to double-check whether movement should occur or not, or how it should occur. This could be used, for example, to implement traps, locked doors, or things blocking one or both ends of the door. Remember, BYOND's default movement interface, while lacking in features in a few places, is still very robust and useful, and it's a good idea to use it when you can.&lt;br&gt;
&lt;br&gt;
It's also possible that you may want to use movable atoms rather than a turf or area as a portal. Because the &lt;tt&gt;Move()&lt;/tt&gt; proc will never call the &lt;tt&gt;Enter()&lt;/tt&gt; or &lt;tt&gt;Entered()&lt;/tt&gt; procs, this has to be implemented in a different, but similar, way. There are two procs exclusively for the &lt;tt&gt;/atom/movable&lt;/tt&gt; type that acts similarly to &lt;tt&gt;Enter()&lt;/tt&gt; and &lt;tt&gt;Entered()&lt;/tt&gt;, called &lt;a href=&quot;http://www.byond.com/docs/ref/info.html#/atom/movable/proc/Cross&quot;&gt;&lt;tt&gt;Cross()&lt;/tt&gt;&lt;/a&gt; and &lt;a href=&quot;http://www.byond.com/docs/ref/info.html#/atom/movable/proc/Crossed&quot;&gt;&lt;tt&gt;Crossed()&lt;/tt&gt;&lt;/a&gt;. The implementation are very similar.</description>
        </item>
                <item>
            <title>The Dunning-Kruger Effect</title>
            <link>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=257776</link>
            <guid>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=257776</guid>
            <pubDate>Tue, 07 Feb 2012 05:42:13 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Popisfizzy?command=view_comments&amp;post=257776#comments</comments>
            
            <description>I'm sure more than a few people around here are aware of this, I just wanted to let people know of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect&quot;&gt;Dunning-Kruger Effect&lt;/a&gt;. There are more than a few members of these forums who are a practical incarnation of it.</description>
        </item>
                <item>
            <title>Woo, Orrery!</title>
            <link>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=253398</link>
            <guid>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=253398</guid>
            <pubDate>Sun, 05 Feb 2012 20:26:45 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Popisfizzy?command=view_comments&amp;post=253398#comments</comments>
            
            <description>Now, this'd've been more suitable for the blogs when they were around, but they aren't around anymore so suck it.&lt;br&gt;
&lt;br&gt;
If anyone remembers, in a time long, long ago, in the immeasurable distant ages of the old internet (maybe back in March or April?) I was working on a Javascript game engine utilizing the features of HTML5. That engine is called Orrery, and I've gotten back into working on it, rewriting it to work a little more nicely. I'm finally at the point where I can draw neat things!&lt;br&gt;
&lt;br&gt;
For example, &lt;a href=&quot;http://files.byondhome.com/Popisfizzy/HTML5/orrery/index.html&quot;&gt;this, which I think looks pretty neat&lt;/a&gt;. :D&lt;br&gt;
&lt;br&gt;
Everything in that is algorithmically-generated. There is no manual drawing of any of the polygons. In fact, this is the code I use to draw it.&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;dmkeyword&quot;&gt;var&lt;/span&gt; angle = Math.PI / 360 * 24;&lt;br&gt;&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt; scale = 4;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt; second_angle = 0;&lt;br&gt;&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt; translate_x = 0;&lt;br&gt;&lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt; translate_y = 0;&lt;br&gt;setInterval( function () {&lt;br&gt;  angle += Math.PI / 360;&lt;br&gt;&lt;br&gt;  second_angle += Math.PI / 360;&lt;br&gt;  translate_x += Math.PI / 720;&lt;br&gt;  translate_y += Math.PI / 720;&lt;br&gt;&lt;br&gt;  &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt; dx = 5 * Math.sin(translate_x);&lt;br&gt;  &lt;span class=&quot;dmkeyword&quot;&gt;var&lt;/span&gt; dy = 15 * Math.sin(translate_y);&lt;br&gt;&lt;br&gt;  Canvas.Draw.Translate(dx, dy);&lt;br&gt;  Canvas.Draw.Rotate(Math.PI * Math.cos(second_angle) / 180);&lt;br&gt;  Canvas.Draw.Translate(-dx, -dy);&lt;br&gt;&lt;br&gt;  Canvas.Draw.Clear();&lt;br&gt;  Canvas.Draw.Polygon(40, -40, 12, 66 * scale,  angle * 4, { FillColor : &lt;span class=&quot;dmstring&quot;&gt;'#100000'&lt;/span&gt; });&lt;br&gt;  Canvas.Draw.Polygon(40, -40, 11, 58 * scale, -angle * 2, { FillColor : &lt;span class=&quot;dmstring&quot;&gt;'#321000'&lt;/span&gt; });&lt;br&gt;  Canvas.Draw.Polygon(40, -40, 10, 50 * scale,  angle    , { FillColor : &lt;span class=&quot;dmstring&quot;&gt;'#543210'&lt;/span&gt; });&lt;br&gt;  Canvas.Draw.Polygon(40, -40,  9, 42 * scale, -angle / 2, { FillColor : &lt;span class=&quot;dmstring&quot;&gt;'#765432'&lt;/span&gt; });&lt;br&gt;  Canvas.Draw.Polygon(40, -40,  8, 34 * scale,  angle / 3, { FillColor : &lt;span class=&quot;dmstring&quot;&gt;'#987654'&lt;/span&gt; });&lt;br&gt;  Canvas.Draw.Polygon(40, -40,  7, 26 * scale, -angle / 4, { FillColor : &lt;span class=&quot;dmstring&quot;&gt;'#BA9876'&lt;/span&gt; });&lt;br&gt;  Canvas.Draw.Polygon(40, -40,  6, 18 * scale,  angle / 5, { FillColor : &lt;span class=&quot;dmstring&quot;&gt;'#DCBA98'&lt;/span&gt; });&lt;br&gt;  Canvas.Draw.Polygon(40, -40,  5, 10 * scale, -angle / 6, { FillColor : &lt;span class=&quot;dmstring&quot;&gt;'#FEDCBA'&lt;/span&gt; });&lt;br&gt;}, 1);
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
Thus, I can basically scale it and increase its rotation speed and direction with just a few changes in the code (And I'm also getting, in theory, about 1000 FPS. In practice, it's about 85 FPS and I'm just telling the canvas to update as fast as possible). I've basically just finished working on my code for drawing basic figures (squares, rectangles, parallelograms, ellipses, circles, and regular n-sided polygons), and may just implement some other simple line-and-figure drawing, and maybe a way to draw a convex hull.&lt;br&gt;
&lt;br&gt;
So, yeah. That's what I've been doing lately.</description>
        </item>
                <item>
            <title>What.</title>
            <link>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=242787</link>
            <guid>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=242787</guid>
            <pubDate>Fri, 03 Feb 2012 23:36:40 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Popisfizzy?command=view_comments&amp;post=242787#comments</comments>
            
            <description>&lt;a href=&quot;http://thinkprogress.org/health/2012/02/03/417657/santorum-tells-sick-kid-not-to-complain-about-1-million-drug-costs-because-people-pay-900-for-an-ipad/?mobile=nc&quot;&gt;http://thinkprogress.org/health/2012/02/03/417657/ santorum-tells-sick-kid-not-to-complain-about-1-million-drug -costs-because-people-pay-900-for-an-ipad/?mobile=nc&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&quot;While campaigning yesterday in Woodland Park, Colorado, GOP contender Rick Santorum told a sick child and his mother that they shouldnt complain about the exorbitant cost of his medication because some people spend $900 on iPads.&quot;&lt;br&gt;
&lt;br&gt;
What.</description>
        </item>
                <item>
            <title>My last blog post.</title>
            <link>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=123078</link>
            <guid>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=123078</guid>
            <pubDate>Tue, 24 Jan 2012 01:55:47 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Popisfizzy?command=view_comments&amp;post=123078#comments</comments>
            
            <description>For a different reason than the rest. My account expires in a little over one week, and for the first time in years I'll have to go without a membership. My financial situation currently is incredibly awful, and while I'd like to renew my membership, I'm broke for a couple weeks until my next paycheck, and even then I really just can't afford it.&lt;br&gt;
&lt;br&gt;
Well, I got my first membership when the blogs were a new thing, and I'll be going out as they're becoming an old thing (to an extent), so I guess it's kind of appropriate.&lt;br&gt;
&lt;br&gt;
See ya.</description>
        </item>
                <item>
            <title>Looking through old notebooks is interesting...</title>
            <link>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=122409</link>
            <guid>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=122409</guid>
            <pubDate>Sat, 31 Dec 2011 01:27:50 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Popisfizzy?command=view_comments&amp;post=122409#comments</comments>
            
            <description>&lt;center&gt;&lt;span style=&quot;font-size: 20pt;&quot;&gt;&quot;Hello dying pen, you've been a good friend&quot;&lt;/span&gt;&lt;/center&gt;
&lt;br&gt;
&lt;br&gt;
Just written at the top of a page. Nothing else related to it, anywhere.</description>
        </item>
                <item>
            <title>Happy Festivus.</title>
            <link>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=122241</link>
            <guid>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=122241</guid>
            <pubDate>Sun, 25 Dec 2011 18:23:10 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Popisfizzy?command=view_comments&amp;post=122241#comments</comments>
            
            <description>Because combo breaker.</description>
        </item>
                <item>
            <title>Regular hexagonal tiling, hex grids, and coordinate system.</title>
            <link>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=122097</link>
            <guid>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=122097</guid>
            <pubDate>Wed, 21 Dec 2011 11:23:12 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Popisfizzy?command=view_comments&amp;post=122097#comments</comments>
            
            <description>The title rolls right off the tongue, wouldn't you say? Lately I've been working on a non-BYOND project. One of the many I'll probably never finish. This particular one is the reason I started Orrery, the HTML5-based game engine I'm working on. In particular, part of the project is going to involve translating positions on a &lt;a href=&quot;http://en.wikipedia.org/wiki/Hex_grid&quot;&gt;hex grid&lt;/a&gt; to positions on a &lt;a href=&quot;http://en.wikipedia.org/wiki/Cartesian_coordinate_system&quot;&gt;Cartesian grid&lt;/a&gt;, which is the sort of grid that you normally see on stuff like graph paper, and is one of the most common coordinate systems.&lt;br&gt;
&lt;br&gt;
Before we start off, I need to describe how my particular hex grid system is built. Starting some research on this topic, I used &lt;a href=&quot;http://playtechs.blogspot.com/2007/04/hex-grids.html&quot;&gt;this site&lt;/a&gt; to begin. Basically, I begin with a simple Cartesian grid, as shown below.&lt;br&gt;
&lt;br&gt;
&lt;center&gt;&lt;img width=&quot;241&quot; height=&quot;241&quot; src=&quot;http://www.byond.com/members/Popisfizzy/files/2011-12/Popisfizzy-0001/16x16%20Cart.%20Grid.PNG&quot;&gt;&lt;/center&gt;
&lt;br&gt;
&lt;br&gt;
The website I used suggested building a hex grid out of a rectangular grid. This is basically the same as a Cartesian grid, except the grid is stretched along the x-axis. My particular transformation basically multiplied the width by two, so I have (x', y') &amp;#8594; (2x, y). This generates the grid shown below (overlaid on top of the Cartesian grid).&lt;br&gt;
&lt;br&gt;
&lt;center&gt;&lt;img width=&quot;241&quot; height=&quot;241&quot; src=&quot;http://www.byond.com/members/Popisfizzy/files/2011-12/Popisfizzy-0001/32x16%20Rect.%20Grid.PNG&quot;&gt;&lt;br&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;The red is the rectangular grid. The blue is the underlying Cartesian grid, which has been stretched.&lt;/span&gt;&lt;/center&gt;
&lt;br&gt;
&lt;br&gt;
Now, over-top of this I draw the hex grid, with a particular tiling relative to the rectangular grid, which I'll describe next.&lt;br&gt;
&lt;br&gt;
&lt;center&gt;&lt;img width=&quot;241&quot; height=&quot;241&quot; src=&quot;http://www.byond.com/members/Popisfizzy/files/2011-12/Popisfizzy-0001/Hex.%20Grid.PNG&quot;&gt;&lt;/center&gt;
&lt;br&gt;
&lt;br&gt;
Now, in order to do all this, I have to make a choice about what coordinates on the rectangular grid the hex coordinates will map to. I have chosen the coordinate of the first full rectangular block on the bottom-left of the hexagon, and colored these blocks gray so they stand out.&lt;br&gt;
&lt;br&gt;
In addition to this, I've chosen a particular tiling for the hex grid to simplify our mathematics. From this point on, I'll use the notation &lt;i&gt;R&lt;/i&gt;(x,y) to indicate a particular rectangular coordinate, &lt;i&gt;C&lt;/i&gt;(x,y) to indicate a particular Cartesian coordinate, and &lt;i&gt;H&lt;/i&gt;(x,y) to indicate a particular hex coordinate.&lt;br&gt;
&lt;br&gt;
There is a highlighted rectangular block at the coordinate &lt;i&gt;R&lt;/i&gt;(0,0). This is no accident. I have chosen this particular location so we can have the mapping &lt;i&gt;H&lt;/i&gt;(0,0) &amp;#8594; &lt;i&gt;R&lt;/i&gt;(0,0). This means we won't have to &lt;a href=&quot;http://en.wikipedia.org/wiki/Translation_(geometry)&quot;&gt;translate&lt;/a&gt; the result of our transformation from the hex grid to the rectangular grid.&lt;br&gt;
&lt;br&gt;
Now that we have that out of the way, we have to define our coordinate system for the hex grid. Often, when people attempt this, they try and emulate the Cartesian coordinate system. Basically, assume our drawing is on a piece of paper. The common method is define the x-axis and y-axis emulating, exactly, the underlying Cartesian system. The problem with this is that it results in alternating rows of hexagons having different x values, because in a hex grid you can't move straight 'up' into another hexagon; you have to move two rows to do this.&lt;br&gt;
&lt;br&gt;
As it turns out, this particular pattern is not very optimal. For one, it's just plain wonky. Two, it doesn't allow for nice translations to a Cartesian grid. The basic idea isn't flawed, though. Once again, with our paper example, there's no real problem with having an x-axis that increases from left-to-right as you move along the bottom of the paper, and there's no problem in having a y-axis that increases as you move bottom-to-top along the side of the paper. What you can do to rectify this, though, is have the x-axis move &lt;i&gt;diagonally&lt;/i&gt;, through the hexagons. This results in the coordinate system below.&lt;br&gt;
&lt;br&gt;
&lt;center&gt;&lt;img width=&quot;241&quot; height=&quot;241&quot; src=&quot;http://www.byond.com/members/Popisfizzy/files/2011-12/Popisfizzy-0001/Hex.%20Grid%20with%20Axes.PNG&quot;&gt;&lt;br&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;The orange lines are the x-coordinates. The green lines are the y-coordinates. The thick lines indicate x-coordinates and y-coordinates of 0. The origin is where these intersect&lt;/span&gt;&lt;/center&gt;
&lt;br&gt;
&lt;br&gt;
Using this particular orientation, we now see that, indeed, &lt;i&gt;H&lt;/i&gt;(0,0) &amp;#8594; &lt;i&gt;R&lt;/i&gt;(0,0).&lt;br&gt;
&lt;br&gt;
Now, we need to define our &lt;a href=&quot;http://en.wikipedia.org/wiki/Linear_map&quot;&gt;linear transformation&lt;/a&gt; that converts our hex coordinates into rectangular coordinates. The concept is much, much more nuanced than this, but basically our particular linear transformation boils down to this. There exist constants a,b,c,d such that &lt;i&gt;R&lt;/i&gt;(x', y') &amp;#8594; &lt;i&gt;H&lt;/i&gt;(ax + by, cx + dy).&lt;br&gt;
&lt;br&gt;
To do this, we need to find a few sample points on our grid to test. Really, we only need two, though it helps to not choose the sample points &lt;i&gt;H&lt;/i&gt;(0,0) &amp;#8594; &lt;i&gt;R&lt;/i&gt;(0,0). I'm going to choose the sample points &lt;i&gt;H&lt;/i&gt;(0,1) &amp;#8594; &lt;i&gt;R&lt;/i&gt;(1,3) and &lt;i&gt;H&lt;/i&gt;(-1,-1) &amp;#8594; &lt;i&gt;R&lt;/i&gt;(-3,-3). You can verify these yourself.&lt;br&gt;
&lt;br&gt;
Now, our linear transformation is as follows:&lt;br&gt;
&lt;center&gt;x' &amp;#8594; ax + by&lt;br&gt;
y' &amp;#8594; cx + dy&lt;br&gt;&lt;/center&gt;
&lt;br&gt;
We have two sets of sample data that for each of these. We know x, x', y, and y', so we plug these in. For &lt;i&gt;H&lt;/i&gt;(0,1) &amp;#8594; &lt;i&gt;R&lt;/i&gt;(1,3) we get&lt;br&gt;
&lt;center&gt;1 &amp;#8594; 0a + 1b&lt;br&gt;
3 &amp;#8594; 0c + 1d&lt;/center&gt;
&lt;br&gt;
and for &lt;i&gt;H&lt;/i&gt;(-1,-1) &amp;#8594; &lt;i&gt;R&lt;/i&gt;(-3,-3) we get&lt;br&gt;
&lt;center&gt;-3 &amp;#8594; -1a + -1b&lt;br&gt;
-3 &amp;#8594; -1c + -1d&lt;/center&gt;
&lt;br&gt;
This allows us to create two systems of equations:&lt;br&gt;
&lt;center&gt;1 = 0a + 1b&lt;br&gt;
-3 = -1a + -1b&lt;br&gt;
&lt;br&gt;
3 = 0c + 1d&lt;br&gt;
-3 = -1c + -1d&lt;/center&gt;
&lt;br&gt;
Solving this system of equations gets us the following constants:&lt;br&gt;
&lt;center&gt;a = 2&lt;br&gt;
b = 1&lt;br&gt;
c = 0&lt;br&gt;
d = 3&lt;/center&gt;
&lt;br&gt;
&lt;br&gt;
Thus, we get the transformation &lt;i&gt;R&lt;/i&gt;(x', y') = &lt;i&gt;H&lt;/i&gt;(2x + y, 3y). If we plug in our sample points, we see that we get what we should. &lt;i&gt;H&lt;/i&gt;(0,1) &amp;#8594; &lt;i&gt;R&lt;/i&gt;(1,3), &lt;i&gt;H&lt;/i&gt;(-1,-1) &amp;#8594; &lt;i&gt;R&lt;/i&gt;(-3,-3), &lt;i&gt;H&lt;/i&gt;(0,0) &amp;#8594; &lt;i&gt;R&lt;/i&gt;(0,0).&lt;br&gt;
&lt;br&gt;
The thing is, we would like the Cartesian coordinates, not the rectangular coordinates. We're working on a Cartesian grid, after all. This happens to be very simple. Above I noted (using slightly-different notation), &lt;i&gt;C&lt;/i&gt;(x',y') &amp;#8594; &lt;i&gt;R&lt;/i&gt;(2x, y). Because we Know &lt;i&gt;R&lt;/i&gt;(x',y') &amp;#8594; &lt;i&gt;H&lt;/i&gt;(2x + y, 3y), we can just plug in the Rectangle-to-Cartesian transformation into the Hex-to-Rectangle transformation: &lt;i&gt;C&lt;/i&gt;(x',y') &amp;#8594; &lt;i&gt;H&lt;/i&gt;(2(2x + y), 2(3y)) = &lt;i&gt;H&lt;/i&gt;(4x + 2y, 6y). Thus, to transform between hex coordinates and Cartesian coordinates, we have &lt;i&gt;C&lt;/i&gt;(x',y') &amp;#8594; &lt;i&gt;H&lt;/i&gt;(4x + 2y, 6y). Simple enough.&lt;br&gt;
&lt;br&gt;
Lastly, we will likely want to convert from Cartesian coordinates to Hex coordinates. This could be complicated depending on the transformation. Luckily for us, it's simple. We can use the transformation we already have. Basically, we have the following equations above (after swapping the variables around):&lt;br&gt;
&lt;center&gt;x = 4x' + 2y'&lt;br&gt;
y = 6y'&lt;/center&gt;
&lt;br&gt;
And now we solve for, in the first equation, x', and in the second equation y'. For the second equation, this is simple:&lt;br&gt;
&lt;center&gt;y' = y/6&lt;/center&gt;
&lt;br&gt;
The second equation gives us&lt;br&gt;
&lt;center&gt;x' = (x - 2y')/4 = (x - 2y/6)/4) = x/4 - y/12&lt;/center&gt;
&lt;br&gt;
Thus, our transformation is &lt;i&gt;H&lt;/i&gt;(x',y') &amp;#8594; &lt;i&gt;C&lt;/i&gt;(x/4 - y/12, y/6). This transformation will, though, will generate non-integer values, which are not actually meaningful for our hexadecimal coordinate system. Thus, we simply need to floor the resultant values: &lt;i&gt;C&lt;/i&gt;( floor(x/4 - y/12), floor(y/6) ). This gives our transformation. Once again, you can test with a few sample points, like those above, to verify this is true.&lt;br&gt;
&lt;br&gt;
Now, because BYOND uses a positive Cartesian grid (meaning that BYOND only uses the first &lt;a href=&quot;http://en.wikipedia.org/wiki/Cartesian_coordinate_system#Quadrants_and_octants&quot;&gt;quadrant&lt;/a&gt; of a Cartesian grid), this isn't necessarily the &lt;i&gt;best&lt;/i&gt; layout to use. In fact, it may be better to shift the hex grid up by one, so that the very hexagon at &lt;i&gt;H&lt;/i&gt;(0,0) is completely on the map. This means that when we convert from Hex coordinates to Cartesian coordinates, we need to subtract one from the transformation, and add one when we convert from Cartesian coordinates to Hex coordinates. These leaves our transformations as follows:&lt;br&gt;
&lt;center&gt;&lt;br&gt;
&lt;i&gt;C&lt;/i&gt;(x',y') &amp;#8594; &lt;i&gt;H&lt;/i&gt;(4x + 2y - 1, 3y)&lt;br&gt;
&lt;i&gt;H&lt;/i&gt;(x',y') &amp;#8594; &lt;i&gt;C&lt;/i&gt;(x',y') &amp;#8594; ( floor(x/4 - y/12 + 1), floor(y/6) )&lt;/center&gt;
&lt;br&gt;
As it happens, this means our translation is no longer a linear transformation (in fact, it becomes an &lt;a href=&quot;http://en.wikipedia.org/wiki/Affine_transformation&quot;&gt;affine transformation&lt;/a&gt;), but this doesn't matter for most applications, and it greatly simplifies things.&lt;br&gt;
&lt;br&gt;
And thus, we have the mathematics of one potential regular hexagon grid and coordinate system in BYOND. This isn't necessarily the best for every game. For example, someone may want to have the flat portion of the hexagons be at the bottom, rather than the sides, which requires different mathematics. Or they may want differently-sized hexagons. Still, using this you should be able to get a start on what the mathematics of the transformations for your system need to be!</description>
        </item>
                <item>
            <title>Dark Matter</title>
            <link>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=121647</link>
            <guid>http://www.byond.com/members/Popisfizzy?command=view_post&amp;post=121647</guid>
            <pubDate>Tue, 06 Dec 2011 01:34:58 +0000</pubDate>
            
            <comments>http://www.byond.com/members/Popisfizzy?command=view_comments&amp;post=121647#comments</comments>
            
            <description>I HATE, HATE, HATE people who compare dark matter to luminiferous aether. It just shows how ignorant of science, theory, and evidence they are.</description>
        </item>
            
    </channel>
</rss>


