Wednesday, July 16, 2008

wxPython Integration

Finally uploaded some new stuff.

Two more 'main' files.

One has the game running inside a basic wxPython window.

Another extends the AUI Docking Window Manager Demo as can be seen in the photo here.

Wednesday, May 7, 2008

RoboCute Has Left The Building

I'm going back to doing C++ over at Botworx. Vacation is over!

Thursday, May 1, 2008

May 01, 2008


It's been 9 days since the last post so I guess I should write something.

Let's see ...

Refactored a ton of stuff.

Moved code into the __init__.py files that belong there.

Using OpenGL quads for the widget skins now. No more cracks while scaling, plus it's faster. Also started work on a DocWidget class for displaying help files, use as a console, etc.

Fleshed out the Catalog to include all the items from the PlanetCute tile set.

Right now I'm trying to implement persistence which will probably take the rest of the week, since I'll also need to come up with File Dialogs also.

That's it for now.

Tuesday, April 22, 2008

New Render Batching and Unified Front End

Rendering has been significantly sped up by batching OpenGL calls on a per terrain page basis. Thankfully pyglet has support for this kind of thing or I'd be up a creek. FPS ranges from 60 for closeups to about 10 - 20 for birds eye view.

The front end has been unified where it is possible to not only create avatars, but also take control of them by pressing the 't' key while the selector is over them when using the Designer. Pressing the escape key takes you back to the tool/avatar that you were using previously.

Still a long way to go though.

Friday, April 18, 2008

On to Better Things

Definitely, this paging stuff is getting boring.

Short story fast ... I put the page caching into a Clip class that the rendering process uses. When the Clip crosses a page boundary I just update the current page location and invalidate the cache. The cache is set at 3x3 but can be any size really.

This results in seamless traversal of the World.

This means it's good enough to move on to other pressing needs such as AI, the user front end and more efficient rendering.

Better things to come!

Wednesday, April 16, 2008

Where's Waldo?

Yes, yes. The back end is getting there.

The program as it is now can infinitely tile, but now I have to work on the camera code to shift the page map.

Then it's back to the front end which is the AI/user interface code, since I have some new ideas to clean that mess up.

After that I'm going to work on improving the frame rate. As you can see it's not too hot on this zoom level. Decent at 1:1 though.

Time to commit!

Slow and Steady

Well, the slow part is right. Steady is coming, eventually.

Making the move to a paged world opens up a lot of possibilities and a lot of headaches.

The picture was supposed to be full of treasure, but only one of the treasure bots ran. That's an easy fix. I just wanted something to slap on the blog even if it's not perfect.

Back to work.

Tuesday, April 15, 2008

Reconstruction

There is some major reconstruction going on.

No paging terrain yet but I'm working on it.

I've got things going in a more document/view direction now.

Too busy to tell more!

Monday, April 14, 2008

Paging Terrain

This is going to be a pain.

Alright then. I created GridPage and GridPageVu classes that take over the functionality that the Scene class was providing.

This means it's possible to have multiple pages right now.

I just need to figure out how caching and indexing is going to work.

Hmmm.....

Designology

Wow, I've got a full head of steam going now!

I reworked the GUI code where it's starting to look like a real widget framework.

We now have a catalog with multiple pages.

All the zoom issues have been worked out, there just remains a problem with tiling where you see hairline fractures between the tiles when the scale is not 1:1. There's a rounding problem afoot. Maybe I'm supposed to tile to a framebuffer first, and then blit?

When it came time to write classes for all of these new items in the catalog, I thought 'There has got to be a better way!'

So instead of writing a class for each item, there will exist only one class for multiple items of a similar category. For the blocks, landscape and treasure this really makes sense.

As you can see, I decided to go the spreadsheet route again to define the catalog. It works pretty well, just property/value pairs in a row.

The catalog reader is able to instantiate a class, pass the item that was used to create it and also assign attributes on the fly!

This means that it will be possible to create new catalog items by mixing and matching different classes. Say, you want the Boy with a different brain, or with a different image, or whatever.

Okay, I have got stop putting off committing this darn thing to SVN. If you download it just realize it's only two weeks old!

Sunday, April 13, 2008

Selectionology

This is a lot of fun but it's also a lot of work. If it weren't for Python and pyglet, I'd probably have thrown in the towel by now.

As you can see in the image I have multi-select working now. You can add to the selection with the Ctrl key and create selection ranges via the Shift key.

I still need to work on clearing selections, I guess using the escape key. Since I'm using escape for exiting the program I need to write code to change that behavior.

I modified the way catalog pages are displayed. I decided to scale the original images using OpenGL instead of manually creating thumbnails. Now I need to rewrite the code that calculates the page height taking the scaling into account. Centering also needs to be fixed.

Hopefully, I can pound this into some consistent form and then I'll commit to SVN.

Saturday, April 12, 2008

Zoom, Zoom, Zoom - Part 2

That was pretty simple to fix. I only had to upgrade the culling and the camera code. Other stuff like mouse picking works through OpenGL via unproject so no changes there. Sweet!

Zooming works through plus and minus on the numeric keypad.

I'm thinking it's time to do a commit to SVN even though this is in a haphazard state between 'Is it a game?' or 'Is it a game editor?'.

Zoom, Zoom, Zoom

It occurred to me that editing on a 1:1 scale would be impractical. So I inserted glScale(.5, .5, .5) into the pipeline as a test.

Looks sweet! Or, it will after I add all the necessary code to handle scaling properly.

I think it's probably time to look into rendering to a frame buffer also. This is really going to kill my frame rate!

Selector is Working

Five minutes after I made the last post I realized what was happening. I was repeating the same Cell across. The bug was in the spreadsheet reader.

As you can see I have the code rigged to where clicking an image deposits a block where the Selector is.

Work, work, work.

The Selector

After deep meditation, I decided that the Selector is a Robo, meaning a Character type class.

This way I don't have to add any extra code for navigation.

I was going to use the mouse to select blocks, but since blocks are singletons and therefore have no real coordinates, this was problematical.

Frustration

The picture to the right here shows a rendering bug I can't seem to quite figure out. Which is odd since all of this code is really simple!

Once the Selector walks onto an empty cell it gets redrawn across the screen. What's really odd is that if I move another cell to the right it's still repeating from the first blank cell across.

Using PyDev's debug mode doesn't reveal anything being abnormal. What gives?!!!

Friday, April 11, 2008

The Catalog - Part 2

I decided to attach the catalog page to the dashboard layer and fixed the dashboard layer to layout/draw multiple items.

I need more dash items like one to display the current item we are painting with.

Alright then. I've got enough to start with ...

Time to start doing some mouse action handling!

The Catalog

Python and pyglet makes for wicked fast progress!

Instead of getting carried away and trying to write a widget library from the bottom up, I'm just going to repurpose what I have and refactor later on.

Basically I took the Bubble code, copied, pasted and modified it to work in the vertical direction, resulting in a widget.List class.

I took the easy way out and repurposed the scene reader to read in catalog pages from a spreadsheet. Each sheet is a page in the catalog. Each row describes a catalog page item. Name, image, creation code, etc.

Now I need to generate thumbnail images for each item because the actual sprites are too big. Joy.

I also need to implement scrolling at some point.

Getting closer though!

Thursday, April 10, 2008

World Building

This seems like the logical next step since the spreadsheet method is getting old.

I'm not really looking forward to it though. It's going to be tough with a lot of nit picky details. Sounds too much like work!

The Catalog

Classes need to be written to implement a catalog of items with categories and subcategories. This catalog will be specified in XML.

The Categories

Too simple to elaborate on right now.

The Items

Each item element in XML will specify the item name, image and Python creation code as it is using the current spreadsheet method.

The User Interface

Luckily, I wrote an ultra simplified user interface in CEGUI for Botworx that I can copy, paste and modify.

The unlucky part is that I need to write something like CEGUI!

Final Thoughts

Too much like work.

Wednesday, April 9, 2008

Clean Up Time

Heh, that's what I tell my three year old nephew when it's time to put his toys away. Clean Up Time! Yay! Not.

Unfortunately, when you make a mess and actually care about what your writing it's necessary.

There was a bunch of Noob mistakes that needed cleaning up. Thanks to some kind people from the PyWeek competition I was able to take care of them in short order.

I was using tuples for block coordinates and transforms, now these are classes.

Basic dumb stuff that needs to be done. Boring!

Google App Engine

I found out about the preview release of Google App Engine while browsing Google News last night.

Rarely do I get excited about software releases of any kind. This one is different.

What can I say? Visit the link. This one is HUGE!!!

Tuesday, April 8, 2008

SVN Work Flow

I updated SVN.

I think I have the proper work flow figured out now.
  1. SyncBack to Deploy/robocute
  2. SyncBack to SVN/robocute
  3. Commit to SVN
Deploy/robocute is the folder where I backup to create zips that serve as local backups and contains pyglet so it can be used as a download that only requires Python 2.5.

SVN/robocute is the folder that serves to commit to and in the future update from SVN sans pyglet.

The backups are stripped of all unnecessary garbage by SyncBack. (Need to filter out those darn Thumbs.db before the next commit!)

If other folks start contributing I'll add another SyncBack Task that copies from SVN to my real development directory, which will get backed up to the Deploy folder beforehand just in case.

Since this project is alpha, I'm going to target alpha libraries as well. This means that if you checkout from the SVN you need to grab pyglet from their SVN as well. That's not too painful is it? :)

Alright, I'm going to hold off adding new stuff and do some cleanup first.

Now That's a Lot of Treasure!

I wrote a class called TreasureSpreader yesterday.

This screen shot is the result. Today, I'll write code which calculates a random probability of each square containing treasure which should only take a few minutes. I tested it with total spreading to make sure every cell was getting visited.

I was going to go into more depth in this article but I'll wait until I refine the code some more. Yes, it's flood fill, but I'm separating the flood from the fill to make it more reusable. Should be cool!

Monday, April 7, 2008

I Tried

Well, this is all the work I care to spend on a cute robot icon.

Here is a link to the tutorial for doing Bubbles in InkScape.

Hmmm.... it'll do for now.

Cute Robots


I was searching for icons of cute robots and ran across Apple's Automator.

Now that's one cute robot!!! I hope this qualifies as fair use. :o

Darn it. I need some icons for this project! I would be in definite trouble if I used this one. I am interested in looking at the software though.

Looks like I'll have to give InkScape a shot and take a break from programming. Drats!!!

The Night After

I made a lot of progress today.

It turned out the block culling was the easiest thing to do with the biggest payoff. I did end up changing the block coordinates to y-up.

Plus a lot of other little changes and ideas along the way.

Now I need to check this into SVN and put a .zip on Google Code.

Sunday, April 6, 2008

Culling

Hmmm ... there's two ways to do this.

Easy way is to iterate over all rows and columns and clip at the draw level.

Slightly more difficult is to only draw the cells that need to be drawn plus clip.

Cell? That's probably a good way to look at it. I'm going to start using that terminology.

Block Coordinate System

Well, I started to change it and changed my mind instead. :)

Since the blocks are rendered back to front and people are used to thinking in a y-down system I'm going to leave it be.

The extra math isn't all that bad.

I'll just think of it as the z plane. Which it is if you think about it.

Coordinate Systems are a Headache

It's like big-endian v.s. little-endian only worse.

I made the mistake of using y-down for the block coordinates because I was importing from a spreadsheet.

OpenGL of course uses y-up. That means I wrote things I shouldn't have had to. And now I need to fix them before I go any further.

If only it had occured to me to just reverse the rows after I read them in!

I still don't know what the game plan for widget coordinates would be since they are y down.

I might flip the coordinate system for that ... Ugh!!!

I hate coordinate systems!

Operation Share and Care a Success!

Well, that took all of 10 minutes. The funny thing is that I imported my deployment directory that I use to back things up with SyncBack.

This was inadvertently the best thing I could have done! Because that directory is stripped of all the garbage such as .pyc files.

Sweetness.

Sharing and Caring

Google Code, SVN, and TortoiseSVN = CONFUSION.

As luck would have it some kind person wrote a good article about it that I'm going to read.

So, I'm going to take the plunge today and figure this out. Besides sharing with others it's also a good way to back things up. I'll probably still back up locally just in case I lose internet or something.

Singleton Blocks

It seems kind of extreme to have the blocks themselves be singletons. I could just have shared resources, image, etc. The thing is, I really don't see why they can't be shared.

If we use a 3D graphics mesh as an example, the grid can be likened to triangles and these blocks are the textures. I'm just going to roll with it until something really ugly pops up.

A Humourous Note

When I reimplemented the Stone Blocks as singletons the AI became confused. That was because I let the singleton approach lapse and started doing things I shouldn't like comparing blocks!

The correct approach is to compare Block Coordinates. I may want to create some kind of handle class that contains coords etc. Hmmm...

Lesson is: Don't Let It Lapse!

Singletons in Python - Take Three

This is starting to get old quick.

What about wrappers?

Say WaterBlock and WaterBlockImpl.

Then we use the universal metaclass approach and have the wrapper pass the key for WaterBlockImpl's __init__?

Well, the downside of this is even more code and double instantiation. Nuts.

I guess I'll just go with first instinct.

Singletons in Python - Take Two

After reading the post again I fully understand what's going on. This is a universal technique that can be implemented in the root. The downside is that a URI needs to be passed to each classes __init__ method.

I realized the stripped down version I created doesn't need the metaclass and looks like the solution I had been thinking about this past week.

WaterBlock_singleton = None

class WaterBlock(Block):
def __new__(cls, *args, **kargs):
global WaterBlock_singleton
if not WaterBlock_singleton:
obj = object.__new__(cls)
WaterBlock_singleton = obj
obj.__init__(*args, **kargs)
return WaterBlock_singleton
def __init__(self):
super(WaterBlock, self).__init__()
self.vu = BlockVu(self, 'Water Block.png')
The global is necessary because the actual class object doesn't get created until it's instantiated. If you try it inside the class definition you get this:

UnboundLocalError: local variable 'WaterBlock_singleton' referenced before assignment

This way is sort of messy, but I don't think there is a universal solution to the problem. I am not going to require passing some kind of class key inside of __init__

Therefore, I'll just run with this until a better solution comes along.

As a side note, the way I tested to see if this worked was by clicking on different Water Blocks. The selection code I wrote is universal and works on any object. I have it print the objects ID to the console as a default handler. Pretty cool.

Singletons in Python

Talk about confusion. I was thinking 12 ways to do it that I've seen. Probably more that that!

Here's a post that's pretty fresh that seems to be the direction to take.

Here's a first stab at it that works!!! It's a simplified version of what was in that post.

It's pretty messy. I'm guessing at what the author is getting at though. His code only needs to be implemented in the root class?

WaterBlock_singleton = None

class WaterBlock(Block):
#MetaClass
class __metaclass__(type):
def __call__(cls, *args, **kwargs):
return cls.__new__(cls, *args, **kwargs)
#Class
def __new__(cls, *args, **kargs):
global WaterBlock_singleton
if not WaterBlock_singleton:
obj = object.__new__(cls)
WaterBlock_singleton = obj
obj.__init__(*args, **kargs)
return WaterBlock_singleton
def __init__(self):
super(WaterBlock, self).__init__()
self.vu = BlockVu(self, 'Water Block.png')

The Morning After

PyWeek 6 is over. It's like Christmas came and went and now I have this deflated feeling. :(

To make matters worse, the final submission uses a debug level. I'm not surprised since I had gone several days without sleep trying to turn this into some kind of game. I probably should have just pulled the plug and declared DNF. Only then, I wouldn't have forced myself to semi-finish this dratted thing!

Final Analysis

This thing is a complete hog right now. I guess that's not surprising since I wrote it in a week.

I need to figure out the best approach for singletons to implement shared instances of the blocks. Originally I was using a dictionary and factory methods that worked well, but it's really useful to be able to just instantiate an object and get a singleton. Since I found like 12 ways to do singletons in Python this may take a few days to unravel.

Culling needs to be implemented. This might not be too hard since this is a rigid type world.

Using a spreadsheet to define the world is just a stop gap measure. I need to look into pickling, and write a world builder sooner or later. Probably later after these other issues are cleared up.

Future Directions

I think I'll continue to develop this as a board game for small children. The art is a perfect fit. The avatar counts off as it moves so that could teach counting and number recognition.

I also want to keep the game side of it simple until the rendering, etc. get's sorted out.

Too much!

Friday, April 4, 2008

Hee, Hee, Hee.

It's working! The query is returning the mouse pointer object ... so I'll temporarily cheat and get whatever is under that.

...

Okay I fixed it. This will work for now. I'm not sure about this technique. Maybe a more generic visitor pattern that walks the tree and can either draw or query?

Hope is alive!!!

A Long Night Ahead

Okay, I'm going to do a little brainstorming here on the Blog. It helps me get energized and I know these notes won't get lost!

Event Processing

Okay, I hacked this thing together in a week. A lot of the objects don't even have positions! The parent object sets the position in a graphics context and then calls draw on the children.

Idea: Piggyback mouse events inside the draw call. Yeah, probably not a long term solution but it will work for the time being.

Problem: Objects are drawn back to front!!! The one in back will get the event! Negative.

Solution? ... I'm thinking ... more along the lines of a query.

Get all objects at point x,y and reverse the list.

Hey, It could happen!

Thursday, April 3, 2008

DNF?

It's starting to look like 'Did Not Finish'. :(

There is only one day left and right now I'm writing the code to handle mouse events. Not good.

If I was smart I would have used PyGame or another game engine instead of writing my own.

If I was smart I would have gone with my first instinct to make some crappy looking Robot - Kung Fu side scroller.

Instead, I made a pretty killer start on the game framework of my dreams!

I can handle DNF. :)

Hello World!

After struggling with how to implement some sort of user interface, I finally decided that all of the interaction could occur through Bubbles.

To do this the Bubble needs to be stretchy. Since the Speach Bubble that comes with the PlanetCute set has a vertical gradient It can only stretch horizontally. So I chopped it horizontally into three slices where you blit both ends and use the middle slice to do the fill. Then you draw your text and buttons!

This is good enough for the contest, plus the gradient does look pretty sweet! After PyWeek 6 is over I'll do a Bubble that will stretch in both directions.

Wednesday, April 2, 2008

Milestone 1 Achieved!!!


Hey! I got the little dude moving around under keyboard control.

Not bad for 3 days work, considering I'm writing a game engine in addition to the game itself.

I fixed the way that a scene is described in a spreadsheet that is totally wicked. The cell where the girls are at contains the following.

[StoneBlock(), RampWest(), RoboCatGirl(), RoboCatGirl()]

Each cell represents a stack. By being able to dynamically evaluate this in Python not only was I able to get rid of the dictionary approach I was using, It opens up some interesting possibilities!

Most exciting of those is to write procedural block generators.

[FloodFill([GrassBlock()])]

Oh yeah! I'm getting pumped up now baby!

I give more credit to the guy behind Python than my own genius. Guido van Rossum. Any relation there to R.U.R. (Rossum's Universal Robots)? Just kidding. He's my new superhero!

Tuesday, April 1, 2008

RoboCute: An RPG Board Game


In order for this to be a game by the time PyWeek 6 ends, I need to scale down my ambitions somewhat, for now.

My thinking is to create a board game with RPG elements.

I think it will be fun. The Cuties will have robots as protagonists in the game, sort of like Team Rocket.

Rules: Rough Draft

Players roll the dice and pick up goodies on the block their Token/Avatar lands on.

Paths can split and rejoin. The Token/Avatar will query the user on these choice points.

Some blocks may contain mini-games. (This may be for a post-Pyweek version)

On random occasions Team Robo, whatever, will attack.

Battles will be purely non-physical/psionic and amusing. Rock, Paper, Scissors Attack!

In Closing

I have a lot of work to do in the next 4 days!

April's Fool

Look, It's RoboBoy and RoboCatGirl!

All that work just so he could have a buddy?!!! I feel like a fool thinking I could do collision and AI for this in a week. Well, I had doubts, but now that I know what's involved I need to scale down my ambitions.

So ... to avoid looking like the April's Fool I'm going to make this a board game! A Robot board game of course.

Monday, March 31, 2008

Looking Cute

Yeah ... but how is collision and AI going to work?!!!

I need to get basic player code working by the end of today!

Sunday, March 30, 2008

Leveling the Playing Field

This is only my fourth week programming in Python, and second week of learning Pyglet.

There is no way I am going to write a level editor!

Thinking about tile based games made me think of a spreadsheet. But the format needs to be cross platform and hopefully there is some free code in Python available to help me get rolling.

Open Document Format

I was fortunate enough to find examples in Python to import .odf files. I was using Google Spreadsheet which can export .odf just for fun, but OpenOffice has more compact exporting and I can directly edit the file on the hard drive.

Fun!

Introduction

RoboCute is my entry in the PyWeek 6 competition.

I was trying to think of some kind of juxtaposition to make things more interesting.

My first thought was Caveman Robot. Click the link for hilarity.

Then I thought about the movie Robot Monster. I watched that movie as a kid and it freaked me out. I saw it again last winter and I laughed so hard I fell off the couch!

What about Robot Viking I asked myself? Hmm ... still not original enough.

Finally RoboCute came about because I gave up trying to do my own tiles. So I'm using the most fabulous tiles I've ever seen! Free or not. Luckily their free.

Visit: Lost Garden: Danc's Miraculously Flexible Game Prototyping Tiles

Call me a wimp, call me unoriginal, but there are some interesting challenges ahead from choosing this tile set!