Friday, April 29, 2011

Markov Name Generator

I use something like this to generate names for stars and planets in my procedural universe game thingo.

import random

class Markov(object):
def __init__(self, samples, order, minLength):
self.order = order
self.minLength = minLength
self.chains = {}
self.used = []
self.samples = [i.strip().upper() for i in samples if len(i) > order]
for word in self.samples:
for letter in xrange(len(word)-order):
token = word[letter:letter+order]
entries = self.chains.setdefault(token, list())
entries.append(word[letter + order])

def next(self):
s = "";
while True:
n = random.choice(self.samples)
i = random.randint(0, len(n) - self.order)
s = n[i:i+self.order]
while len(s) < len(n):
i = random.randint(0, len(s) - self.order)
token = s[i:i+self.order]
if token not in self.chains:
break
s += random.choice(self.chains[token])
s = s[0] + s[1:].lower()
if not (s in self.samples or s in self.used or len(s) < self.minLength):
break
self.used.append(s);
return s;

def reset(self):
self.used.Clear()

You can seed it with any data you like to generate any sort of name. Eg:
starnames = """
Achernar Alpha Eridani \
Achird Eta Cassiopeiae \
Acrab Beta Scorpii \
Acrux Alpha Crucis \
Acubens Alpha Cancri \
Adhafera Zeta Leonis \
Adhara Epsilon Canis Majoris \
Ain Epsilon Tauri \
Aladfar Eta Lyrae \
Alamak Gamma Andromedae \
Alathfar Mu Lyrae \
Alaraph Beta Virginis \
Albaldah Pi Sagittarii \
""".split(" ")

m = Markov(starnames, 2, 6)
for i in xrange(10):
print m.next()

Gives this output:
Siolphh
Hafere
Ammaam
Ammaka
Ittatartar
Chieri
Scooor
Araineaa
Feriisda
Achuih

New Procedural Planet Generator Released.

The procedural planet package has been updated to version 1.4, and you can see the new demo here.

It features better city light control, better water control, a sun shader, many more planet texture ramps and a nice skybox cubemap.

The package is still pending release on the Unity Asset store, and should be available in a few days.

Wednesday, April 27, 2011

7 Bit Integer compression, in Python.

def decode7bit(bytes):
bytes = list(bytes)
value = 0
shift = 0
while True:
byteval = ord(bytes.pop(0))
if(byteval & 128) == 0: break
value |= ((byteval & 0x7F) << shift)
shift += 7
return (value | (byteval << shift))


def encode7bit(value):
temp = value
bytes = ""
while temp >= 128:
bytes += chr(0x000000FF & (temp | 0x80))
temp >>= 7
bytes += chr(temp)
return bytes


x = encode7bit(345)
print decode7bit(x)

Public and Private in Python?

I've just finished refactoring an awful C# class. I had been delaying the job for a while because I didn't want to do it.

Then, while staring at the code, I realised I could simply delete all the private methods and fields, leaving the public interface intact, and then re-implement the class in a much cleaner way. Great idea! I finished the job in a few hours, with a brand new class that doesn't give me a headache.

This is the first time I've actually seen a real value in having private and public scope for methods and variables. It makes refactoring much safer and easier! So... why don't we have them in Python?

Saturday, April 23, 2011

Encryption between Python and C#

I do a lot of work in restricted environments, where I still need to secure internet traffic. I chose to use the RC4 algorithm because it is simple to implement and relatively fast. It is actually easy enough that a simple programmer like myself could write matching Python and C# implementations!

RC4 is also a stream cipher, which means you don't need to worry about breaking your cleartext into blocks, padding them out... and other related pain.

If you do use RC4, you should be aware that it has some vulnerabilities.

Python:
def RC4(data, key):
x = 0
s = range(256)
for i in range(256):
x = (x + s[i] + ord(key[i % len(key)])) % 256
s[i], s[x] = s[x], s[i]
x = y = 0
out = ""
for c in data:
x = (x + 1) % 256
y = (y + s[x]) % 256
s[x], s[y] = s[y], s[x]
out += chr(ord(c) ^ s[(s[x] + s[y]) % 256])
return out


C#:
using System;


public class RC4
{
static public void Cipher (ref byte[] bytes, string skey)
{
var key = System.Text.ASCIIEncoding.ASCII.GetBytes(skey);
byte[] s = new byte[256];
byte[] k = new byte[256];
byte temp;
int i, j;

for (i = 0; i < 256; i++) {
s[i] = (byte)i;
k[i] = key[i % key.GetLength (0)];
}

j = 0;
for (i = 0; i < 256; i++) {
j = (j + s[i] + k[i]) % 256;
temp = s[i];
s[i] = s[j];
s[j] = temp;
}

i = j = 0;
for (int x = 0; x < bytes.GetLength (0); x++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
temp = s[i];
s[i] = s[j];
s[j] = temp;
int t = (s[i] + s[j]) % 256;
bytes[x] ^= s[t];
}
}
}

Thursday, April 21, 2011

Russians.

My favourite quote from a user bio on freelancer.com.

It is sayd: "if problem is easy then your local programmers can solve it; if problem is difficult then you should hire programmers from India; but if your problem is impossible to solve you must hire Russian."

Sunday, April 17, 2011

Sweet Python Syntax

I've been writing Python code for quite a while, yet sometimes I still get surprised by some neat undiscovered feature. This is what I found today. The neat part is where the tuple is unpacked inplace in the for statement.

things = {}
things[1] = (2,3)
things[2] = (4,5)

for id, (A, B) in things.items():
print id, A, B

I could be wrong, but I vaguely recall trying this once, and it not working. Now it does!

Friday, April 15, 2011

If you hadn't already guessed...


... I really like spacecraft. :-) Another shot of our game models, rendered in-engine (Unity3D).

Tuesday, April 12, 2011

Weather Geeks...

Can you tell me if the chart on this page is correct? If so, how to they get the data for the more ancient measurements? I'd like to use this data in a Python script I'm tinkering with...

Update:Evidence in the comments suggest this site is not trustworthy. There is better information linked in the comments, including this interesting graph.

Monday, April 11, 2011

AI for Unity3D

I'm about to release a tool called React. It implements behaviour trees for Unity3D.

Here is the obligatory screencast. I hope this is as easy to use as I think it is! It makes the designer specify what actions and conditions are available on the game object, before the programmer implements them.

The first step is to create a React Graph using the React Editor. The graph consists of selectors, sequences, actions, conditions and many other different node types. This graph is serialized into an asset so that it can be used by multiple game objects.

The second step is generating the C# script. This is as simple as clicking the generate button. The generated file contains stubs for the actions and conditions used in the behaviour tree. The body of these stubs is then filled in with appropriate code, and voila, you have an intelligent object.

It should be fully baked any day now, stay tuned!

Update: Now available on the asset store.

Friday, April 08, 2011

Pyramid vs NodeJS vs Gevent

Summary: NodeJS wins.

Test Program
ab -n 10000 -c 5 http://localhost/


Gevent Code
from gevent import wsgi

class WebServer(object):
def application(self, environ, start_response):
start_response("200 OK", [])
return ["Hello world!"]

if __name__ == "__main__":
app = WebServer()
wsgi.WSGIServer(('', 8888), app.application, backlog=1024).serve_forever()


Pyramid Code
from pyramid.config import Configurator
from pyramid.response import Response
from paste.httpserver import serve

def hello_world(request):
return Response('Hello world!')

if __name__ == '__main__':
config = Configurator()
config.add_view(hello_world)
app = config.make_wsgi_app()
serve(app, host='0.0.0.0')


NodeJS Code
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8124, "127.0.0.1");


Gevent Results
Time taken for tests:   3.255 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Requests per second: 3072.53


Pyramid Results
Concurrency Level:      5
Time taken for tests: 14.650 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Requests per second: 682.57



NodeJS Results
Concurrency Level:      5
Time taken for tests: 2.953 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Requests per second: 3386.80

Tuesday, April 05, 2011

You know you've made something good...

...when dudes want to pirate your gear.

The perks of working on games...


You get to make really cool stuff.

These models were built by Nic, our new hire. The shader on the ships is a custom specular / bumped / reflective / illuminated beast, and the skybox is generated by our Spacebox tool.

Friday, April 01, 2011

...??!!

Popular Posts