Thursday 7 August 2014

Home Sweet Home

Wanted to just quickly share a screenshot (click to expand):


This is someone's home network. You can see the external network and power connections on the border there, they connect to the outside world and relay network and power signals as needed. The fuse box, for lack of a better name, feeds off this power, and in turn powers all the wired devices in the house, indicated by the yellow wires. The router is connected to the outside world and serves the house's 3 computers (it turns out this is quite a large house, 3 is the current maximum for a home network) and their wifi access point, indicated by the green wires. The access point appears to have a mobile phone and laptop connected to it wirelessly, indicated by the white lines.

I just found this screenshot quite satisfying, the procedural generation is coming along quite well, and it's nice to see it working after this huge refactoring I've been doing. For those interested, below is the template file for home networks:

{
  "ShouldScale": true,
  "MinSize": 0.05,
  "MaxSize": 0.1,
  "Needs": ["MediumVoltagePower", "Network"],
  "Structure":
  [
    {
      "Type": "FuseBox",
    },
    {
      "Type": "Router",
      "Serves":
      [
        {
          "Type": "Computer",
          "Min": 1,
          "Max": 3
        },
      ]
    },
    {
      "Type": "WifiAccessPoint",
      "Serves":
      [
        {
          "Type": "Mobile",
          "Min": 0,
          "Max": 3,
          "Hours": ["Morning", "Evening", "LazyNights"]
        },
        {
          "Type": "Laptop",
          "Min": 0,
          "Max": 3
        }
      ]
    }
  ]
}

Saturday 2 August 2014

The Whole World at Once

So I'm about half-way through a major refactoring of the procedural generation system, it's coming along slowly. It's one of those refactorings when your code base seems to half in size. I usually take that as a good sign.

Up till now the world wasn't generated until it became 'relevant'. This means until you zoomed in on a city, it was nothing but a placeholder. When it became relevant, it would generate all it's component parts: power stations, ISPs, neighborhoods, etc. The problem with this though, was that a freshly generated world had no knowledge of its constituent parts, so was unable to generate network traffic on their behalf. This would have led to a very boring world.

The brute force solution would have been to just generate the entire world at loading, the problem with this though is the majority of the CPU work done during generation is related to the physical representation of a node. All we really need to know about a node beforehand is what it is, how big it is, and what it belongs to. So what I've been refactoring towards, is a system where the entire internet is generated at the start, but only at a minimal level. This meant breaking apart the relationship of a node's details and its graphical representation.

I'm nearly done this refactoring now, and it's been interesting to see some of the numbers it's producing. Up till now I've not really had any real idea how big the internet I've been creating is, since it would only generate nodes when I looked at them. But now since I'm generating all of it beforehand, at least at a minimal level, I know exactly how big it is.

So far, for the sake of fast turnaround, I've only been generating 200 cities in the world. It's been enough to get a fairly populated internet and takes about 20 seconds to generate (with completely unoptimized code mind you). So for the first time I've had a chance to see what my world is made of, here it is:

51605 CPUs
51605 PSUs
51605 OSs
51605 NetworkAdapters
6248 Routers
6008 WifiAccessPoints
6008 HomeNetworks
1041 SmallPowerSubstations
852 NetworkSubstations
852 Neighbourhoods
189 LargePowerSubstations
173 NetworkProviders
200 Locations
208 NetworkExchanges
16 Generators
16 PowerStations
16 ISPs

This translates to roughly 50,000 devices. Some of them desktop machines, some laptops, some phones, some routers, anything with a CPU. I'm pretty happy with this number considering it only takes 20 seconds to generate with the current unoptimized code. I'd ideally like to see upwards of a million devices in the finished game, but I'm actually less worried about the generation time and more about the graphics load and amount of UI clutter.

I plan to dump Unity at some point in the future and roll my own engine for this. I'm using very little of the goodies and niceties that Unity provides for most types of games, and it doesn't give me the low level rendering support I need to achieve the framerate I want. For instance, it doesn't provide access to GL vertex buffers so I'm pushing the thousands upon thousands of lines to the GPU every frame. With 1000+ cities in my world, the framerate drops below 15 fps on my little tablet. With vertex buffers I suspect this will rise to 60+ fps. But for now I'm putting off this migration, functionality first, optimization second and all that jazz.

I started this post with the full intention of talking about potential gameplay ideas and lay off the technical stuff, but I guess my fingers had a different idea. Well, it's always nice to get this technical stuff off my chest. Maybe after a couple more beers I'll rant about botnets and cryptocurrencies for a while.

Hack the planet!