Jonathan's profileJonathan Chayce Dickinso...Blog Tools Help

Blog


    May 27

    Populous: Born Again

    Introduction

    I am writing a re-make of Populous: The Beginning. A legendary game that was years ahead of it's time (what more do you expect from Peter Molyneux?).

    Initial Ideas

    Populous is played on a height-mapped sphere, and I am not willing to fore-go that concept: but it does pose a few problems.

    Singularity

    This is what people call the convergence at the north and south poles of a sphere. There is a solution that is very effective, described by Paul Borke. In his implementation he pre-treats the texture. I am going to derive these values at runtime, for both the heightmap and the texture. By doing this I will gain the advantage that the landscape can have a higher resolution than the actual heightmap used (important for my CLOD algorithm).

    CLOD

    All the CLOD algorithms (for landscapes) I have seen so far use Geospheres, which I am now certain are not nessecary. They use sub-divisions and are a nightmare to implement.

    The camera is on a fixed-orbit around the planet (maybe a zoom function would be present). Because of this we know what angle the camera is at (its position is derived from the angles, rather than the other way round). Thus we know at exactly which point we need greatest detail.

    How do we have a CLOD sphere? It is rather easy in fact. We specify how many vertices we want along each edge and by pre-treating that value with a sin/cos function we can have it tighten near the camera, while still keeping the number of target vertices. This is how we do it on one axis:

    input: float num;
    input: float width;
    const: PiO2 = Pi / 2;

    float widthMult = width / (numHoriz * PiO2);
    float curX = 0;

    for(float vertX = 0; vertX < numHoriz; u++)
    {
    float angle = Pi * vertX / numHoriz;
    float step = Sin(angle) * widthMult;
    curX = curX + step;
    // curX is in range 0:width
    }

    Take that curX and map it to a sphere and you will have a CLOD sphere.

    Let's Go!!!

    I am going to see if I can implement this beast using Axiom (a C# engine that is a port from OGRE).

    March 10

    Trees and Anonymous Delegates

    Trees and Anonymous Delegates

    Something that I found to be really useful with the new .Net 2.0 anonymous delegates is "actioning".

    Scenario

    I had a situation where I was recursing through a tree to perform some action against all the items. Lets set up a simple tree node:

        public class TreeItem : List<TreeItem>
        {
            public string Text;
    
            public TreeItem(string text)
            {
                Text = text;
            }
        }

    The old way

    Using the old naive way we could do the following:

        static class Program
        {
            static TreeItem RootNode = new TreeItem("Root");
    
            static void Main()
            {
                // Fill the tree with useless data.
                RootNode.Add(new TreeItem("Node 1"));
                RootNode[0].Add(new TreeItem("Node 1.1"));
                RootNode[0].Add(new TreeItem("Node 1.2"));
    
                RootNode.Add(new TreeItem("Node 2"));
                RootNode[1].Add(new TreeItem("Node 2.1"));
                RootNode[1].Add(new TreeItem("Node 2.2"));
    
                // Do the actions, the old way.
                TreeItem[] items = FlattenTree();
                foreach (TreeItem item in items)
                    Console.WriteLine(item.Text);
    
                if (System.Diagnostics.Debugger.IsAttached)
                    Console.ReadLine();
            }
    
            static TreeItem[] FlattenTree()
            {
                TreeItem newItems = new TreeItem("Nothing");
    
                FlattenTree(newItems, RootNode);
    
                return newItems.ToArray();
            }
    
            private static void FlattenTree(TreeItem newItems, 
                                            TreeItem node)
            {
                newItems.Add(node);
                foreach (TreeItem item in node)
                    FlattenTree(newItems, item);
            }
        }

    As you can see, there are two loops occuring here (once to recurse the tree, and once to action all the items). That is far from optimal.

    The new way

    Let's see how we can optimize this further. Using anonymous delegates we can action all the items in the tree in a very clean fashion with little code changes required.

        static class Program
        {
            static TreeItem RootNode = new TreeItem("Root");
    
            static void Main()
            {
                // Fill the tree with useless data.
                RootNode.Add(new TreeItem("Node 1"));
                RootNode[0].Add(new TreeItem("Node 1.1"));
                RootNode[0].Add(new TreeItem("Node 1.2"));
    
                RootNode.Add(new TreeItem("Node 2"));
                RootNode[1].Add(new TreeItem("Node 2.1"));
                RootNode[1].Add(new TreeItem("Node 2.2"));
    
                // Do the actions, the new way.
                ActionTree(delegate(TreeItem item)
                {
                    Console.WriteLine(item.Text);
                });
    
                if (System.Diagnostics.Debugger.IsAttached)
                    Console.ReadLine();
            }
    
            static void ActionTree(Action<TreeItem> action)
            {
                ActionTree(action, RootNode);
            }
    
            private static void ActionTree(Action<TreeItem> action, 
                                           TreeItem node)
            {
                action(node);
                foreach (TreeItem item in node)
                    ActionTree(action, item);
            }
        }

    Now the tree is only being recursed, no iterating and assigning a useless array.

    Breaking Out the Generic Solution

    Now we need the ability to break out of the recursion. First we need to define a delegate.

        public delegate bool ContinueAction<T>(T t);

    Next we need to make the iteration process. Enter extension methods, after further tweaking I acheived the following:

        public class TreeItem : List<TreeItem>
        {
            public string Text;
    
            public TreeItem(string text)
            {
                Text = text;
            }
        }
    
        public delegate bool ContinueAction<T>(T t);
    
        static class Program
        {
            static TreeItem RootNode = new TreeItem("Root");
    
            static void Main()
            {
                // Fill the tree with useless data.
                RootNode.Add(new TreeItem("Node 1"));
                RootNode[0].Add(new TreeItem("Node 1.1"));
                RootNode[0].Add(new TreeItem("Node 1.2"));
    
                RootNode.Add(new TreeItem("Node 2"));
                RootNode[1].Add(new TreeItem("Node 2.1"));
                RootNode[1].Add(new TreeItem("Node 2.2"));
    
                // Do the actions, the generic way.
                RootNode.ActionTree<TreeItem>(delegate(TreeItem item)
                {
                    if (item.Text == "Node 2")
                        return false;
                    Console.WriteLine(item.Text);
                    return true;
                });
    
                if (System.Diagnostics.Debugger.IsAttached)
                    Console.ReadLine();
            }
    
            private static bool ActionTree<T>(this T node, ContinueAction<T> action) where T : IEnumerable<T>
            {
                if (!action(node))
                    return false;
                foreach (T item in node)
                {
                    if (!ActionTree<T>(item, action))
                        return false;
                }
                return true;
            }
        }

    And that's it! Those bound to .Net 2.0 can just remove the this from the extension method and call the method as follows:

        ActionTree<TreeItem>(RootNode, delegate(TreeItem item) {...});

    Hope this helps!!!

    February 20

    Developer Vision

    One of the things I have started seeing in the industry is the importance of developer vision. You actually get to factors influencing developer vision: the actual developer's vision and the box that you place them in.

    Developer Vision

    I have started noticing that some developers write much better code than others. There are several influencing factors but the most important one is pride. I am proud of my code, 'ugly' code (read Hungarian notation) annoys the hell out of me because it just shows lack of commitment to the public interface. If a developer can't take the time to try and understand code they should seek another job or hobby.

    Which brings me to my second point: public interface. You could write code that would take other developers (and potentially yourself) a very long time to program against, or you could bite the bullet and make a masterpiece in the first place. It will save you time down the line and you may find that you can reuse your code.

    But that isn't really the point of this article. The point is that some developers can just see further than others, one developer may go and write the code as per the spec, and the next will write it as per the spec with neat extras. They may even sit at home late at night and code you your next big thing.

    Boxes

    Put a developer in a box and they will never be able to write you something new, something that you never even conceived. Developers have a vast amount of knowledge about the power and capability of the systems that they use: much more than any technical writer, manager or customer. They can solve all your problems: if you only allow them to.

    I am fortunate that the company I work for supports innovation: and I have seen some amazing stuff come from the developers here (especially one in particular who really knows about the larger picture). We are treated well and rewarded for our efforts.

    Software Lifecycle

    Currently the general layout of the software cycle dictates that you first spec the product and then write the code. This is very well intentioned and is meant to keep everyone happy. Why not try this for your next product: tell the developers what you want, let them go off and see what they come up with, write the spec and then write the final code. You may just find you get more than you expect, and has stuff you never knew you needed.

    January 24

    Fun With Power Problems

    Eskom. A single word that now inspires hate and remorse in every single South African. Especially those in my industry.

    ZAY2K10 Bug

    I'm coining it. We have all heard of the Y2K30 bug (which is 10x more lethal than the Y2K strain), but here is a new one. South Africa and the 2010 Soccer World Cup. There are going to be huge infrastructure problems in South Africa when thousands of demanding tourists cross our border. It won't only be a electricity problem, but I can tell you what will causes it all: a power problem.

    The Current Government and Situation

    The current government is corrupt and completely and utterly unorganised. They resort to giving their top brass multi-million Rand bonuses; when, firstly, they don't deserve those bonuses and secondly, they can't afford those bonuses. They run essential services like they are capitalist ventures: sure they might publicise the telecoms and electricity providers - but certainly, as far as electricity goes, competitors are illegal.

    Telecoms were only recently opened to competition, but I might add we have yet to see consumer services from the competitor (which we welcome with open arms). Telkom still reigns supreme and most consumers will most probably be too complacent to switch to the alternative. Hopefully South Africa can do something about its telecoms situation because it is just plain down-right annoying (our Internet services cost a small fortune).

    Cellular Ogopolies

    There are two cell phone providers in South Africa (essentially), Vodacom and MTN. Both are ripping customers off from sickening heights. When Virgin Mobile came through I switched from Vodacom straight away: but it was just too plain limited - and my girlfriend is on Vodacom (so it works out cheaper, but only slightly).

    Given all of this, I must admit that Vodacom is trying pretty damn hard to give their customers good bang-for-buck. I was surprised when they allowed prepaid customers to buy data bundles for as little as R189 (about US$30) for 500mb, while that is a burst of rain for us, our American friends still point and throw stones at us.

    Uneducated

    Our current political party is dominated by uneducated, immoral or just plain stupid delegates. I am sure if you look up most of them you will see that they have degrees: 'complementary' degrees from our (otherwise hopeless) brown-nosing universities. I sure wish I could get a degree for landing a job, but I don't tow as much power (or as big bonuses) as they do.

    Computer Industry

    The computer industry is blossoming, world-wide; and in South Africa we are biding our time between power cuts, spending our incomes on bandwidth and taking pills to combat our depressing situation. Wasted money, wasted time - which means wasted money squared.

    We are third-world because that is what suits our government.

    January 23

    Cosmos

    I'll make my first real post an introduction to Cosmos (which neither stands for something nor does not stand for anything). Cosmos is an open source operating system written in 100% pure home-grown C#. How do we do this?

    Il2Cpu

    IL2CPU is a compiler that compiles CIL (Common Intermediate Language) to ML (Machine Language). CIL can not be run directly on a CPU (currently, at least): but it is what C# compiles to. ML is what your CPU understands.

    To get around the issue of needing ML at some point we inline assembler into C# (but it is strongly typed and all that amazing goodness). We can 'plug' methods in the corlib (.Net base library) and replace object and method implementations (this is a work in progress - a lot more needs to be done on the front of plugs).

    Why IL?

    So why are bothering to use IL in the first place?

    1. Languages that compile directly to ML generally suck (that includes 'hardcore' C/C++), why?
      1. ML is unsafe - write buggy programs (which even the best programmers do) and you are opening security holes: just look at Windows. 
      2. ML is complicated - yes, spend 10 years writing your operating system in C to prove your point.
      3. ML is only faster in academic situations - in very, very, very academic situations. Not to mention that up until now CIL has been benchmarked on an ML operating system.
      4. ML is static - you don't take advantage of MMX/SSE/3DNow automatically.
    2. It's a challenge.
    3. It's a philosophical leap.
    4. It's controversial.
      1. Everyone tells us that we can't and throws stones at us. Kinda like the nerd in elementary school who grows up and lands up being their boss.
    5. It will be easier in the long run.

    What We Are Looking Forward To

    We are really looking forward to:

    • Strongly typed drivers
    • Modular system
    • Uber security
    • Filesystem abstraction (read WinFS)

    So It Starts

    Blogging: Finally

    After months (or not so much) of searching for a decent blogging service, I came across one: Windows Live + Live Writer.

    What I'm Up To

    SourceCode

    I am a SourceCode developer. Spend most of my time chasing up new technologies and seeing how we can appropriate them for our customers. Most of the time I look at new Microsoft technologies, or I look at old ones and see how we can use them.

    I waste my boss's time with new ideas for products.

    Cosmos

    Cosmos is an open source operating system written in C# (that is, 100% C#) built using the IL2CPU component (that is really seen as a sub-project of Cosmos). We are making good progress and are nearing milestone 1.

    What To Expect

    Those aforementioned technologies (the ones that don't make it) may just be useful for somebody else. You might be lucky enough to score some sourcecode.

    Cosmos, of course, should be a great learning experience for me!