Tuesday, 11 November 2014

Gameplay Brainstorming


Some lunch break gameplay ideas to help guide my development:
  • A frontal attack is too difficult on a high security target, so instead, discover a nearby person who works at the target and infect their phone or laptop with malware that has a chance of spreading to the internals of the target network.
  • If a target's primary entry point is too secure, but a currently unused backup entry point is less secure, a DOS or other disabling attack to the target's primary entry point could result in the backup entry point becoming active, allowing for entry into the network.
  • Some extremely high security, high value networks are air-gapped with the exception of a highly controlled satellite connection via another high security network.
  • A target's security personal are only human and can be distracted by attacks on secondary targets on a network, lessening the chance of detection of an attack on the primary target.
  • Harnessing the power of a botnet can make it possible to crack crypto-coin wallets.
  • Networks containing devices owned by VIPs can yield high value data which can be sold on the blackmarket.
  • Messing with VIPs' data will attract the attention of the authorities, raising your suspicion level.
  • A high suspicion level will cause the authorities security professionals to actively seek you out. You can reduce your suspicion and lower your chance of arrest by moving your home base.
  • Dwelling at the same home base for too long with a high suspicion level will result in the authorities probing your network. If these probes go unnoticed for too long, you will be raided and arrested. Taking the appropriate precautions and looking out for activity by the authorities at your home base will keep you one step ahead.
  • Moving your home base takes time and costs significant amounts of money. The new location should be chosen carefully.
  • Software and exploits can be purchased from other hackers, finding these hackers can be difficult and some will not deal with you until you've reached a certain skill level.
  • The presence of another hacker on a network can be identified by the unusual behavior of a device on the network.
  • Other hackers have home bases as well, containing their collection of software and exploits, these devices are extremely high security and difficult to attack. Doing so will not raise your suspicion level with the authorities, but will likely result in retaliation if detected.
  • Security advisories can be translated into exploits with a high enough skill level.
  • Every workstation has a user. Every user has a home network their other devices may be found on while they're not at work.
I've also added filesystems, money and time too, so here's a picture to keep things colorful:


Saturday, 8 November 2014

5k lines of code lighter...

So another month has past, there seems to be a pattern forming here. Maybe I'll make this a monthly update kinda deal. I've been finding much more time to spend on HTP over this last month, mainly because I've been making it a high priority to find the time. Things have been going very well, my decision to throw out my old art style was definitely the right one, and actually led to me throwing almost my entire code base away, a depressing thing as any programmers out there will know, but almost always worth the pain.

I had a gameplay epiphany the other day, on the toilet of course, where all epiphanies must occur. Up till then, I was never really sure how I was going to translate this strange simulated internet thing I've been creating into some kind of game, something fun. Up till then, I was adamant on simulating every tiny little aspect of everything as a node in a hierarchy. The world had cities, cities had sites, sites had networks, networks had computers, and computers had components. It was kinda cool, being able to zoom right down from the world level to the CPU level. Cool, but extremely costly. To generate the 100,000+ computers I wanted to make the game feel 'vast' meant simulating literally millions and millions of nodes. All the time. It didn't scale, and was really leading me to any kinda of gameplay.

So on the toilet, it dawned on me, I could simulate thousands of nodes without much difficulty, so if these nodes weren't individual components, but entire networks, I could easily have the hundreds of thousands of computers I wanted, and each of these networks, which would form the galaxy of interconnected nodes floating in cyberspace, the experience I wanted to create, could be its own sort of 'level', with its own puzzles and challenges. It's kind of hard to articulate how I think this is going to work in my head, so I supposed it's probably easier to just show you. So here is the closest I've come to a thin vertical slice of how the finished game might play so far. You'll notice for the first time a few actual gameplay elements going on as I take on a small home network and infect a computer with some malware:



I'm much happier with the visuals, as primitive as they are, I think I could do a lot with them. It's also nice simulating networks like this because I can happily simulate the physics on 100-200+ computers in these networks and get that nice movement as new nodes are discovered and the network fleshes out.

In terms of the user interface, I started out trying to use a 3D interface that surrounded each node and displayed relevant information, but I found it hard to read, clunky, and getting in the way of the cyberspace feel. The current system console UI started out as a quick and dirty debug placeholder, but it's starting to grow on me, I think with some love, it could actually work for the final UI. It suits the hacker motif and I can convey a lot more information then I could with a 3D in-world UI. So it'll do for now, and I'll see how it pans out later as the game gets more complex.

Whilst the gameplay is still very very early on, I'm still trying to be very careful to try and not corner myself into repetitive gameplay, so am trying to think of ways to encourage lateral thinking and emergent puzzles. For instance, when attempting to hack an ISP or other high security network, a full frontal attack may be extremely difficult, with layers of firewalls and intruder detection systems. But ISPs must have a human element, an alternative approach would be to identify a nearby home network in which one of the ISP's employees works, then attempt to hack through their relatively low security home network and plant some malware on their mobile phone whilst it's connected to their wifi. This malware may in turn find it's way onto the internal network of the ISP and provide you with a backdoor that would be otherwise very hard to establish. It's this kind of gameplay I want to encourage, and while I'm a long away from that level of gameplay now, it helps to keep that in the back of my head at all times.

Well I guess that'll do for this month, I'm very excited with where HTP is at now, mostly because I've gotten over a lot of the technical challenges now, and am able to work on some of the pure gameplay elements.. which is not only more fun, but much easier work in comparison. The next month should be quite productive if I can still make the time to work on HTP.

Hack the Planet!

Tuesday, 7 October 2014

Bloody Crunch

It's been a long time since I both had a chance to write something on here or even work on HTP. The promised 2 weeks of The Crunch turned into 4 weeks, as always seems to be the way. The Crunch simply prevented me spending any time at all on HTP. As I'm sure some of the other developers out there know, time spent away from a project slowly builds up a barrier to re-entry, as knowledge of the code base fades and momentum is lost.

Crunch time is starting to end at my work, and for my own sanity I need to take my personal project time more seriously and make time for it.

This is not going to be a technical blog post for once, this is I guess more my ramblings about how, as developers, we tackle code block (the equivalent of writer's block for the non-programmers out there) and keeping project momentum going. I've been in this situation many times, and I've slowly learnt how to deal with it.

When approaching a project I haven't touched in a little while I don't try and pickup where I left off with the bugs I was tackling those many weeks ago. There's no point, my train of thought has long since left the station and you need those first steps back into a project to be fun and exciting.

So on that note, I've going to throw away my whole visual style and try some experiments. As much as I like the idea of flying around a globe with with real geographically accurate locations, the technical challenges are substantial, and I kind of feel I'll be losing the whole otherworldly feeling of drifting through the alien world of cyberspace. By limiting myself to a flat surface (which obviously the world isn't, I'm no flatlander.. but for all intents and purposes it is when you're zoomed in looking at a individual computer), I feel like I might lose some of the experience.

I plan on turfing out my entire graphics layer and trying something more akin to flying through a galaxy of connected nodes, to do this with my current code base would no doubt require MASSIVE refactoring, and would likely kill my attempt to regain the momentum I lost after taking a break from the project. So I'll be playing around with a few standalone demos probably, seeing how each one feels and what looks right. I'll post my results on here and whilst I know I don't have many followers on here, I'd love to hear feedback and opinions when I do :]

I'll leave you with a reference picture I've had kicking around for a while which I always find particularly inspiring:



Hack the Planet!

Sunday, 7 September 2014

It's STILL alive!

It's been exactly a month since my last update, my excuse is a lot of work commitments and The Crunch have really sapped my time. But 2 more weeks of The Crunch and I should have more time to spend on HTP.

Having said that, I have managed to squeeze in the odd hour or two here and there and I've actually made some good progress on something I'd like to share with the tumbleweeds :]

I've completely rewritten how the signal routing system works and have finally got it up and running. Nodes can now now 'provide' or 'request' things based on their functions, for example, here is part of the definition of a computer's power supply:

"Functions":
[
  {
    "Type": "Request",
    "ResourceType": "MediumVoltagePower",
    "Interval": 5,
    "ShowRequest": true,
    "Critical": true
  },
  {
    "Type": "Provide",
    "ResourceType": "LowVoltagePower",
    "Channel": "Power",
    "MaxPerSecond": 100
  }
]

What this means is every 5 seconds a power supply will attempt to request a unit of 'MediumVoltagePower'. Initially a power supply has no idea where it can get this request fulfilled, so it sends a broadcast request to every other node it's connected to. Put simply, this broadcast request will spread out across the entire power network until it encounters a node which has a 'provide' function that can fulfill the request. When this happens, the providing node sends a signal back down the reverse route that the requesting signal took. When the requesting node receives this signal, it now knows of a node that can provide for future requests so it stores the route to that node for future use.

I do a few other things to help speed this broadcasting process up, like if a request signal passes through a node that can't provide for the request, but does know of a node that can, it will point the request in the right direction, speeding the process up. Also, if any node is asked to pass on a providing signal, it will know where that signal came from, so it knows if it, or any other requesting node, needs that particular resource, it knows where to find it.



Well that's the dry details of how the system works out of the way. What's quite interesting about this system is pretty much all the traffic on the internet can be boiled down to requests and provisions. Some of them are critical for a node's operation, like power. But some are simply the byproducts of the behaviors of the AI agents in charge of the nodes. Take the following example for taken from the definition of the 'AveragePersonComputer' role (roles are something I use to describe the behaviors of a node):

"Functions":
[
  {
    "Type": "Request",
    "ResourceType": "Network",
    "Channel": "SocialNetworking",
    "TimesPerDay": 20,
    "ShowRequest": true,
    "Critical": false
  },
  {
    "Type": "Request",
    "ResourceType": "Network",
    "Channel": "Banking",
    "TimesPerDay": 2,
    "ShowRequest": true,
    "Critical": false
  },
  {
    "Type": "Request",
    "ResourceType": "Network",
    "Channel": "Porn",
    "TimesPerDay": 1,
    "ShowRequest": true,
    "Critical": false
  },
  {
    "Type": "Request",
    "ResourceType": "Network",
    "Channel": "Piracy",
    "TimesPerDay": 1,
    "ShowRequest": true,
    "Critical": false
  }
]

None of these requests are vital for the operation of the computer, but they will be requested by the node as long as it's active. These behaviors might change over time too, if a computer is infected by malware and becomes part of a botnet, it may start producing spam traffic as well as it's normal traffic.

This is all kind of exciting for me, cause the signal routing system is one of the first big systems I need to start doing some interesting stuff, stuff even bordering on gameplay! :O It's also really exciting to see the world come to life for the first time:



Having spent a good chunk of my day today trying to tear out quite an impressive infestation of spyware, browser bars, search hijackers and all kinds of other nasty computer bed bugs from my girlfriend's laptop, I can't wait to start simulating that kind of stuff in my little internet :]

Hack the Planet!

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!

Saturday, 26 July 2014

It's Alive!

I haven't posted in a little while because I've been waiting for the next natural breaking point in development, where I have something significant to say.

Making things like this always feels a bit like a long road trip to me, you've got your mountains, your valleys, your long stretches. Right now I feel a bit like I've finally reached the ridge after a long uphill stint. Suddenly a bunch of things have come together and started working and there's a great sense of possibilities.

The things in this simulated world have finally started to talk to each other. I wanted to start with something simple, so I decided to get the power grid working, starting with the power stations. The first official breath of life in my world started in the power station located in Jakarta (which happens to be positioned almost directly beneath the camera's initial position, so it gets a lot of attention). I zoomed in to it until I could see it's constituent parts. The "SuperHighVoltagePower" generator (I really should find out the technical terms for this stuff) sputtered into life after it's initial 5 second delay period. It's produced a signal of "1" on the SuperHighVoltagePower wire which slowly traveled down it's connected wires, leading it to the power station's external power connection. The connection, as defined by its relay function (described in my last post), transmitted this power signal over to the adjacent Large Power Substation, who's job it is to bring the voltage of the power down from SuperHighVoltagePower to HighVoltagePower (yeah... I'm a scientist me) and transmit it to the other power-needy sites in Jakarta.



What I quite like about what I've created so far is all these behaviors are pretty much all defined in these easily modifiable JSON files. The only behaviors that live in code so far are the functions' logic, and given how very atomic and simple they tend to be, I will likely pull that behavior out into a scripting language, probably LUA, to make sure they are moddable too.

The next interesting challenge is going to be getting a city to adopt the behaviors of all its children and its children's children, so looking at a freshly generated city, you would see it spitting out the network traffic and power output you would expect to see it's as-of-yet ungenerated children produce. I could brute force this using a recursive approach that scoops up any important functions of a city's children, and run those functions on the children's behalf until they have been generated and can take over. But I think I'd prefer to start work on a more scallable kinda "traffic profile" system.

I'd want the traffic, be it network and power, to be produced by a traffic profile that is defined by the the profiles of a node's children. Instead of running hundreds of individual functions on the children's behalf, it would lump all this behavior together into a single traffic profile. If changes were to happen to this profile, say the city receives a number of new virus infections, when the player zooms in on the city and its children become relevant again or are generated for the first time, these new infections would be distributed to the node's children, and when zooming out again, the profiles would be consolidated back into its parent's profile. This feels like the only way to simulate an approximation of the entire internet on a little tablet :S

So that will likely be taking up quite a few of my next lunch breaks. Will report back when I've made some progress there :]