Categories
agile dev-process games industry

Problems to Avoid When Introducing Scrum to Customers

(I’m quoting a very handy short extract from Clinton Keith’s December 2007 Gamasutra article, so that I can find it again easily later. Clinton is/was the CTO of High Moon Studios, and is probably the most well-known proponent of Scrum in the games industry. Rather than wade through the whole article when I want to pass on some of his advice, I wanted to be able to copy/paste the relevant sub-bits)

Categories
computer games dev-process java tutorials programming

Writing games in Korean – part 1

First, check whether I can actually render Korean characters. I know that Unicode supports nearly all of the glyphs (or, more correctly it seems, “ideographs”) needed for Chinese, Japanese, Korean (typically abbreviated as “CJK”) – but I also know that MS Windows fonts are infamous for missing some/most/all of the unicode characters (there are tens of thousands of them, so this is not all that surprising – except that Microsoft has been shipping OS’s localized to those countries for many years now, so I’d hoped maybe they would include at least ONE “CJK + Latin” font on all machines by now, no? No; they don’t).

Quick test program using Java (NB: java one of the easier languages for this because it was invented late enough that Unicode had settled down, and so it has extremely good Unicode support built-in to the core libraries, unlike C++ et al. By default, Java uses unicode almost everywhere, so I don’t need to debug unicode support, yay!):

NB: …but then when I tried it I quickly discovered a problem. I quickly gave up on the obvious route, so might have missed a workaround, but… I could have done this using Java’s built-in GUI toolkit (Swing), which supports using any font as a text label. However, it seems there’s a design flaw in Swing that’s been around since 1997 (yes, folks, 11 years and counting): the only component that can have the font changed – JLabel – which is a “general-purpose” label for any GUI component (good idea!) … is incompatible with the only component capable of being a button – JButton – which is a “general-purpose” button. Crap. If I’m not missing something here, with one small piece of poor API design, Sun have made their *almost* international-friendly GUI system almost completely useless for multi-language GUIs. Just to be clear: it’s not specifically internationalization they’ve broken here: its a general issue – any forms of customized rendering cannot use the JButton / JLabel combo. Why? Why, why, why would you do such a stupid thing, after going to the effort of making these generic widgets? Oh, well. Custom rendering it is…

/**
 * Simple test program that renders Unicode characters from a particular font of
 * your choice, a couple of thousand at a time, automatically wrapping them based on
 * render width on screen.
 * 
 * You need to manually change the font name and the start/end co-ordinates of where
 * in the unicode constellation to render.
 */

import java.awt.*;
import javax.swing.*;

public class PaintSomeUnicodeChars extends JFrame
{
	void setup()
	{
		getContentPane().add( new charPane() );
	}
	
	public static void main( String[] args )
	{
		PaintSomeUnicodeChars window = new PaintSomeUnicodeChars();
		window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		window.setup();
		window.pack();
		window.setSize( 600, 500 );
		
		window.setVisible( true );
	}
}

class charPane extends JPanel
{
	public void paint( Graphics g )
	{
		int si = 44032;
		int ei = 46000;
		g.setColor( Color.red );
		g.setFont( new Font( "Verdana", 10, 40 ) );
		g.drawString( "Chars from " + si + " to " + ei, 30, 30 );
		
		g.setColor( Color.black );
		g.setFont( new Font( "Lucida Sans Unicode", 10, 20 ) );
		
		int accumulator = 0;
		int height = 20;
		int xwidth = getWidth();
		for( int i = si; i < ei; i++ )
		{
			char[] chars = Character.toChars( i );
			String drawString = String.copyValueOf( chars );
			int advance = g.getFontMetrics().charsWidth( chars, 0, chars.length );
			
			if( accumulator + advance > xwidth )
			{
				accumulator = 0;
				height += g.getFontMetrics().getHeight();
			}
			
			g.drawString( drawString, accumulator, height );
			
			accumulator += advance;
		}
	}
}

Why choose Lucida Sans Unicode?

Apart from the fact that it’s present on all modern Windows machines automatically, I cheated a bit and used Character Map (Start > Programs > Accessories > System Tools > Character Map) to quickly inspect each of the fonts already installed and find out which ones had lots of unicode in them. Character Map has a neat feature where it completely ignores missing characters, automatically skipping over them, so you can very quickly see if a font has lots of unicode, some, or very little.

Stepping through in the java app, I fairly quickly found lots of Unicode characters. success – I can correctly render arbitrary Unicode characters in java.

NB: important because it took a lot more lines of source than I expected; java’s built-in “char” datatype is incapable of being used to render Unicode, because it’s too small a range of values. That also means you can’t use ANY methods that take a char as argument (this is documented in the Java API docs for Character). I’d never really used the methods that take int’s as argument before…

Fonts…

Not really happy with the font, though, and it’s clearly missing a whole bunch of characters. Some googling for free CJK fonts found me that allegedly Arial Unicode MS would work – which comes free with Microsoft Office (which I have on one of my machines).

NB: the way font licensing works, it’s probably illegal to copy a font you have on one machine to another machine you own. Unless you can obtain the font from the original source (e.g. in this case by buying a second copy of MS Office).

Arial Unicode MS has lots of characters, but … they’re wrong. At least, one third of the ranges of Korean characters are completely useless, as far as I can tell, because whoever made this font (whoever Microsoft licensed it from?) didn’t read the spec carefully and stuck the wrong characters in from U+1100-U+11FF. More on this later…

Giving up on that font, I went looking for others. The first four or five I tried that didn’t look ugly were all from download sites in Japan or Korea and kept crashing on the download. I found a couple of places hosting UnBatang (“UnBatangOdal.ttf”) and claiming it was free, but the first I found where the download didn’t crash was on http://www.i18nl10n.com/fonts

UnBatang (the name you have to use in Windows / Java from inside an application in order to load it) seems to work very well. It has nicely painted ideographs for the main range of Hangul characters/syllables, and it has *correct* glyphs for the other two ranges (although they’re a bit ugly).

Unicode Hangul

Specifications for official standards tend to be big. Really big.

Specifications for anything to do with internationalization tend to be huge.

Add in localization and data-transfer between different cultures, and you can expect something gargantuan.

So, I was really really happy to find a downloadable copy of only the CJK Chapter of the Unicode 5.0 specification (it’s still a big document!). This contains a full explanation of what Hangul is in Unicode, where to find it (yay!), and why there are not one but three separate sets of Hangul glyphs.

Here’s the preface to the Chapter 12 PDF I downloaded, in case you want to find the spec / electronic version yourself:

Electronic Edition

This file is part of the electronic edition of The Unicode Standard, Version 5.0, provided for online
access, content searching, and accessibility. It may not be printed. Bookmarks linking to specific
chapters or sections of the whole Unicode Standard are available at

http://www.unicode.org/versions/Unicode5.0.0/bookmarks.html

Purchasing the Book

For convenient access to the full text of the standard as a useful reference book, we recommend purchasing
the printed version. The book is available from the Unicode Consortium, the publisher, and
booksellers. Purchase of the standard in book format contributes to the ongoing work of the Unicode
Consortium. Details about the book publication and ordering information may be found at

http://www.unicode.org/book/aboutbook.html

Unicode 5, Hangul, and Arial Unicode MS

So, armed with the offical spec, I read up on Hangul. What did I find?

The Unicode Standard contains both the complete set of precomposed modern Hangul syllable
blocks and the set of conjoining Hangul jamo. This set of conjoining Hangul jamo can
be used to encode all modern and ancient syllable blocks.

(this is the glyphs at U+1100–U+11FF)

“conjoining Hangul jamo” means “these glyphs have been positioned inside their spaces in the font so that if you need to make one ideograph out of, say, four Korean letters, you just pick the top-left version of the first letter, the top-right version of the second, etc, and OVERLAY all the glyphs, and what comes out will autamatically be correctly spaced out etc”.

What did the author of Arial Unicode MS do?

Made all those glyphs take up the full available space, and centre them horizontally and vertically.

Why? Seriously, why? Because any application that tries to render those characters is going to render them on top of each other (according to the specification, this is the ONLY point of having those characters), and you won’t be able to read at all what the letters say.

If you want to render just individual letters from the Korean alphabet, there’s a different range of Unicode where you can find them all centred etc (which Arial Unicode MS also has … so it seems to be just copy/pasting internally).

I guess the font author just didn’t read the spec. Or I’m completely misunderstanding the spec. But the fact that UnBatang spaces the conjoining jamos out in such a way that this works as I expected it to suggests to me that it’s the Arial Unicode that’s broken…

The joy of Conjoining

I couldn’t get hold of the Unicode spec section on how to conjoin, because of some mimetype problems between their server and my PDA’s web browser. I figured I could probably work it out by trial and error fairly quickly.

I can’t remember how to spell my name in Korean yet – I know the letters, I’m just a bit flaky on what the placement of them is. So, a quick experiment, to see how easy it is to position characters using the Conjoining Jamo from UnBatang:

	... constants used later - the Unicode values for the letters of my name: ...
	
	int a = 0x1161; // jungseong vowel
	int d = 0x1103; // choseong consonant
	int d2 = 0x11ae; // jongseong consonant
	int m = 0x1106; // choseong consonant
	int m2 = 0x11b7; // jongseong consonant
	int blank = 0x110b; // silent char you place at front if first letter is a vowel
	
	... the body of the paint method: ...
	
	g.setColor( Color.black );
	g.setFont( new Font( "UnBatang", 10, 30 ) );
		
	int w = 0;
	int lead = 0;
	w += renderIdeograph( g, blank, lead, 40  );
	w += renderIdeograph( g, a, lead+w, 40  );
	w += renderIdeograph( g, d2, lead+w, 40  );

	lead+=30; w = 0;
	w += renderIdeograph( g, blank, lead+w, 40  );
	w += renderIdeograph( g, a, lead+w, 40  );
	w += renderIdeograph( g, m2, lead+w, 40  );
		
	lead=0; w = 0;
	w += renderIdeograph( g, blank, lead+w, 80  );
	w += renderIdeograph( g, a, lead+w, 80  );
		
	lead+=30; w = 0;
	w += renderIdeograph( g, d, lead+w, 80  );
	w += renderIdeograph( g, a, lead+w, 80  );
	w += renderIdeograph( g, m2, lead+w, 80  );
	
	... and then this method to do the paint of each part of an ideograph: ...
	
	/** Doesn't really render an ideograph, renders a single glyph from the Font */
	public int renderIdeograph( Graphics g, int i, int x, int y )
	{
		char[] chars = Character.toChars( i );
		String drawString = String.copyValueOf( chars );
		int advance = g.getFontMetrics().charsWidth( chars, 0, chars.length );
		
		g.drawString( drawString, x, y );
		
		return advance;
	}

Which renders exactly like this:

hangul-adam-unbatang.PNG

Which makes me want to point out the nice thing about properly specified fonts: in the source code, I simply did “the natural thing”, as if I were outputting characters in an arbitrary conjoined language:

  1. Render the first part of the first ideograph at (x,y)
  2. Ask the font to tell you how many pixels wide (w) it just rendered that part
  3. Render the next part of the first ideograph at (x+w,y)
  4. …repeat until first ideograph is complete, increasing w more and more each time…
  5. Choose a value for how much you want the ideographs separated from start to start (ideograph_width)
  6. Render the first part of the second ideograph at (x + ideograph_width, y)
  7. …repeat as for first ideograph

And it worked. First time. I didn’t expect it to – I expected to have to do something strange like manually “reset” the (w) value each time I went from the first line of the ideograph to the second (Korean orders letters top-left, top-right, bottom-left, bottom-right, (repeat) … as opposed to Latin which is just left, right, more right, even more right, etc).

For this to have worked, it means the font is deliberately rendering the lower letters (e.g. d2 and m2 in my constants) a long way to the left of the origin that you tell it to render them at. This would be very, very confusing if you just tried to render these letters individually (well, duh).

Of course, if you try to run that code using Microsoft’s Arial Unicode MS font, you get a complete mess instead, because that font is FUBAR, as mentioned before. You get this:

hangul-adam-arial-unicode.PNG

…which is completely incomprehensible.

Categories
dev-process games industry

Bureaucracy

Thinking about the B-word recently … it seems that Bureaucracy doesn’t solve any problems; all it does is organize the solutions you already have, to make them more effective.

Which I think is why bureaucratic procedures MUST be updated, changed, revised, and replaced on a regular (almost frequent) basis. I vaguely remember that Lou Gerstner’s book on how he saved IBM in the 1990’s had some details on why bureacracy is good, and what it is.

It’s also why most attempts to introduce bureacracy fail to have any beneficial effect, and instead waste the time and energy of everyone involved; not because bureaucracy sucks (which is the impression most people get, quite understandably), but because it exposes and highlights all the other problems those organizations already had but were doing nothing to solve.

Sadly, in my experience the process usually seems to go something like this:

  1. Have a bunch of tricky but not impossible problems
  2. Management and/or staff lack one or more of the time, skill, experience, or courage to deal with them, or (for one of those reasons) grossly underestimate the scale of the problems
  3. Someone introduces bureaucracy to try and “solve” them rather than actually summon the energy or the courage to do the solving part themselves
  4. Bureaucracy takes lots of effort to introduce, and SEEMS to end up “making things worse”, because it exposes more eloquently the problems, so that more people see more problems than they saw before
  5. Management write-off the bureaucracy as a waste of resource
  6. Management ignore the problems that are now painfully, glaringly, obvious (as revealed by the bureaucracy)
  7. Management never does bureaucracy again, blames all the existing problems on bureaucracy, and hopes that by ceasing to do any bureaucracy those problems will gradually go away of their own accord.

If you introduce bureaucracy without knowing HOW and WHY it will solve your problems, then you are relying on nothing more solid than blind hope. Hope is not a strategy.

Categories
agile computer games dev-process games industry

Fighting Consulting Firms

a.k.a. how some Publishers view independent Developers

This is a quote found buried in the middle of the otherwise completely unrelated, but sometimes highly amusing, “rant to end all rants” about the rise and fall of the talent and skill of the people within the Ruby on Rails development community:

I have a few pieces of advice for people about to hire any company like ThoughtWorks. There’s just a few simple strategies you can follow to make sure you get the most out of them and get your money’s worth:

1. Make sure you have the right to see every resume and interview each consultant they place. Treat them like new hires and don’t let anyone who’s not worth the rate you’re paying on the team.
2. Demand a variable rate based on the position of the person and their experience.
3. Demand that no employees can leave the project to work on another project. These placements have to be for the life of the project or until the employee quits.
4. Require that you have the right to have someone replaced if they are not immediately capable. Part of what you’re paying is that a ThoughtWorker should be able to drop in commando style and just start working. The reality is they are usually totally lost anyway.
5. Seriously consider recruiting one full time employee as a team lead, another as a project manager, and then staff the rest of your team with independent consultants. You’ll find that you get more control and better quality at a lower price.

Having employed one extremely famous web-design consultancy, run by some of the most famous world experts in using XHTML/CSS (and doing so attractively), and had very similar discoveries/realizations about their dodgy business practices when we were charged 5-figure sums for 3 webpages that were thrown together in around half an hour … in 2005 … I found the list above quite a good starting point for anyone considering paying an external team of experts :).

At some point, I’d like to followup with my own lessons learnt from what to do and what not to do on the publisher side of the game-publisher/game-developer relationship.

Categories
databases dev-process programming

Improving your dev process: Automating collection of game-crash info

(As spotted in last month’s Game Developer magazine’s Inner Product column. Good enough that I wanted to draw some attention to it, and hopefully add a bunch more of these good ideas as I come across them / remember them)

Most games, when they crash hard enough, memory dump. The customer (or internal tester during development) can then be requested by the dev team to find a specific file in a specific directory (the mem dump) and email it to them for analysis.

Some games actually popup a dialogue to the user, to tell them about this file, and where to find it, and who to email it to.

Some even include some contextual information automatically (“the user was on Level 3, and has the following DirectX hardware info”). Most just ask the user to fill in a field “telling us what you were doing when it crashed”.

Most games, during development, automatically either popup – or display in a custom textarea – a message every time somethign unexpected happens, something that MIGHT be a symptom of a bug. There are even conference talks about how to avoid making your playtesters so sick of error messages that they stop bothering to read them, and hence the messages become mostly a waste of time.

How many games do a simple call to the SQL client library to send to the local SQL server a simple detailed report of what happened, when, why, and how bad it was? This information is ALL already available, but how hard is it to copy/past the following into your source code and execute it as an SQL command?

INSERT INTO reports.errors (time, problem, severity, stacktrace, user, IP, clientversion) values (TIMENOW(), “+assertion.getMessage()+”, “+assertion.getLevel()+”, “+assertion.getStacktrace()+”, “+assertion.getUsername()+”, “+system.getLocalIPAddress()+”, “+client.getVersion()” );

Nice idea – free, detailed, metrics on exactly why, when, and where your game exe is crashing, any unexpected problems, anyone who’s running an out-of-date version, etc.

And with the dev team no longer having to rely on users *actually bothering to tell them* when they see big flashing warnings and errors, we might avoid some of the programmer/artist antipathy (“[artist] hey, can you help me with something?” “[programmer] its got an error! no wonder it doesnt’ work!”, “oh, ignore that, it always does that”, “um, how long has it been ‘always’ doing that?”, “ever since around the time the game started running really slowly, 2 months ago. It sucks – now everything takes me twice as long to test. But that’s just life, I guess” [cue: programmer grinds teeth, smashes forehead on desk, or similar]).

NB: I have nothing against artists. They are just an easy scapegoat for a not-very-funny-but-actually-quite-painful-if-you’ve-been-there joke. No artists were harmed in the making of this post.