Jump to content

  • Log In with Google      Sign In   
  • Create Account

Satisfaction Guaranteed*

middle of freaking nowhere

Posted by , 28 October 2005 - - - - - - · 221 views

Ah thank god.

My family recently got a cabin in the middle of freaking nowhere of NY state. So I've been staying up here for a week as it's a much better environment to get work done. But the internet hasn't been hooked up until today. I was doing pretty well surviving for the first few days, but then I started going a little stir crazy. Everything's all better now.


Posted by , 23 October 2005 - - - - - - · 247 views

Status check:

My dream of interactive programming continues to elude me. I've gotten it to work in special cases, but I want to be able to do it everywhere, without too much set-up work. BeanShell seems to have problems if you a) load a script, b) create an object with that script, then c) reload the script and try to use newly-defined code on that object. The object hangs on to references to the old script's structures. So I actually got an error that said "Error: Cannot cast class BlockType to class BlockType", because one of the BlockTypes was the new version and one was the old version, and it didn't figure out that they should be the same just cause they have the same name. Oy.

I've been playing the game Psychonauts. The art is amazing. The animation is amazing. The level design, and the entire premise of the game is delightfully weird and great. If you take everything that was great about Grim Fandango and multiply it by 5 then that's what the game is like.

It's just too bad you need to endure hours of annoying platform-jumping to enjoy all that great stuff. The gameplay mechanics are the least revolutionary thing about the game, so much that they drag down everything else.

Overall I think that the whole "jumping" mechanic just needs to die. It was silly to begin with, and it's been overdone to death, so maybe as an industry we can all just collectively move on.

I have a logo!

Posted by , 13 October 2005 - - - - - - · 229 views

Astute readers will notice that the test code I posted 2 entries ago is the same code that renders the yellow spikey things in a circle. Except that the final version used 300 steps instead of 70, and the other values were tweaked too.

And, by the way, since the rendering was script code, I was able to fiddle with those numbers *live* and see the changes immediately. Interactive programming rocks. I think it might be worthy of writing a tutorial article, since it rocks so much.

Anyway, time to write a game.


Posted by , 13 October 2005 - - - - - - · 234 views

Woooo, just finished evaluating BeanShell. It's great!

The BeanShell version of that last test ran at 8 fps (where the pure Java version runs at 12 fps and the JRuby version ran at 3 fps). So the slowdown isn't too bad, plus the clincher is that I can copy-paste any performance-critical BeanShell code into java.

(ps, the reason those FPS numbers are so low is that the test is re-rendering the SVG tree on every draw. In the real game, if I do use SVG sprites, they'll be pre-drawn and cached)

Plus BeanShell gets a heap of bonus points because it worked the first time, and behaved just like I expected. I can't say the same for those other engines :)


Posted by , 13 October 2005 - - - - - - · 212 views

Yeah I change my mind a lot.

After evaluating Rhino, I came to this conclusion: really no scripting language has a very fluid way of passing Java objects to a script.

So with that knowledge in hand, I went back to JRuby because a) I have a crush on that language, and b) I do know a roundabout way to pass a java object to a ruby script (just use the BSF).

So I set up a performance test. On one side is this ruby code:

include_class 'SVGSprite'

def draw
num_steps = 70;

for step in 0...num_steps
angle = step * 1.0 / num_steps * 2 * 3.1415926545;
loc_x = 100+ 40*Math.cos(angle);
loc_y = 100+ 30*Math.sin(angle);
$sprite.setRotation(angle + 3.1415926545/2);
$sprite.setPreferedSize(2, 15);
$g.draw($sprite, loc_x, loc_y, SVGSprite::CENTER);

public :draw

and the other side is the java version:

int num_steps = 70;
for (int step=0; step < num_steps; step++)
double angle = (float) step / num_steps * 2 * Math.PI;
double loc_x = 100+ 40*Math.cos(angle);
double loc_y = 100+ 30*Math.sin(angle);
sprite.setRotation(angle + Math.PI/2);
sprite.setPreferedSize(2, 15);
sprite.draw(g, (int)loc_x, (int)loc_y, SVGSprite.CENTER);

And the result is that the Java version worked 4 times faster than the JRuby version. That's ridiculous! The bulk of the processing time *should* be in the SVG rendering and the actual image drawing (the details of which are handled in java code), but somehow JRuby manages to take forever doing its thing. So that's it, that's the nail in the coffin, I'm done with it I promise.

So I think I'm going with BeanShell like H_o_p_s suggests. The nice thing is BeanShell looks a lot like Java, so if I ever get worried about performance, I can just copy-paste BeanShell code into java.

Also, while I had JRuby working, I did get to enjoy a few moments of interactive development (that is, changing the code while the game is running, and seeing the results right away). And let me tell you, it was delightful.

tool overload

Posted by , 11 October 2005 - - - - - - · 267 views

Okay, I'm coming to terms with the fact that I am suffering from tool overdose.

Batik? Cool, but it doesn't really help me.

JRuby? The language looks fun, but the Java->JRuby interaction really has been a pain. I can't get it to work the way I want, plus there's something about the implementation that makes it really inefficient. Every time you pass JRuby code a Java object, it seems like it needs to fully ruby-ize the java object, and if you pass it a big object (like say Graphics), it literally sits there working for 10 seconds. I'm not going to have a loading bar for my scripting engine! (though they say this inefficiency will be fixed in the December release)

So JRuby is outta here. Hopefully sometime in the future I'll have an excuse to learn this fun language.

Rhino is looking better and better, I think I'm using that now. It seems to be the only library I can find that has a sane way for Java code to call a scripted method. javascript might not be as charming a language as Ruby, but as long as I have some way in my game to interactively change the game code, I'll be happy.

My tv has gone crazy

Posted by , 07 October 2005 - - - - - - · 88 views

They are showing South Park on WPIX and Family Guy on TBS. I don't know which way is up anymore.

java svg code

Posted by , 07 October 2005 - - - - - - · 157 views

I figured someone might be interested, so here is my java code for getting a simple SVG-backed sprite up and running:

import org.apache.batik.gvt.renderer.StaticRenderer;
import org.w3c.dom.svg.SVGDocument;
import org.apache.batik.bridge.*;
import org.apache.batik.gvt.*;

import java.awt.geom.*;
import java.awt.*;

class SVGSprite
// svg data
SVGDocument document;
BridgeContext bridgeContext;
StaticRenderer renderer = new StaticRenderer();
SVGUserAgent userAgent = new SVGUserAgent();
static GVTBuilder builder = new GVTBuilder();

double documentW, documentH;
double preferedW, preferedH;
int offscreenW, offscreenH;

// sprite data
double rotation = 0;
double translate_x = 0, translate_y = 0;
boolean needs_redraw = true;

// flags
public static final int CENTER = 1;

public SVGSprite(String svg_file_name)
document = SVGLayer.loadDocument(svg_file_name);

bridgeContext = new BridgeContext(userAgent);

GraphicsNode root = builder.build(bridgeContext, document);
Dimension2D docSize = bridgeContext.getDocumentSize();
documentW = docSize.getWidth();
documentH = docSize.getHeight();
setPreferedSize(documentW, documentH);

needs_redraw = true;

void setPreferedSize(double size_x, double size_y)
preferedW = size_x;
preferedH = size_y;
double max_diam = Math.max(preferedW, preferedH);
max_diam = max_diam * 1.5;
offscreenW = (int) (max_diam);
offscreenH = (int) (max_diam);
renderer.updateOffScreen(offscreenW, offscreenH);
needs_redraw = true;

void setRotation(double rot)
rotation = rot;
needs_redraw = true;
void setTranslation(double x, double y)
// this method can useful for setting the draw coordinates with float-precision
translate_x = x;
translate_y = y;
needs_redraw = true;

AffineTransform cached_transform = new AffineTransform();
void redraw()
cached_transform.translate(translate_x, translate_y);
cached_transform.rotate(rotation, offscreenW/2f, offscreenH/2f);
cached_transform.translate((offscreenW - documentW)/2f, (offscreenH - documentH)/2f);
cached_transform.scale(preferedW/documentW, preferedH/documentH);
renderer.repaint(new Rectangle(0, 0, offscreenW, offscreenH));
needs_redraw = false;

void draw(Graphics2D g, int loc_x, int loc_y, int flags)
if (needs_redraw) redraw();

if ((flags & CENTER) != 0)
loc_x -= offscreenW;
loc_y -= offscreenH;

g.drawImage(renderer.getOffScreen(), null, loc_x, loc_y);
//g.drawRect(loc_x, loc_y, offscreenW, offscreenH);

// *************
import java.awt.*;
import java.awt.geom.*;
import java.io.IOException;

import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.dom.svg.SVGDocumentFactory;
import org.apache.batik.util.XMLResourceDescriptor;
import org.w3c.dom.svg.SVGDocument;
import org.apache.batik.bridge.*;
import org.apache.batik.transcoder.*;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.renderer.StaticRenderer;

public class SVGLayer
protected static SVGDocumentFactory factory;

static SVGDocument loadDocument(String uri)
if (factory == null)
// create document factory
String parser = XMLResourceDescriptor.getXMLParserClassName();
factory = new SAXSVGDocumentFactory(parser);

try {
return factory.createSVGDocument(uri);
} catch (IOException e)
return null;
// **************

import java.awt.*;
import java.awt.geom.*;
import org.apache.batik.bridge.UserAgentAdapter;

class SVGUserAgent extends UserAgentAdapter
AffineTransform transform = new AffineTransform();

public AffineTransform getTransform()
return transform;

public Dimension2D getViewportSize()
return new Dimension(100,100);

public void displayError(String message)
throw new RuntimeException(message);
public void displayError(Exception e)
public void displayMessage(String message)
throw new RuntimeException(message);

// ****************

and here is sample code of it being used:

public void paint(Graphics2D g2d)
SVGSprite = new SVGSprite("file:a.svg");
sprite.setPreferedSize(20, 20);
sprite.draw(g2d, 10, 10, SVGSprite.CENTER);

September 2016 »

25 2627282930 

Recent Entries

Recent Comments

Recent Entries

Recent Comments