Friday, December 26, 2008

Building a GUI for an embedded system.

I'm building a HMI for an industrial control application, in a hurry. I'm faced with some choices:

#1. Use a GUI system on top the Unity 3D RAD platform.
#2. Use a 'standard' toolkit, like Windows Forms, GTK or QT.
#3. Build a GUI system on top of Pyglet.

Number #1 would be great to use, because it will let me use 3D elements as GUI items, and builds a very slick looking product. Unfortunately it doesn't work well with the touchscreen, because of the way it's GUI system works. It assumes you are always using a mouse. Because of this, I'd have to work-around the problem, which is an unknown and a risk.

Number #2 would be ok, because I could use Python, and it will get me up and running quickly. However, because I'm using a touchscreen, with no keyboard, most of the pre built widgets would be useless. I'd need to build new custom widgets, which almost negates the advantage of using an existing toolkit.

Number #3 is a risk, because there is an amount of new code I would have write and test. I can't just dive in and write the application. However, I have written lots of OpenGL GUI code before, which I can draw on, and I can make it look much better than Number #2. I can also build the widgets explicitly to work with touch screens, which should make for a better end user experience.

I'm going with #3.

Monday, December 15, 2008

Global Game Jam

Global Game Jam is coming to Perth.

The Global Game Jam will start at 5:00 PM Friday, January 30, 2009 through 5:00 pm Sunday, February 1, 2009, local time.

Arrangements for the venue and other things are still in progress, however there is likely to be a (small) entry cost for participants. Numbers are very limited, so you will need to get in quick.

To register, please email me at simonwittber@gmail.com, with your name and contact phone number. You must be able to attend the venue (likely to be in Northbridge, Western Australia) if you wish to participate.

Edit: We currently have 6 interested people...

Tuesday, November 18, 2008

Fibra grows events.

Fibra has grown an event handling plugin.
  1 import fibra
2
3
4 def task_a():
5 for i in xrange(10):
6 yield fibra.Send('AN_EVENT')
7
8 def task_b():
9 while True:
10 msg = yield fibra.Recv('AN_EVENT')
11 print 'Received:', msg
12
13 def test():
14 s = fibra.schedule()
15 s.install(task_a())
16 s.install(task_b())
17 s.run()
18
19 if __name__ == "__main__":
20 test()
Now I need to reinstate the networking layer... and think about adding multi-core features via the new (in 2.6) multiprocessing module. It would be nice to have events magically transferred across process boundaries. FibraNet used to do this, but I haven't found a clean way of adding this to fibra, yet.

Wednesday, November 12, 2008

Due to popular demand...

...another gamejam has been scheduled for November 14-30. Short notice I know. Apologies.

I had hoped to deploy a new version of the gamejam.org interface, but I simply don't have the time. Next year, perhaps.

The previous gamejam was quite successful, so if you feel inclined, feel free to join in.

Monday, November 10, 2008

The Attraction of Dynamic Languages.

Today, a friend asked me, "Why are you attracted to dynamic languages?".

I didn't have a ready answer. After thinking about it for a while, I can list some good reasons why I prefer to work in Python, which is a dynamic language. Lately I have been writing a lot of code in C and C# (directly re-implementing Python algorithms), so I think I am in a good place to pass comment.

  1. Python code is ~10% the size of my equivalent C# code. This means less typing, faster prototypes and less room for bugs.

  2. Dynamic languages really do promote loose coupling. There is no dependence on types. This helps the programmer write re-usable code, and actually re-use it, rather than hide it away in some dusty, forgotten SVN repository...

  3. Python works rather well with C. It's a piece of cake to convert a Python function into C code, then call them using ctypes. This fits perfectly with an incremental development method, where a prototype can slowly be converted into C code as needed.

  4. Late binding lets you do some really clever stuff, and makes things like state machines very compact and easy to code and understand.

I've also found a few things in mono.net which I wish I had in Python.

  1. A standard, OS independent socket implementation.

  2. ...hmm not much else.


Have I missed anything?

Tuesday, November 04, 2008

Burning out...

Too many projects. Too many people asking for things.

No time for the things I really want to do.

How do _you_ prevent burn out?

Thursday, October 16, 2008

Hard Real-time Linux

Is it possible?

In the past, I've been told, "No.".

I've just read an article which states "With a little extra work, you can get hard real-time support with the PREEMPT_RT patch."

Dear Lazyweb, is this so?

Thursday, October 02, 2008

Building a MMO backend.

I've just read a interesting article at IBM developerWorks discussing MMO backend architecture.

Using this kind of architecture, any modern game engine which provides the typical MOG game tools (such as Unity) can be used as a MMO platform, as long as the web glue between MOG instances is seamless. I've done this, using Python/Pylons, and it works well.

If Unity Technologies is to compete effectively for MMO developer attention, they need to provide a headless server which can run on Linux. Once this last piece is in place, it will become a viable option for MMO type projects.

Wednesday, October 01, 2008

How does struct.calcsize work?

>>> import struct
>>> struct.calcsize("b") + struct.calcsize("ffi") == struct.calcsize("bffi")
False
I would have expected calcsize("bffi") to be 13, instead it is 16. Hmmm.

Because of this, I have to write some weird code.
>>> a, = struct.unpack("b", buf[0])
>>> b, c, d = struct.unpack("ffi", buf[1:])
Why would this be so...

Sunday, September 14, 2008

Casual Gamer Hardware Statistics

Unity Technologies have been kind enough to publish the hardware statistics gathered by their web player.

There is some suprising information in there.

  • 45% of players have two CPU's.

  • 45% of players < 1GB of RAM.

  • The majority of players are running a screen resolution of 1024x768

This kind of information is _invaluable_ for independent game devs.

Thanks for the stats UT!

Wednesday, September 03, 2008

Tuesday, September 02, 2008

Google will own the web.

Google have finally announced they are releasing a browser. After years of speculation, it is here.

Unfortunately, I'll have to wait some time before I can check it out:
"Google said it's still working on versions compatible with Apple Inc.'s Mac computer and the Linux operating system."

Monday, September 01, 2008

XPS M1330 vs Macbook Pro

Last week my XPS M1330 was repaired (after I dropped it!).

I've been using a Macbook Pro 15 inch for that last few months while I procrastinated about calling Dell to get the XPS repaired. I also need the MBP for Unity and other graphical work.

I have to say, going back the XPS (with Ubuntu) is like a breath of fresh air. It's nicer to type on, has page up page down keys, a brighter screen. Using Ubuntu also feels much cleaner. I can't explain "cleaner", but it just feels that way compared to OS X. I know I can run Ubuntu on the MBP, but I thought I should give OSX a fair go. I'm pretty sure that I'll start using Ubuntu again for web and server code development, and leave the MBP for Unity and other graphical work.

It's really hard to get used to two different laptop keyboards though. :-)

Friday, August 29, 2008

Paul Oakenfold is scoring our game...


For the last 6 months I've been working on a MMO, Interzone Futebol, with Interzone Games. It's not your typical MMO.

Today we just found out that Paul Okenfold is providing the score for the game! Awesome!

Steve Wozniak is coming to Perth.

Steve Wozniak is coming to Perth!

Woah.

The conference is named the "Leading Lights Conference". It's all about innovation, business and getting investors interested in your project. This sounds a bit dry, but I'm sure his keynote will be interesting!

Saturday, August 16, 2008

gamejam is over...

gamejam wound up with a bang at the Nullarbor demo party.

Great stuff, and many awesome games were shown at Nullarbor.

The final released games are on the front page of gamejam.org. It's likely that some more uploads should treacle in over the next few hours days.

Tuesday, August 12, 2008

Nullarbor Bakery Party

The best of WA's indie game talent will be on show at the Bakery.
The Nullarbor independent game developers competition (http://www.notrees.org/2008/) is coming to a close for 2008 and, in conjunction with gamejam, we're getting together to send it off in fine form.

This is a party in two parts:

Developers' Old School Demoparty
* Friday, August 15 @ 7pm
Get together with your crew and put those finishing touches on your game. Party, socialise, and play.

Nullarbor Finals, Come on Down!
* Saturday, August 16 @ 7pm
See the finished games and vote for your favourites!

Entry is FREE!

Location: The Bakery, 233 James Street, Northbridge, Western Australia

Demoparty: Friday, August 15 to Saturday August 16. From 7pm to 7pm.
Rock up when you will, but be early for the good spots.

Presentation and Competition: Saturday, August 16, from 7pm to 9pm
As this is a licensed venue this is an 18+ event





For more information on Nullarbor visit the website: http://www.notrees.org/2008/

Any questions? Drop us a line at contact@notrees.org

Event Sponsors: Spinfast, Autodesk, Artrage, Edith Cowan University, Binary Culture, Surrender Events

Sunday, August 03, 2008

GameJam is rollin' along...

The GameJam has started, and we are currently sporting 61 members. w00t!

Most of them are local to Perth, West Australia; and many of them are using Python for their entries. Great fun.

Now... I... must... code!

Monday, July 28, 2008

Unity 2.1 is OUT!

Awesome. Shadows on Terrains. w00t!! Just in time for gamejam!

FTA:

Streaming Terrains

A seamless world is key when making an MMO. With Unity 2.1 you no longer are limited to a single terrain. Immerse your user in an endless landscape, based on streamed data.


Real-Time Shadows on Terrains

For extra kicks, lights and shadow projectors make terrains more distinct. And with Unity Pro, real-time shadows make them even more dazzling.


http://unity3d.com/unity/whats-new/unity-2.1

Monday, July 14, 2008

What Rocks?

Owning and running a public site (gamejam.org) which people are actually (almost) using.

I've spent a week of spare time hours building and adding features, which has been quite refreshing. In my day job(s), I need to worry about lots of problems which simply don't exist on a simple site designed to serve a few hundred people.

So far, I've implemented these features:

- Signup / Verification by email
- Diary / Twitter style microblog system
- Atom feeds
- Etag caching (only used for non-authenticated clients)
- Chat system
- Screenshots
- Team creation, invites
- Polls, comments
- Member profiles

I'm planning to add a trust graph, file uploads and... whatever else pops into my head. I don't know where this burst of development energy has come from, but I hope it lasts.

Wednesday, July 09, 2008

27 GameJammers!

So far, I've had 27 legit registrations for gamejam.

This provided sufficient motivation to add some more features to the web site.

gamejam.org now has member profiles, polls, comments, teams and developer diaries. There is also an atom feed for diary entries.

It's all written in Pylons, with help from jQuery and js-kit.

Friday, July 04, 2008

First steps to GameJam!

Registration is up and running at http://gamejam.org/.

There is more to the web app to be developed, but I'll hold off until enough people register their interest.

Tuesday, July 01, 2008

Software is an Approximation.

Software is never correct. It is only any approximation of what we believe the solution to be.

Programmers can never be perfectionists. Compromise is inevitable.

What Sucks?

When you're struggling with a tough problem...

you google some keywords...

and the first page of results are your own blog posts... :-(

Monday, June 30, 2008

Planning a GameJam

Inspired by other game jam events around the world, I'm planning (with a friend) to run a game jam sometime soon in Perth, Western Australia. We've had a few game companies set up shop here in the last year or so, and there should be plenty of talent around to sustain a short event.

I figure with the right web app, most things could take care of themselves! I started to prototype something in GAE, but it was a bit tedious, so I'll jump back into the familiar and efficient territory of Pylons for this small project.

Thursday, June 26, 2008

Take my money, damnit!

I've just spent that last 40 minutes trying to purchase VMWare Fusion through vmware.com.

I get to the end of the process, and receive this message:

"We are unable to process your order. Please verify your information and try again."

So, I go back, recheck information, try different permuations of my title, firstname, middle initial, last name. Argh. None of it works. ARRGH!

How hard is it to give me some relevant feedback so I know what is going wrong. ARRRHG AGAIN!

Thursday, June 19, 2008

Top 100 Web Apps

Scouta, the web service I've been working on for almost 2 years, has come in at #9 in BRW's top 100 list of Australian Web Apps.

The scouta service is built on the Pylons framework, and uses large amount of SQLAlchemy.

Thursday, June 12, 2008

Inertial Dampeners Essential


After an inspiring conversation with a colleague about our favorite game, Privateer, I was motivated to create a space ship simulation, controlled via 3 axis joystick.

I modeled the ship so it has two thrusters at the rear, which can pivot independently. I then apply separate forces to each thruster, which allows the ship to roll, and change pitch.

Unfortunately, the ship is extremely difficult to control. It would spin wildly, even with small amounts of thruster angle. The simulation only became workable when I added large amounts of torque dampening, and limited the thruster pivots to -+5 degrees.

Tuesday, June 10, 2008

Game Sound Effects

Looking for cool sound effects for your game?

Look no further.

This cool tool was written by DrPetter. It uses different synthesis techniques to create pickup, laser, explosion, powerup, hit, jump, blip and other random noises. Great fun.

Sunday, June 08, 2008

Google AppEngine - Game Portal?

So, after years of procrastination, I'm building a game portal, for better or worse. At present I'm only intending to host my own games.

The decision I'm facing is whether to invest in google appengine, or not. My only concern is whether it's unnecessarily restricting my target audience, or whether it its actually supplying me with a read-made target audience.

Monday, May 26, 2008

Return of the Krool.

A few years ago, I built a micro-game called Krool Joolz using Python and Pygame.

With my recent acquisition of a Unity3D license, I decided to try and recreate the game play using Unity. It was a good learning exercise, I learned several Unity concepts, how the engine works etc. I'm quite impressed so far. Deploying a build to the web with just a few clicks is great!

You can play with the prototype if you like.

There is no meta or end game yet, you just play until you lock the grid.

Friday, May 16, 2008

Dear lazyweb...

I'm setting up my Python dev environment on a new macbook... and easy_install is running like treacle down a hill. It is so slow!

Anyone else experienced this, and worked out what is wrong? I'm guessing its something network related...

Tuesday, May 13, 2008

I have Unity.

I've just arranged to purchase Unity 3D, a rapid game development tool.

I was first attracted to Unity because it could use the Boo language, which has some similarities to Python, my language of choice. Having played with the trial version, I've realized that Unity is an excellent tool, and will let me focus on games, instead of game libraries and frameworks.

Ironically, my first Unity project is not a game. I'll be using it to simulate industrial robots. Hopefully my client will allow me to post some screen shots as work progresses...

Thursday, May 08, 2008

Apache + SSL + PSK on Ubuntu

This howto describes the process of using Apache and SSL with trusted clients, via Pre Shared Keys. Unlike the usual way of using SSL, this setup requires the server _and_ the client to have valid certificates. This means you need to create a client certificate and deliver it securely to the client.

1. Enable SSL.
sudo a2enmod ssl

2. Generate a private key without a passphrase,
openssl genrsa -out server.key 1024

or with a passphrase.
openssl genrsa -des3 -out server.key 1024

3. Create a certificate signing request.
openssl req -new -key server.key -out server.csr

4. Sign it yourself.
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

5. Copy your new certificate and keys to the appropriate places.
sudo cp server.crt /etc/ssl/certs
sudo cp server.key /etc/ssl/private

6. Edit your apache site configuration, add these lines into a VirtualHost section.
SSLEngine on
SSLCertificateFile /etc/ssl/certs/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile /etc/ssl/certs/server.crt

7. Create a certificate which you can give to a client, or a group of clients.
openssl pkcs12 -export -out client_cert.pfx -in server.crt -inkey server.key\
-name 'Certificate Name'

8. Make sure the client gets the client_cert.pfx file, which they install into their browser.

9. To use the client_certificate.pfx in a python httplib or httplib2, it needs to be split into a key and certificate file.
openssl pkcs12 -clcerts -nokeys -in client_cert.pfx -out client_cert.pem
openssl pkcs12 -nocerts -in client_cert.pfx -out client_key.pem

10. Strip the pass phrase from client_key.pem so Python does not prompt for a pass phrase!
openssl rsa -in client_key.pem -out unsecured_client_key.pem

Monday, April 07, 2008

A Native Vertex Array for Python

My PyWeek effort did not produce a game, but I've got some useful code to share.

The graphics module provides a C extension types (via Pyrex) for working with Arrays of Vectors. It includes a composite VertexArray type wshich uses said Array types, with methods to draw the vertex array, compact the array and produce an index, as well as methods for arithmetic opertations on arrays.

There is also code for an OBJ loader, a Vector3 type and an OpenGL Transform type.

You can get it via BZR or Download.

Tuesday, March 11, 2008

Pyglet + Fixed Time Step Updates

Pyglet 1.1 comes with a shiny new event loop. I've always liked to control my own mainloop, so that I can implement things like fixed time step updates, and simulation/frame skipping.

After some advice from Alex, I came up with the following class, which plugs neatly into the pyglet mainloop/clock schedule architecture.

import pyglet

class FixedStepLoop(object):
"""
A fixed time step loop for pyglet.
"""
def __init__(self, update_function, step, max_step):
self.update_function = update_function
self.step = step
self.max_step = max_step
self.simulation_time = 0.0 - self.step
self.real_time = 0.0
self.frame_time = 0.0
pyglet.clock.schedule(self._tick)

def _tick(self, T):
self.real_time += T
self.frame_time += T

if T > self.max_step:
self.simulation_time = self.real_time - self.step

while self.simulation_time <= self.real_time:
self.update_function(self.step)
self.simulation_time += self.step
self.frame_time = 0.0

self.step_fraction = self.frame_time / self.step

If you instantiate this class with an update function as the first parameter, followed by the time step size and the maximum step size (after which simulation skipping will occur), the update function will be called with a fixed time step parameter.

As a side effect, you can all get the step fraction (percentage of time passed between update calls) if you want to implement some interpolation between your game state.

window = pyglet.window.Window()

def on_update(t):
print t

fixed_step_loop = FixedStepLoop(on_update, 1.0/10, 0.2)

@window.event
def on_draw():
print fixed_step_loop.step_fraction
window.clear()

pyglet.app.run()

Thursday, February 21, 2008

SOCKS proxy using SSH

I've just seen and used a brilliant ssh option.

The command:
sudo ssh -D localport user@externalhost
will set up a local SOCKS proxy listening on localport which will route all your traffic (including privledged ports) via external host.

Sunday, February 17, 2008

Notebook Audio

My notebook audio (Intel HDA) is terrible. Using jackd, I constantly get xruns, and I cannot change any parameters to try and alleviate the problem.

So, I bought an external USB audio device, plugged it in, and it just worked. No more xruns. Jackd no longer complains, and I have 5ms latency. Amazing. Even a cheap ($5) USB device performed better than the internal audio device in my laptop. It's an XPS M1330 by the way.

To celebrate I bought a pair of Edirol MA-15 Monitor speakers, which are a pleasure to listen to. Now I can look forward to getting to grips with Pure Data, or maybe Galan, which looks quite interesting.

Friday, February 01, 2008

Pyglet + Joystick

I've written a pygletified Joystick class. I'm not sure I'm using dispatch_events correctly, but it seems to work. With some more work it could support OSX and Win32.
from pyglet import event
import sys

if sys.platform == 'linux2':
import struct
from select import select

class Joystick(event.EventDispatcher):
JS_EVENT_BUTTON = 0x01 #/* button pressed/released */
JS_EVENT_AXIS = 0x02 #/* joystick moved */
JS_EVENT_INIT = 0x80 #/* initial state of device */
JS_EVENT = "IhBB"
JS_EVENT_SIZE = struct.calcsize(JS_EVENT)

def __init__(self, device_number):
device = '/dev/input/js%s' % device_number
event.EventDispatcher.__init__(self)
self.dev = open('/dev/input/js0')

def dispatch_events(self):
r,w,e = select([self.dev],[],[], 0)
if self.dev not in r: return
evt = self.dev.read(self.JS_EVENT_SIZE)
time, value, type, number = struct.unpack(self.JS_EVENT, evt)
evt = type & ~self.JS_EVENT_INIT
if evt == self.JS_EVENT_AXIS:
self.dispatch_event('on_axis', number, value)
elif evt == self.JS_EVENT_BUTTON:
self.dispatch_event('on_button', number, value==1)

def on_axis(self, axis, value):
pass

def on_button(self, button, pressed):
pass

Joystick.register_event_type('on_axis')
Joystick.register_event_type('on_button')

else:
raise ImportError('Platform not supported (%s)' % sys.platform)



if __name__ == "__main__":
j = Joystick(0)
@j.event
def on_button(button, pressed):
print 'button', button, pressed

@j.event
def on_axis(axis, value):
print 'axis', axis, value

while True:
j.dispatch_events()



Tuesday, January 15, 2008

Many versions of one Python package

I had to spend some time today working out how to use pkg_resources correctly. I've got multiple versions of SQLAlchemy, and I expected that this code:
import pkg_resources
pkg_resources.require('SQLAlchemy==0.3.11')
would simply active the correct package and everything would just work.

Not so.

In order to use multiple versions of a package, you must install it with the --multi-version option. Eg, these commands:
easy_install --multi-version SQLAlchemy==0.3.11
easy_install --multi-version SQLAlchemy==0.4.2
will let you use pkg_resources to activate different versions of the SQLAlchemy package. Without the --multi-version argument, pkg_resources.require will only perform a dependency check, rather than check and activate the required version.

Saturday, January 12, 2008

Deeply Nested Resources in Pylons

I've finally got around to working out how to achieve deeply nested resources in Pylons and Routes.

Say you want a URL like this:

/books/some_book/chapters/some_chapter/pages/some_page

where 'some_book', 'some_chapter', 'some_page' are member names you want to fetch out of the 'book', 'chapters' and 'pages' collections.

Using routes, you cannot achieve this using the 'parent_resource' option only. You need something extra. The config/routes.py file will need to have these entries:
map.resource('book', 'books')
map.resource('chapter', 'chapters', parent_resource=dict(member_name='book', collection_name='books'))
map.resource('page', 'pages',
path_prefix = '/books/:book_id/chapters/:chapter_id',
name_prefix = 'page_'
)
The route_dict dictionary still has all the information you need. I haven't tried this beyond three resources.

Tuesday, January 01, 2008

Fireworks from the Balcony.


Fireworks from the Balcony.
Originally uploaded by simonwittber
NYE 2008 Fireworks in Perth, Western Australia. Taken from my balcony.

Popular Posts