GameMaker Tutorial: Password systems 3: on-screen keyboard

Yeah, I know. Last article, I said in this article we’d cover parsing and validation and converting the password into gamestate data. We’ll get there eventually. But I want to take a detour and show you how to build an on-screen keyboard.

In the first article in this series, I handled the user input simply, by using the get_string_async() function. This is good enough to be functional, but has two main problems:

First, because we’re allowing input directly from the keyboard, the player can enter any characters at all, which means that we’d need to handle characters that are not part of our password’s alphabet. This means extra programming. Not necessarily a bad thing, if that’s what’s right for the user, but it is more work to write up validation scripts that properly handle our Base64 password alphabet.

Second, the user experience of typing a password into a textbox is fine, as far as it goes, but it isn’t at all like an authentic old school keyboard system. This is a somewhat debatable point — old school consoles used on-screen keyboards not because they were better than keyboard entry, but because there was no keyboard. Entering passwords this way is slower and more tedious. But, if we are going to re-create the experience authentically, we need to heed the conventions of the time.

Every onscreen keyboard in the old days was a custom implementation. No two were exactly the same, although there were a lot of commonalities, and most of the differences were cosmetic. The most common implementation was a grid of characters, which the player selected one at a time using the D-pad, pressing a button to enter the character, and another button to go back. When the entire password was entered, typically the player submitted it by pressing the Start button, or sometimes there was an on-screen button that the player would select with the D-pad. We’ll build something like that in this tutorial, although we’ll use the keyboard rather than a gamepad control. Implementing the gamepad controller input capability isn’t too difficult, though, so I’ll probably come back and add that eventually.

The Alphabet and the Font

One of the problems people have with writing down (and later reading) passwords is that certain characters look very similar (such as 0, o O, l, l, 5, S, 9, g, etc.) You can’t help the player’s handwriting, but at least when the game is displaying the characters on the screen, you should be sure to pick a font that makes these characters unambiguous. These symbols are merely labels which stand for a number value, so it doesn’t really matter what they are.

It’s not a bad idea to omit the similar looking characters, although for this tutorial I’m going to stick with the full alphabet. We’ll at least want a font that has very distinct characters to aid the player in recognizing them correctly. Google for “programmer” or “console” fonts, for suggestions on good ones to use, and pick something out that looks right for the style of game that you’re making. Make sure the capital “I” has serifs and the zero has a slash or dot in it, and so on.

The Onscreen Keyboard Object

oOnScreenKeyboard

Create

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?";
font = fConsole;
var k = 1;
for (var i = 0; i < 8; i++){
 for (var j = 0; j < 8; j++){
 keyboard[i,j] = string_copy(alphabet,k,1);
 k++;
 }
}
row_selected = 0;
column_selected = 0;
instructions_text = "Press A to select letter. Press B to erase letter. Press Enter to submit password.";

input_string = "";
max_input_string_length = 4;

Draw

draw_set_font(font);
draw_set_halign(fa_left);
draw_set_valign(fa_top);
draw_text(10,10, "PASSWORD: " + input_string);

draw_set_halign(fa_center);
draw_set_valign(fa_middle);

for (var i = 0; i < 8; i++){
 for (var j = 0; j < 8; j++){
 draw_text(x+(32*i), y+(32*j), keyboard[j,i]);
 }
}
draw_rectangle((column_selected * 32) - 16 + x,
 (row_selected * 32) - 16 + y, 
 (column_selected * 32) + 16 + x, 
 (row_selected * 32) + 16 + y, 
 true);

Press Button1

(Pick whatever keyboard key you want for this.)

if string_length(input_string) < max_input_string_length {
 input_string += string_copy(alphabet, (row_selected*8) + column_selected + 1, 1);
}else{
 audio_play_sound(snBadPassword,1,false); 
}

Press Button2

(Again pick whatever keyboard key you want for this.)

input_string = string_copy(input_string,1,string_length(input_string)-1);

Press Enter

if validate_password(input_string){
 apply_password(input_string);
 room_goto(rmGameStart);
} else {
 bad_password();
}

Press Up

row_selected = (row_selected + 7) mod 8;

Press Down

row_selected = (row_selected + 1) mod 8;

Press Left

column_selected = (column_selected + 7) mod 8;

Press Right

column_selected = (column_selected + 1) mod 8;

That's it for the Events, but we need to write three scripts for the Press Enter event. These passwords are where most of the implementation-specific code is going to go.

The details of these scripts will vary from project to project, but this is where we'll handle the validation, parsing, and conversion to gamestate data -- what I thought we'd be covering in this article. We'll cover our example versions of them in the next article.

GameMaker Tutorial: Password systems 2: encoding/decoding

As we established in the first article in this series, a game save password stores game state data. In this article, we’re going to talk about the low level details of how this is done. We won’t be talking much about the password itself, or the game state data. We’ll be focusing instead rather narrowly on how to encode and decode the data.

Numeric data

As far as numeric data is concerned, we’re only going to worry about encoding/decoding integers, for simplicity’s sake. For the most part, we’ll be concerned with positive integers, but we’ll cover negative values as well.

Actually, treating numeric GML data values as integers is a little bit tricky, since in GameMaker the only data types available are strings and reals (floating point numbers). For the most part you can treat a number as though it were an integer in GameMaker, as long as you don’t do math on the number that causes the digits after the decimal point to become non-zero values.

If you want decimal values, you can store the value as an integer, and then divide it by 10, or 100, or however many decimal places as you need after you decode it. Or, if you want to store a fraction, you can store the numerator and denominator as integers, and divide them after decoding them.

As long as you don’t deal in fractions and decimals, you can pretend that your numbers are integers, and GameMaker for the most part will act as though they are. This will come up later when we hit the limit for the largest integer value that we can encode using our method (16,777,215). I’ll explain why below, but for now it’s enough to know this should be a large enough value that we don’t really need to worry about trying to encode larger values, at least for most games.

The basic idea is that each character in your password alphabet stands for an integer value. Notice that the complete alphabet (26 upper case + 26 lower case) + the 10 numerals + 2 special characters gives you a range of 64 values; 2^6 = 64, so each character in a password can represent a 6-bit binary value.

A B C D E F G H
0 1 2 3 4 5 6 7
I J K L M N O P
8 9 10 11 12 13 14 15
Q R S T U V W X
16 17 18 19 20 21 22 23
Y Z a b c d e f
24 25 26 27 28 29 30 31
g h i j k l m n
32 33 34 35 36 37 38 39
o p q r s t u v
40 41 42 43 44 45 46 47
w x y z 0 1 2 3
48 49 50 51 52 53 54 55
4 5 6 7 8 9 ! ?
56 57 58 59 60 61 62 63

Beyond 63

What can you do if you want to store a value larger than 63? Simple, you just use a second digit in your base-64 number. Just like the next number after 9 is 10, in base-64 the next number after ? is BA. Until you’ve looked at base-64 numbers for a long time, it’s going to be very difficult to recognize the value represented by a base-64 number, but we don’t need to — we’ll tell the computer to do it for us with some gml scripts.

We said before that a 4-digit base-64 number stores 24 bits, or up to 16,777,215 in base-10. But for some numbers that might be overkill. If we wanted to, we could treat each digit as a single base-64 value, and add them together. For a 4-character base-64 string, this would give us a range of 0-252, nearly a byte. It’s a much less compact way of storing the data, but for small values it’s not too bad.

To do the conversion from base-10 to base-64 and back, we’ll need some gml scripts.

b64_to_dec(b64)

/*
Takes a string of a b64-encoded value and converts it to a real number
*/
var b64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?";
var value = 0;
var digit = 0;
var neg = 1;

if string_copy(argument0,1,1) == "-"{
 argument0 = string_copy(argument0,2,string_length(argument0)-1);
 neg = -1;
}

for (var i = string_length(argument0); i >= 1; i--){
 value += (string_pos(string_copy(argument0,i,1), b64_alphabet)-1) * power(64,digit); 
 digit++;
}

return neg * value;

/*
Takes a real number and converts it to a base-64 encoded string. Supports integer values from 0-16777215.
*/

var b64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?";
var value = abs(argument0);
var r;
var str = ""; 
var done = false;

while !done{
 r = value mod 64;
 str = string_char_at(b64_alphabet, r+1) + str;
 value = (value - r) div 64;
 if (value == 0){done = true;}
}

if (argument0 < 0){
 str = "-" + str;
}

return str;

Lastly, it will be handy to have a function that can pad a B64 encoded string to a specific length:

b64_padded

/*
Takes a base-64 encoded string (argument0) and pads it to padded_length (argument1) with leading "A"'s (0's). 
If the number is negative, the first character in the padded string will be a "-". If the padded_length is 
less than the length of the b64 value, the function returns -1 to signify an error. 

(Note the error code returned is a real number, -1, not to be confused with the correct output of 
b64_padded(-1,2), which would return the *string* "-1") 
*/

//argument0 the b64 string to pad to length
//argument1 the length to pad to

b64 = argument0;
len = argument1;

if len < string_length(b64){return -1;} //too short, return error
if len == string_length(b64){return b64;} //just right; we're already done

var str = "";
if string_copy(b64,1,1) == "-"{
 str = "-";
 len--;
 b64 = string_copy(b64,2,string_length(b64)-1);
}
repeat (len - string_length(b64)){str+="A";}
str+=b64;

return str;

Negative Numbers

The scripts above handle negative values just fine. But the minus sign is not part of the base-64 alphabet. If we need to store negative numbers, we have a few choices.

We can expand our password alphabet to include a minus sign (or an arbitrary symbol that we can use as a substitute).

Or we can designate certain characters in the password to store a boolean which signifies whether a given numeric value stored elsewhere in the password is positive or negative. Then encode the absolute value of the number, and re-combine it later with the boolean that holds the sign.

Or we can sacrifice a bit in our base-64 encoded numbers and treat them as signed integers, such that A-g represent values 0 through 32, and h-? represent negative values -1 through -31.

Beyond 16,777,215?

The encoding/decoding scripts work for values up to 16,777,215, or ???? in b64. This value is (2^24)-1. Beyond that, the numbers do not encode/decode properly. The reason for this has to do with the way GameMaker stores numeric values. All numbers in GameMaker are floating point values. GameMaker uses a 32-bit floating point, of which 24 of those bits are used for the digits to the left of the decimal point. The remaining 8 digits are used for the fractional value to the right of the decimal point. This means that for a number above 16777215, we can’t store the value in a 32-bit floating point variable without losing some precision. This precision prevents us from cleanly encoding a value above 16777215 and decoding it back to the same value. Fortunately, such high values should be rare to encounter in the game state data.

What happens if you try to store a larger value depends on the build target. Some may lose precision, resulting in off-by-one conversions — data corruption. Others may fail to return a value entirely when the conversion script is called, which would result in total loss of the data. Certain build targets (I’m not certain which ones) may use 64-bit floating point values, rather than 32-bit. In this case, we can go even higher, up to (2^52)-1. This is a ridiculously large number, and it’s almost certainly more than enough for any game state value you might want to encode.

Tip for validation

If the password space allows a value larger than the max value for a given game state variable, you can use those larger values as a form of validation check. For example, let’s say that the maximum number of lives in your game is 255. This requires an 8-bit value, but since each character represents 6 bits, and we don’t want to bother splitting characters, we use 2 password characters, which represents 12 bits of data. We can use these additional value space between 256 and 4096 for a validation check.

The simplest method would be to reject any password that contains data in the lives bits that decodes to a value greater than 255. Another way to handle this is to use a math value to obfuscate the lives value. Since 4096/256 = 16, we can take the value of the two characters that we use to encode the lives count as follows: lives x 16 = password substring. Now, when you’re validating the password, you can mod the value of the characters that represent the lives by 16, and if the calculation doesn’t work out to 0, then you know the password isn’t valid.

Or you can make the “right” remainder be dependent upon some other part of the password — for example, when the Level is even, the lives substring should mod16 to 0, but when Level is odd, it should mod16 to 1, unless Level is divisible by 3, in which case… Sneaky/unnecessary complexity like this will make the password harder to understand, and therefore require more effort to crack the password system. Don’t fool yourself into thinking you’re coming up with a super secure uncrackable password, but it will make the password a little less obvious than a simple counter, and for password system crackers, will make the puzzle more fun.

String data

Old NES password games did not typically have any string variables to preserve in a save password. In fact, the few games where you could enter a name were all, to the best of my knowledge, battery backup games that used savefiles.

It’s simple enough to store a string in a password, though, since a password is a string. The only real issue is dealing with variable length strings. For a lot of reasons, it’s probably best to stick with a fixed length for strings and pad shorter strings with spaces, trimming them later when applying the password to game state.

However, it looks weird if your password has string values stored as plain text in the password — it’s an obvious indicator to the player that the password is storing data, which could invite mischief. So it’s probably a good idea to encode the data somehow.

We could encode strings by using the numeric ASCII values of the letters, and then convert them back, character by character. While not encrypting the data, it would be sufficiently obfuscated for our purposes.

I won’t bother implementing this for now, since our demo password only has 4 characters, and in any case it’s not really necessary, but it’s good to have an idea of how we might do it if we decide to later on.

Boolean data

GameMaker doesn’t have a true boolean data type. The boolean constants true and false are equal to 1 and 0 in GML. Boolean expressions in GameMaker are handled by evaluating to a real number, and any number <0.5 evaluates as false, and 0.5 or greater evaluates as true. Therefore, to encode a boolean, all we really need to do is encode a value of 0 or 1. Or any other value that will evaluate to true or false.

But, since a single base-64 character can store up to 6 bits of data, and each bit can store a 0 or a 1, a single character could in theory store up to 6 boolean values, which means a 6x greater density than if we just stored one boolean value in each character.

To achieve this, we need to convert a base-64 value to a binary value, and vice versa. Then we would need to break the binary value into its individual bits, and designate each bit for a specific boolean value.

Note that the next few functions do not really deal with binary values, but rather with strings storing 0 and 1 characters, which we can convert to boolean values by using the real() function.

Edit: I’ve updated these functions with more elegant implementations, and replaced the brute force switch statement lookup table approach that I had here originally. Thanks to Ian Schreiber for the suggestion.

bin_to_dec(bin)

/*
Takes a string of a binary encoded value and converts it to a real value.
*/
var bin_alphabet = "01";
var value = 0;
var digit = 0;

for (var i = string_length(argument0); i >= 1; i--){
 value += ((string_pos(string_copy(argument0,i,1), bin_alphabet)-1) * power(2,digit)); 
 digit++;
}

return value;

dec_to_bin(dec)

/*
Takes a base-10 value and encodes it as a binary string
*/
var bin_alphabet = "01";
var r;
var str = "";
var done = false;
neg = sign(argument0);
value = abs(argument0);

while !done{
 r = value mod 2;
 str = string_char_at(bin_alphabet, r+1) + str;
 value = (value - r) div 2;
 if (value == 0){done = true;}
}

if (neg < 0) {str = "-1" + str;}

return str;

bin_to_b64(bin)

/*
Takes a 6-digit binary encoded string and converts it to a b64-encoded character.
*/

return dec_to_b64(bin_to_dec(argument0));

bin_to_bool(bin)

/*
Extracts the argment1-th bit out of the binary string supplied in argument0 and returns it, converted
to a real number. The real value can be interpreted as a boolean (0=false; 1=true).
Argument0 must be a string consisting only of "0"'s and "1"'s
Argument1 must be a number between 1 and string_length(argument0). 
*/

return real(string_copy(argument0,argument1,1));

bool6_to_bin(bool,bool,bool,bool,bool,bool)

/*
Takes six boolean values and concatenates them to create a 6-bit binary encoded string, 
suitable for converstion to a b64 value with the bin_to_b64() function.
*/

/*
force conversion of arguments to gml boolean constants
*/

if argument0{argument0 = true;}else{argument0 = false;}
if argument1{argument1 = true;}else{argument1 = false;}
if argument2{argument2 = true;}else{argument2 = false;}
if argument3{argument3 = true;}else{argument3 = false;}
if argument4{argument4 = true;}else{argument4 = false;}
if argument5{argument5 = true;}else{argument5 = false;}

/*
concatenate bools to string
*/
return string(argument0) + string(argument1) + string(argument2) +
 string(argument3) + string(argument4) + string(argument5);

bin_padded

//pads a binary encoded string (argument0) to length (argument1)
var bin = argument0;//bin string to pad
var len = argument1;//padded length

if len < string_length(bin){return -1;}
if len == string_length(bin){return bin;}

repeat(len - string_length(bin)){bin = "0" + bin;}

return bin;

These scripts should suffice for encoding/decoding all of our data values.

Advanced password validation with checksums and hashes

Additionally, to keep the player honest, you probably want some kind of tamper-proofing to go with your password encoding. Otherwise, it makes tinkering with the password to cheat too easy. For example, you could play the game, get a password, then get hurt, and get a new password, and by comparing the two, you could infer which characters in the password correspond to your health. Then, you could substitute different values for the password characters that correspond to your health health until you hit upon a value that gave you max health, or, depending on how the game works, even infinite health or invulnerability.

It’s true that deciphering password encoding schemes is a lot of fun, but we don’t want to make the system so easy that it invites cheating. Make the player work at it, and feel like they truly hacked something when they figure out your system.

To do this, we can reserve certain characters in the password for storing checksum values, or even hash values. Understanding hash and checksum math isn’t too difficult, but isn’t terribly necessary, either. We don’t need something impossible to crack, just something functional. There are better checksum functions than I’ll demonstrate here, but this should suffice to make the concept understandable to anyone.

Simple checksum

Using our 4-character example password, we can add an additional two characters for checksum data.

Level Lives Health Ammo Checksum
A-? A-? A-? A-? AA-??

Let’s say the game state data is encoded with the following 4 values from our cipher table, above:

Level Lives Health Ammo
password char B D ? ?
base-10 value 1 3 63 63

A simple checksum for this would be 1+3+63+63 = 130. Of course, this checksum isn’t very strong; any four values for Level, Lives, Health, and Ammo that add up to 130 will have the same checksum. But it does stop someone from changing a single character in the password and getting another valid password.

To add the checksum value to the password, we need to encode 130 as a base-64 value. This would be a 2-digit base-64 number: 22. According to our base-64 encoding table, the value 2 is encoded by the symbol C. So, 22 == CC. So the entire password would be:

Level Lives Health Ammo Checksum
password char B D ? ? CC
base-10 value 1 3 63 63 130

Note that since 63*4 = 252, the highest the checksum value will ever go will be 252, or D8.

If you wanted to get really crazy, you can scramble the order of the characters, shuffling checksum characters in between the data value characters. But we’re not that concerned with obfuscation, so we won’t bother with an example of this.

In the next article, we’ll cover how to design the password specification in greater detail, and write some sample scripts that takes the password, validates and decodes it, and assigns the stored values to re-create the game state.

Part 3

GameMaker Tutorial: Password systems 1: password entry

In old school console games, especially for the NES, it was common to enter a “code” or “password” in order to resume play where you had left off previously. Back in the day, memory was extremely expensive, and very few games implemented a battery backed RAM solution that allowed the player to Save and Restore a game.

Instead, a system of encoding the game state data into a long “password” was often used in lieu of a real save system. In addition to encoding the game state, these password systems often had some kind of validation built into them, so that not just any arbitrary input would be accepted. For fun, sometimes games would have special, secret codes that would enable cheats. For a few players, cracking the encoding system to enable you to configure the gamestate to your exact wishes was a kind of advanced meta-game, excellent for budding young hackers. There is great nostalgia value in these systems if you are into old school retrogaming.

Password systems (general overview)

If you want to build a password save system, at a high level there are a few things you need to do:

  1. Password Entry
  2. Validation
  3. Encoding/Decoding GameState
  4. Password Display

This article will cover Password Entry, while future articles will cover the other topics.

Get the input

For simplicity’s sake, let’s assume a four-character code will encode all the information that we need. In practice, most 8-bit NES games used much more than this, but for a simple input demo this should be sufficient.

The easiest way to enter a string in GameMaker is the get_string_async() function.

save_pw = get_string_async("Enter password", "");

Since get_string_async is an asynchronous function, it does not return a value immediately. We need to add an Async Event to catch the return value when the function calls back to the main program. The correct Async Event to use for this function is the Dialog event. The get_string_async() function doesn’t simply return a string value, though; rather, it returns a data structure called a ds_map, which contains 3 values: an id, a status, and the result. The result is the string that was entered by the player, the password that we are looking for.

We can put the following code in the Dialog Event to handle the return callback:
Dialog Event:

var i_d = ds_map_find_value(async_load, "id");
if i_d == save_pw{
 if ds_map_find_value(async_load, "status"){
 password = ds_map_find_value(async_load, "result");
 }
}

The interface that get_string_async() provides is not very satisfying, aesthetically, but it works well enough for now. (We’ll explore a few other methods later that will more faithfully replicate the “password entry” screens from old NES games, in a future article.)

Right away, we have a few problems with simply getting a string:

  1. Because get_string_async() allows the player to enter any string they want, the player may enter a string of arbitrary length. For our demo, we need them to enter a string that is exactly the right length.
  2. The get_string_async() is not constrained in the characters it will allow the player to enter. Passwords for NES games varied in their alphabets, but many would allow A-Z, a-z, 0-9, and often spaces and special characters. Some games would allow only capital letters, while others would allow lower and upper case. One serious flaw with the old password systems was that the letters were displayed in fonts which often made it difficult to differentiate certain characters, like 1 and l, or 0 and o, etc. Later NES games sometimes corrected for this by using a more distinct font, or by omitting the ambiguous characters from the alphabet entirely.

There are many ways to constrain the allowed characters, but we don’t need to get super fancy with it for our demo.

In the next article, we’ll demonstrate how to decode the password — that is, to translate the password value to game state information. Finally, we’ll demonstrate how to generate and display the password when the game is over (or paused, or at a save point, or whenever it’s appropriate for your game), so that the player can write it down and enter it the next time they play to resume where they left off.

Part 2

Microsoft pulls a XBox One-80

Yesterday, Microsoft backed away from its earlier announcements regarding their XBox One policies.

It’s good that companies listen to customers and respond to their concerns, but it doesn’t quite make up for thinking the right way from the beginning. I don’t know that Microsoft has seen the light, and doubt very much that they have. More likely they are stepping back and re-thinking how their strategy failed, and plotting a new, less direct course to get where they wanted to take the market.

But at least they seem to have listened this time. For now.

Pixel Art Gallery

A while ago when I was playing with my pixel art technique, I wanted to set up a single post with all of my practice drawings in them.

I just now finally got around to it. Turns out it was a lot easier than I would have guessed. (more…)

XBox One: Why REAL ownership matters, and will always matter.

On ArsTechnica, today, I read the following in defense of XBox One:

“This is a big change, consumers don’t always love change, and there’s a lot of education we have to provide to make sure that people understand.”

…a lot of the way people have responded to Microsoft’s moves was “kind of as we expected.” But the implication … was that this temporary confusion and discomfort among the audience would be worth it as gamers and consumers adjust to a console world without game discs.

“We’re trying to do something pretty big in terms of moving the industry forward for console gaming into the digital world. We believe the digital world is the future, and we believe digital is better.”

[Microsoft] made a comparison to the world of home movie viewing, where inconvenient trips to Blockbuster Video have been replaced with Netflix streaming on practically any device instantly. On Xbox One, having all games exist as cloud-connected downloads enables new features like being able to access your entire library at a friend’s house with a single login, or loaning games to up to ten “family members” digitally and remotely.

Immediately, I want to point out that Netflix (and Hulu) didn’t replace owning a copy — my copy — of a movie. They replaced movie rental and scheduled broadcast television — with something better and that eliminated inconveniences.

With Netflix and Hulu, you don’t have to program a DVR, or go to a store, or deal with rental returns and late fees. And assuming you only want to watch a thing once or twice, and don’t care to own a copy of it for all time, it’s great.

But online streaming on-demand services cannot replace certain aspects of owning a copy. And those things are very important. Users of these services know already that what is available today may not be available tomorrow. If the copyright owner decides to stop licensing the programming through the service, it will not be available any longer on the service. But a physical copy that you own can always be played, whenever you want to, as long as you own it. So if you want to guarantee availability of something forever, you can only do so if you own your copy.

And the copy you own will remain the edition you bought forever — no 1984-style “memory hole” for the old edition when the producers decide to release a new cut as the canonical version. No forced upgrades pushed over the network, eliminating or changing some scene that some group found objectionable for some reason, and managed to successfully pressure the studio into changing.

Video productions are re-cut and re-edited all the time, and for the most part people don’t notice it, or care. But sometimes the changes can drastically change the meaning. In the 1990’s, singer Sinead O’Connor once made an appearance on Saturday Night Live,  during which she unleashed a storm of controversy by tearing up a photo of Pope John Paul II on live television. NBC and SNL immediately distanced themselves from the incident and claimed to have had nothing to do with it, apologized for the offense it may have caused Catholic viewers, and claimed that it was something that O’Connor did on her own without informing the producers of her plans. This act of protest was never rebroadcast, and to my knowledge cannot be seen in any format today. Today, apart from viewers memories of the incident, it may as well not have happened. Unless someone with a VCR happened to tape that episode and kept it, as I’m sure many may have done, it would be lost forever, imprisoned in NBC’s video archive, if it exists at all. O’Connor’s act was an act of political speech, and whether you agree with her message or not, she had a right to say what she wanted, in the way she wanted. Of course, NBC and SNL own the rights to the video of the event, and have the right to not to make it available if they want, or edit it in whatever way they choose. But it was also broadcast to millions of homes over the public airwaves, and those who witnessed it own their memories of the event. And, for those who have have their own copy, and because you can own and control your own copy, NBC is not able to suppress it completely, or to compel holders of copies to surrender or destroy them. If need be, it could be proved that the incident happened, and, although they haven’t gone so far as to deny that the incident never took place, they certainly don’t like to bring it up, and if NBC wanted to pretend that it never happened, people can contradict the official histories, not just with memories and eyewitness testimony, but with evidence. Owning your own copy can help save The Truth from the memory hole. It gives you the power to own a little bit of the The Truth, outside of your own skull.

If you’re not a political person, you’re probably thinking “Whoa, you’ve gone off the deep end. This is just entertainment we’re talking about. Movies, TV, and videogames. We’re not talking about the news, or matters of public record. Surely this isn’t important stuff, get a grip.” But games do get censored, or pulled from the marketplace, and this can effect people who already own them, if they give up control of the copy that they purchased to DRM. Moreover, wherever DRM technologies make inroads, it tends to result in their becoming more accepted and likely to be used elsewhere. If we accept DRM for television, movies, and games, the technologies are then already in place, and may be used by hard news and official government content providers. Even if they were only used for entertainment, this is our culture — do we really want it to be completely controlled by corporate copyright holders?

Microsoft’s XBox One distribution offers to replace ownership of a physical copy with something worse. It might beat rentals, but it sucks compared to buying. It’s not the digital distribution and decoupling from physical media, it’s the DRM and the licensing vs. owning a copy.

There are pros and cons to decoupling software from physical media, but on the whole I am fine with owning my copy of a computer file, vs. owning a disc or ROM cartridge that came in a box. But de-coupling need not be accompanied by artificial limitations of use imposed by DRM and the need to authenticate a license to a copyrighted work. A license-to-access model is inferior to a model of owning a copy.

Learning from history

I have, in my personal game collection, consoles from Atari, Mattel, Coleco, Nintendo, Sega, Sony, and Microsoft. The oldest of these systems were built in the 1970’s. They are still fully playable, barring hardware failure.

Even back then, there were very early attempts at online play and distribution of games. They were ahead of their time, but from the earliest days the game industry tried to figure out ways to get people to subscribe to a service that would allow them to sell games directly to customers, replacing traditional retail distribution with digital download over a modem connection.

These services are long gone. Any games that were distributed exclusively via these means are exceedingly rare. If they exist at all, it’s only because someone who downloaded the game never erased it from their media (typically an audio cassette tape, or possibly a floppy disk), and because the game didn’t depend on the online service in order to run. This last bit is absolutely crucial. If these games could not be played if they depended on the continued existence of servers which were closed down by the vendor when they were no longer profitable, these games could not be played today.

“Well, who cares? Who cares about these old games?”

It turns out, a lot of people. Everyone who owns them, and would like to continue to be able to enjoy them. Anyone who wants to introduce their favorite games from their childhood to youngsters today. Collectors. Historians. Game designers.

“But popular games get re-packaged and re-sold with each generation!”

I suppose they do. Nothing wrong with that. It’s a good thing.

But what if your favorite game isn’t one of the few lucky popular games that gets chosen to live on? What if you want to play the games on the original hardware? What if you don’t want to have to re-buy games that you already own in order to play them again on your current-generation console?

“But you can’t go out to a retail outlet and buy a traditionally distributed game that isn’t being made anymore. So why should it matter that you can’t buy a digitally distributed game anymore?”

Because, the games that were sold while it was available are still available. They are tangible, transferrable, resellable goods, and as long as they remain physically intact, and someone in the world wants to enjoy them, there is a market for them. It might be garage sales and flea markets and eBay, but it’s possible to find and buy a videogame that was made in 1977. It might not be easy in some cases, but it’s possible, and it’s no more complicated than finding the game, plugging it in, and playing it.

I guess it may be starting to become more difficult now that old-fashioned NTSC CRT TVs are disappearing, along with their antequated analog signal input jacks, but the point is that there’s no need to negotiate the right to play the game with the copyright holder. If you have it, you can play it.

Digitally downloaded games could be just as transferrable — far more transferrable, in fact. Files are easy to share and copy. Compared to making a copy of a printed circuit board and ROM chip, it’s dead simple. The future should be making it easier to do things, not harder.

But if games have dependencies on network-based resources that the player does not control in order to function, this all changes. It seems likely that game companies will sell the client, but not the server. But when the company no longer sees value in maintaining the servers, and decides to take them down rather than sell them to someone who’d become a competitor, or release the source code so that the player community can host their own servers, that will be the end of that game.

The level of dependency may vary considerably, from simple license/subscription validation, to enabling multiplayer features, updates, and downloadable content, to online leaderboard and achievement data. From the gamer’s perspective, the possibilities are rich, but they all disappear when the servers go offline. Nothing can compel a company to release the server software as a product or as a freebie once they decide to end-of-life an obsolete title, but without the server side, the clients are potentially useless, and at the very least are diminished.

Furthermore, servers can be used to killswitch the client, or to force unwanted upgrades. What if you liked the 1.0 version of your favorite game, but hated what they did with 1.1? If you can’t roll back, if you can’t decline an upgrade, there’s not much you can do. Game companies that serve the player’s interests well should design their upgrade systems to allow the player to play the game in an earlier version mode if they desire. And server code should be made available (whether for free or as a product) once the parent company decides it’s time to shut things down, so that players can continue to have full access to the complete experience indefinitely, as long as there’s a community who wants it. Of course, security concerns will mean that any code running on a network node will need to be patched, so it would be best if the source code is available to enable patches to be made.

Obviously, many of those requirements for libre software are too much for most game companies in their current thinking. “Allow our obsolete products to continue to be sold so that we have to continue to compete with ourselves? Release our server source code, are they mad?” While it’s difficult to imagine many companies doing anything like this in today’s market, these are the sort of things that gamers need as consumers, and the culture needs from the vantage point of the historian. Some companies, notably Id Software, have opensourced their older game engines, so it’s not unthinkable that the same could also happen with server technologies, though there are certainly many obstacles, such as software patents, and the fact that many game design studios license third party engines.

Still, even if it’s a highly unlikely ideal, it’s important as a point of comparison, to know just how much you “own” the things that you “buy”, and a target for the consumer to strive to push the market toward. Consumers do have power when they act collectively. It is only for us to realize this, and seize the power that is within our grasp.

Radar demo now in HTML5

I got the Radar demo working in HTML5, finally. In order to do it, absent a better debugging methodology, I created a new project and meticulously re-built the demo line by line. I’m still not entirely sure why this works while the first one doesn’t — I still need to look at it more closely.

The resulting project isn’t feature-complete yet, but the only missing feature is color coding for IFF, and isn’t where the problem was. Once I’ve finished adding that feature, I’ll update the source download.

For now, here’s an in browser preview of what the radar demo looks like in action:

XBOX One: No thanks

Microsoft’s recent announcement of their next-generation console, the XBOX One, has raised a lot of ire in the gamer community.

The two major issues are “digital rights management” and privacy.

Privacy

The Kinect is a motion sensing control interface that was introduced late in the life cycle of the XBox 360 product line, and has been generally accepted by users as a novel method of control by motion, similar in certain respects to the Nintendo Wii’s Wiimote. With XBox One, the Kinect interface is mandatory, and always on. The Kinect isn’t just a motion sensor. Unlike the Wiimote, it uses a camera and microphone to, essentially, bug your living room. This allows the XBox One to respond to voice commands, like the USS Enterprise‘s shipboard computer on Star Trek, and do other things that are pretty neat. But it also allows Microsoft to watch you live at all hours and in all states of undress, all day every day, like the two-way televisions of George Orwell’s 1984. It turns the home into a zone of no expectation of privacy.

Microsoft’s response to these concerns has been weak. They claim that you can control what the XBox is allowed to do, but can you really? It’s always on, always connected to the internet, and running Microsoft’s operating system — how hard is it for someone to gain unauthorized access to the XBox and use it to spy on you? How easy is it to imagine Microsoft rolling over for government requests to use this technology to monitor citizens suspected of “un-American” activities? How often in the past have we seen large technology companies like Yahoo! and Facebook decide to re-set user-configured preferences to defaults that they prefer, and quietly allow the savvy user who pays attention to re-opt out, again and again, until they wear down and accept the service provider’s preferences? It’s a virtual certainty that Microsoft’s click-through EULA and ToS will grant them the ability to do whatever they want with the information they gather through the device, and hold them not harmless and not liable for any damages caused or enabled by the device. And they’ll turn around and claim that they do nothing with the information that you do not authorize, as though you have control. In reality, the only control that you have at all is whether to buy the device or not.

We are already living in an age where the general public has more or less accepted a total erosion of the expectation of privacy. Is this a step too far? For anyone who thinks about it even for a moment, it would seem to be. Yet, almost no one seems to behave as though they think about it at all. We use the services of Google, Facebook, Twitter, and so on, sharing very personal information about ourselves, often in full public view, and certainly in full view of the service provider, their partners, and anyone who eventually buys them out. We willingly pay Verizon, AT&T, and others hundreds of dollars a year for the convenience of carrying tracking devices that monitor our locations, what we read, who we know, what we buy. We send emails un-encrypted, containing sensitive personal information that is easily intercepted and re-transmitted to anyone in the world. The NSA sucks all of it up into giant datacenters, and apart from a few headlines, barely any notice is paid. And for the most part, nothing happens, and we don’t seem to care.

DRM

In a nutshell, DRM, as implemented for XBox One, means that you do not own the game you thought you bought. You don’t even own the copy — the physical media you own, but all the physical media is a transport vessel. The data on the media is intellectual property, owned by the copyright holder, who controls how it can be used. You own the “license” to play the publisher’s intellectual property — under their terms, which they can change at any time, for as long as they continue to exist, or decide to continue allowing their intellectual property to be made available.

You do not retain the ability to transfer your “rights” to someone else, either as a gift, loan, or re-sale — unless the publisher decides to allow it, and then only through some approved process wholly controlled by them.

It is an extremely raw deal for the consumer, and something which no one should allow to stand.

Of course, ridiculous, draconian licensing terms are nothing new to commercial software. It’s been around for decades, from the earliest days of Microsoft and the personal computer. It’s just that, for most of this time, it hasn’t mattered to consumers, because there was no way to enforce many of the terms stipulated in EULAs, and circumvention was trivial.

It’s been all over the internet by now, with virtually every source that I’ve been able to find coming out against Microsoft’s policies. Here are just a few links:

  1. http://news.xbox.com/2013/06/main
  2. http://www.polygon.com/2013/6/7/4406170/xbox-one-internet-trade-policy
  3. http://www.nowgamer.com/features/1955108/xbox_one_its_for_publishers_not_for_you.html
  4. http://www.giantbomb.com/articles/major-publishers-silent-on-xbox-one-used-game-poli/1100-4659/
  5. http://www.bbc.co.uk/news/technology-22812743
  6. http://www.youtube.com/watch?v=9APmJHu8DNs
  7. http://www.youtube.com/watch?v=1StPJgWkN-U
  8. http://techland.time.com/2013/06/07/microsofts-xbox-one-used-games-policies-are-clear-as-mud/
  9. https://blogs.wsj.com/corporate-intelligence/2013/06/07/microsofts-xbox-one-how-things-have-changed/
  10. http://www.neogaf.com/forum/showthread.php?t=580169

Final Thoughts

All of this comes at a time when the game industry is struggling to figure out a business model that works. The internet, digital distribution, piracy, in-game purchase, free-to-play, freemium, lowered barriers to entry enabling indie developers and hobbyist developers, and other rapid changes have made it very difficult for many companies to remain profitable. This response by Microsoft is the most heavy-handed, top-down approach that we’ve seen so far, and cannot be the future of videogaming entertainment.

It is a future with no history — when the publishers DRM servers are shut off, an entire generation of gaming will be lost forever, never to be seen again. And so it must be a future with no future, as well. An informed consumer who understands the issues at play and what’s at stake, could only reject a product offered on these terms. It is up to gamers to educate the general public to stand firm against this.

There are alternatives. The upstart Ouya console is perhaps the best of them in the current generation.

Radar demo update

I’ve made a number of really nice enhancements to my earlier Radar demo.

The improvements:

  • The original demo used collision_line() to detect when the radar sweep collided with the radar blips to refresh them. This meant that the collision detection could skip over smaller objects at great distances from the antenna, since the space between steps is not scanned. The new one uses an approach based on the angle difference between the mappable object and the sweep’s current and previous positions, and is therefore much more accurate.
  • The original radar used a classic looking monochrome green radar screen. The new one implements IFF (Identify Friend or Foe) color coding. This system is flexible in that it allows you to change the value of the color variables used in the color key, or even a unique color if desired. oMappable child objects must have two instance variables, blip_alpha and blip_color. The demo only uses color for IFF, but for colorblind players it would be helpful to modify the routine to use shape as well as color to identify the blips.
  • I’m particularly proud of how understandable and well-commented the code is, so if you’re a developer and want to modify it for your own needs, it should be quite easy to do so.

I still can’t get it to run in HTML5 builds, so a screen shot will have to do.

Radar Demo by csanyk

Download radar_example.gmz