The re-re-rising

Posted in Twisted Pair with tags on 2012/01/16 by Adam Griffiths

Twisted Pair are back at work full-time.

Shock goes Open Source

Posted in Development, Shock, Twisted Pair with tags , , , , , , on 2011/12/04 by Adam Griffiths

Today marks a historic day for Twisted Pair, as we release the full source code to the Shock C++ Cross-Platform library.

The project files and Socket module are currently missing.

When I get time, I’ll take a day to create the project files for MSVC, Eclipse and XCode.

Look out for PyGLy, our Python graphics library, on GitHub soon.

Pyglet mouse events and rendering

Posted in Development, How To, Programming with tags , , , , on 2011/06/28 by Adam Griffiths

The Problem

I added mouse event handlers to my Pyglet application recently. I found when I moved the mouse over the window, my rendering started to create “ghost” images.

I finally found the solution hidden in the docs.

The pyglet application event loop dispatches window events (such as for mouse and keyboard input) as they occur and dispatches the on_draw event to each window after every iteration through the loop.

So every mouse move (or any other event) triggers Pyglet to call “on_draw”.

But because I’m controlling my own render loop at 60Hz, I didn’t see a need to hook into this event. So I assume Pyglet is attempting to render the scene itself, and it’s failing miserably.

This is really bad design! What if I have lots of events that are seperate? Looks like Pyglet is going to hammer the “on_draw” event.

The Solution?

Well the basic solution is to ensure you’ve hooked into the “on_draw” event and just connect it to your render call. Don’t connect it to your game update logic or you will end up updating everything.

But…

This means your frame rate will vary depending on user input, and may even end up running balls out. Which could turn a simple game into a system hog. My basic application goes from 1% (of 2 cores on a dual core system), to 20% with the mouse moving.

It also means that you need to decouple the rendering from the system update, as each event you have scheduled will trigger an “on_draw” event. If you don’t decouple them, you will render each frame twice!

The Proper Solution?

We need to over-ride the “EventLoop.idle” method as mentioned in the docs.

The code without “on_draw” looks like this:

def idle( self ):
    """An alternate idle loop than Pyglet's default.

    By default, pyglet calls on_draw after EVERY batch of events
    which without hooking into, causes ghosting
    and if we do hook into it, it means we render after every event
    which is REALLY REALLY BAD
    http://www.pyglet.org/doc/programming_guide/the_application_event_loop.html
    """
    pyglet.clock.tick( poll = True )
    # don't call on_draw
    return pyglet.clock.get_sleep_time( sleep_idle = True )

def patch_idle_loop():
    """Replaces the default Pyglet idle look with the :py:func:`idle` function in this module.
    """
    # check that the event loop has been over-ridden
    if pyglet.app.EventLoop.idle != idle:
        # over-ride the default event loop
        pyglet.app.EventLoop.idle = idle

The “on_draw” function also calls pyglet.window.flip() for us, so now we need to do that after our rendering. So add the following (obviously you need to change the window variable depending on what you’ve called it):

# switch out the default idle function for ours
patch_idle_loop()

def render( self ):
    # do render here
    # flip the buffers
    self.window.flip()

And we’re done! No more superfluous “on_draw” events and my simple application no longer spikes the CPU usage when the mouse is moved!

Registering Event Handlers in Pyglet

Posted in Development, How To, Programming with tags , , , , , on 2011/06/25 by Adam Griffiths

The Problem and Pyglet’s own solutions

Pyglet’s documentation suggests a number of methods to receive events.

The recommended method of using @ decorators works for global methods where the event object is known. But if its for a class method or the event object is passed in later, this will not work.

The alternative is to simply over-write the existing handler with something like

window.on_resize = self.on_resize

Unfortunately most of them end up with the following error:

window.set_handler( window.on_key_release, self.on_key_release )
AttributeError: 'Win32Window' object has no attribute 'on_key_release'

This discussion on the developer list explains it. This method only works when the platform’s window class has an existing method to handle the event. And not all events are handled by default, so when you come across this, BOOM!

Even then, when it works this is also a double edged sword. The existing handlers are there for a reason! For example, if you over-write the on_resize method of Window your application will no longer draw (took me a while to figure this out).

So yes, Pyglet’s documentation is really, REALLY, asking for trouble.

The Proper Solution?

Use the “push_handlers” method.

Pyglet automatically detects a method with the event’s name and dispatches the event.
So we can just add methods to our class and we’ll automatically receive the events.

class Test:
  def attachToWindow( self, window ):
    window.push_handlers( self )

  def on_key_press( self, symbol, modifiers ):
    # method name matches the 'on_key_press' event!
    print "Keypress"

Or we can manually specify which events we care about.
If we do this, we must specify the actual function that receives the event.

class Test:
  def attachToWindow( self, window ):
    window.push_handlers( on_key_press = self.on_key_press )

  def on_key_press( self, symbol, modifiers ):
    # method name matches the 'on_key_press' event!
    print "Keypress"

Example of Minecraft style polygonisation

Posted in Development, Programming with tags , on 2011/06/17 by Adam Griffiths

Good walkthrough of rendering a voxel volume from start to finish in a Minecraft style.

It has the following problems however:

  • Single volume, no hierarchy.
  • Lack of hierarchy makes polygonisation harder, it must be done in one sweep.
  • Lack of hierarchy makes modification harder.
  • It performs 2 sweeps of the volume, one to calculate number of primitives, another to create them.
  • The C functions don’t compile in MSVC2008.

But it’s a good source of information on lighting and shader implementations.

Grouping Voxels with Hilbert Curves

Posted in Development, Programming with tags , , on 2011/06/17 by Adam Griffiths

A friend suggested quite a good idea.

Represent Voxels internally using a Hilbert Curve, the same algorithm XKCD used to display a map of IPv4.

Once you’ve got this, you can perform an RLE compression algorithm to it.

 

This paper discusses using Octrees and Hilbert curves to represent masses of voxel data.

RLE? That’s so yesterday!

Posted in Development, How To, Programming with tags , , , on 2011/06/11 by Adam Griffiths

Before writing my RLE implementation, a friend sent me a link to the blist package for Python.

I didn’t see anything amazing on the front page. Makes a 5M size list. Sure, whatever.

What the front page fails to say is that creating that 5M size blist is insanely fast. Because it doesn’t blindly allocate memory like a normal Python list would.

The “blist” list type is faster to add / remove than a Python list, and it supports copy-on-write semantics.

So I’m actually going to remove my cryptic RLE encoding and return to normal 3D array semantics using blists!

Continue reading

Creating Voxel Volumes Quicky in Python Part 2

Posted in Development, How To, Programming with tags , , , on 2011/06/10 by Adam Griffiths

So we created a volume pretty quickly Part 1, we also implemented basic RLE and Position Aware RLE (PARLE).

Read on for a few minor improvements we can make with little effort.

Continue reading

My Favorite Thing…

Posted in Rant, Uncategorized with tags , , , , on 2011/06/10 by Adam Griffiths

FM transmitters on the same frequency clash and quite often SWAP the audio in 2 cars.

My favorite thing is to leave my FM transmitter on my phone at the default frequency of 88.1 and play crazy zombie music while I drive around.

I listen for audio clashes and look around for the person who is totally confused as to why their iPod has become possessed.

Even better is when you can hear their songs and they start to rapidly change as they frantically try to fix it.

Run Length Encoding in Python

Posted in Development, How To, Programming with tags , , , on 2011/06/10 by Adam Griffiths

The following code is my implementation of RLE in Python. I’ve included a method to modify values without having to decode the entire value.

Please note that this algorithm is inferior to the RLE with Positioning I posted about here.

Continue reading

Position Aware Run Length Encoding in Python

Posted in Development, How To, Programming with tags , , , on 2011/06/10 by Adam Griffiths

I mentioned previously wanting to improve the RLE to include position information. I’m sure it’s already got a name, but I’m going to call it Position Aware RLE (PARLE).

Below is the code I’ve written to accomplish this. I’m sure someone can come up with a more concise way of writing it, but this is the best I can do at the moment.

Continue reading

Creating Voxel Volumes Quicky in Python

Posted in Development, How To, Programming with tags , , , on 2011/06/09 by Adam Griffiths

Creating large chunks of memory is quite tricky in Python because of a number of overheads. I’ve been attempting this myself and have found a fast method to do this which combines a few handy optimisations we would need later on for a Voxel Engine anyway.

Please be aware that the code evolves along the way, so don’t blindly copy and paste the first examples =).

Also, the WordPress theme is cutting of some text. If you copy and paste it, it is still there.

This post is continued in Position Aware RLE, RLE and Part 2.

Continue reading

Amnesia… really

Posted in Uncategorized with tags , on 2011/05/28 by Adam Griffiths

Amnesia is a game I can’t play.

I’m not ashamed to admit that. There are a number of games I can’t play. System Shock 2, Doom 3, Blair Witch, the list goes on.

Anyway… Amnesia… I bought it because Thomas Grip is a friend of a friend of mine and I wanted to support him. But I’ve never even installed it.

I was telling a few friends about Amnesia last night. They were pretty excited by what I said.

I wake up this morning, Amnesia is in my Steam Favorites list……….. but how? It wasn’t in there before! My computer was off when I got home so I can’t have done it myself.

But there it is, between Alien Swarm and ArmA 2… seriously… wtf…

Game mechanics: Waterloo

Posted in Game Design with tags , on 2011/05/27 by Adam Griffiths

I hadn’t heard of this game before. Waterloo has some interesting game mechanics.

About the game:

  • RTS
  • Play from the point of view of a commander on the battlefield (literally).
  • Move your HQ to get to a better position.
  • Orders are dispatched by messengers in the form of written notes (literally! It has a text interface!).
  • Messengers take time to arrive and can even be killed en-route.

Four words: HOLY SHIT THATS AWESOME.

Pinning Eclipse to the Windows 7 “start bar”

Posted in How To, Programming with tags , , , , on 2011/05/26 by Adam Griffiths

Eclipse and Windows 7 have a bit of a feud. There is no option to pin Eclipse to the start bar. If you create a shortcut you can pin the shortcut, but when the app is run it creates a second item.

Found a post that fixes this annoying issue.

Be aware that you’ll need to edit the file as Admin if you installed Eclipse into a system location. Best way is to go Start > “WordPad” > Right Click > Run as Administrator, and then open the file from inside the application.

Building PyBullet on Windows

Posted in How To, Programming with tags , , , on 2011/05/24 by Adam Griffiths

PyBullet is a wrapper around the popular Bullet C++ physics library.

Once you’ve build the C++ Bullet library you can then build PyBullet.

The PyBullet documentation states to use the –include-dirs directive to add the Bullet include path, but it also requires the numpy include directory which didn’t resolve automatically for me. Unfortunately you can’t just append it to the –include-dirs flag.

I resolved it with the following:

cd path\to\PyBullet

set INCLUDE=%INCLUDE%;c:\path\to\python\site-packages\numpy\core\include

python setup.py build_ext –include-dirs c:\path\to\bullet\src –library-dirs c:\path\to\bullet\msvc\2008\lib\Release

Obviously you replace the \msvc\2008 directory with the appropriate one if you didn’t build the vanilla target.

After this, copy the file PyBullet\build\lib.win32-2.6\bullet\bullet.pyd to PyBullet\bullet.

Include the PyBullet\bullet directory in your Python project and import.

You should now be able to do the following:

import bullet.bullet as bullet

print help(bullet)

A good case for mandatory castration

Posted in Rant, Uncategorized with tags , , , on 2011/04/20 by Adam Griffiths

Murtle76 not only hates a game he didn’t bother to play, but insists that he isn’t insulting or annoying anyone…

Steam region pricing is getting rediculous

Posted in Games Industry, Rant, Uncategorized with tags , , , , on 2011/04/14 by Adam Griffiths

This discussion regarding Borderlands pricing differences, although not a big deal this time, is the latest in a long line of regional pricing FUBARs.

I saw that Borderlands standalone (US$7.49) and Borderlands GOTY edition (US$7.50) were both on the “Top Sellers” list.

I thought perhaps people were boycotting the DRM encumbered DLC for the game (included in the GOTY edition), which made me happy!

Then I checked the forums and realised I was wrong. Different regions, again, have vastly different prices:

US pricing:
Borderlands GOTY = $7.50

Borderlands = $4.99

DLC = $7.49

Borderlands + DLC = $12.48 (greater than GOTY by $4.98)

AU:

Borderlands GOTY = $7.50

Borderlands = $7.49

DLC = $7.49

Borderlands + DLC = $14.98 (greater than GOTY by $7.48)

UK:

Borderlands GOTY = £7.50

Borderlands = £4.99

DLC = £4.74

Borderlands + DLC = £9.73 (greater than GOTY by £2.23)

Euro:

Borderlands GOTY = €12.50

Borderlands = €4.99

DLC = €5.99

Borderlands + DLC = €10.98 (less than GOTY by €1.52)

As you can see, this pricing is literally schizophenic.

I don’t believe this is Valve (although their Steamworks page does say that they will suggest pricing for games), I think this is the publishers stepping up pressure on Valve to fall into line. And unfortunately it’s working.

I made a comment that perhaps we should all band together to make a “Steam Gifting Co-operative”. Thing is, I was serious.

Many deals in Europe or the AU are far inferior to the US pricing. The region banning is stupid. This usually isn’t Steam but government ratings forcing publishers to offer modified versions (eg. L4D2 with fading out corpses instead of normal version). Grand Theft Auto: Vice City is still NOT on steam in Australia (thanks guys, you forced me to pirate it) although GTA3 and GTA:SA finally are.

Gifting gets us around this. It can also get us around the price issues. The only problem I can see is something like this happening if the “giftor”s bank account goes into the negative. Which is pretty horrific.

People would be re-imbursed for gifts (this isn’t a charity!). The only problem is ensuring that the “giftee” pays the “giftor”. Most bank transfers take a day and by then most deals would be over. I believe PayPal transactions are instantaneous, but I’m not sure. If it is, this would negate this issue.

I think a gifting co-operative is a very realistic and simple way of negating some of the publisher’s influence on Steam.

There are a few forum threads doing exactly this (NeoGafAwkward Zombie), but we need to make it more formal and easier to use.

There needs to be a way to:

  • Request a gift from a specified region (“giftee”).
  • Notify of our intention to fulfill a request (“giftor”).
  • Select a “giftor”.
  • Notify of payment sent, gift sent, gift received.
  • Comment and add to user’s reputation (ala Amazon) for both “giftee” and “giftor”.
  • Cancel a gift request.
  • Quickly view current gift requests with filters for region, age and user rating.

How many times do we have to say it?

Posted in Games Industry, Rant, Uncategorized with tags , , , , , , on 2011/04/13 by Adam Griffiths

DRM doesn’t fucking work!

Next talk like a pirate day

Posted in Rant, Uncategorized with tags , on 2011/04/12 by Adam Griffiths

This year my friends… this year… “Mutambo” will be heard.

Design a site like this with WordPress.com
Get started