Categories
Games General

Video Game Manifestos

I found A Gamer’s Manifesto at Game Girl Advance. It’s humorous and hits home. I’ve always had Nintendo systems so I never really dealt with long load times before, but PC Games and apparently Playstation and XBox titles are plagued by developers who think that long loading times are great. Another valid complaint is the invisible barrier that keeps you within the game map. With the power of game platforms these days, couldn’t the map itself keep you within its boundaries? If I am going to hit the edge of the map as if it was a normal wall, why not make it a normal wall? Or some other suitable obstacle?

Other famous video game manifestos:

Categories
General

Day[24]; // off by one errors

When I was really young, I remember the first time I learned that the first hour of the day started at midnight. It was weird realizing that time moved in this sequence: 10PM, 11PM, 12 AM, 1AM, etc. Thinking about it for awhile, I realized it made sense.

To this day, the border between one day and the next throws people off. I like to think of it as an array of hours.

hours Day[24];

So now I have an array of hours called Day. The first hour is hour 0, and the last hour is hour 23. Translated into actual time: if it is after 12AM, you have entered into the next day.

Why am I bringing this up? Because I recently bought tickets for the latest Star Wars movie, and I bought them for opening night. My ticket says very clearly “Wednesday 12:01AM 5/18/2005”. I haven’t been paying attention to when opening night was supposed to be for the world, but I thought that I could trust my ticket. I received a call from my girlfriend today. She informed me that the movie is tomorrow night and not tonight. I think it is absurd, but she worked in a movie theater before and insists it is true.

So I walk to the theater. I ask a few of the desk workers if it is true that the movie isn’t playing tonight but is instead playing tomorrow.

“Yes.”
Why?
“Because it is Wednesday.”
But TONIGHT is Wednesday. TONIGHT is when it is 12:01AM on Wednesday.

At that point, one of them claims to have warned some manager about people getting confused about this issue. The other workers just apologize and say that it is meant to be Thursday morning, Wednesday night. As if them telling me that makes it alright now. One apologizes because that’s how the computer printed them out. As if some person didn’t make the computer do that. One reassures me that I’ll be able to get in tomorrow, as if that was my concern.

The ticket says one thing, but they “meant” another. I’ve been fairly upset about it all afternoon. I drove in today instead of taking the train since I knew I wouldn’t be back at a reasonable hour. I planned on using tomorrow to work on my presentation. Now because I was supposed to just know what they meant, I can’t work on the presentation tomorrow, and I didn’t get started on the presentation today until I got home hours later than I normally would have.

So tomorrow I will be going to a movie a day after what the ticket says. Imagine if the bank or your job worked this way. Direct deposit goes through on Friday? Nope. It’s actually Saturday. Father says to daughter, “Be home by midnight” only to find out that she is gone for a day longer than he thought she should be.

If the movie is 12:01AM on a Wednesday, it means I need to leave my house on Tuesday to make it in time. Unless you’re the movie theater, in which case it means you need to leave on Wednesday night, almost a full day after 12:01AM. GAH!

Categories
Geek / Technical General

DePaul Linux Community Install Fest

May 14th, this Saturday, will be the DePaul Linux Community Install Fest. It’s open to everyone, so if you’re in the Chicagoland area, check out the information on DLC’s website. Here’s a handy map to the event.

Categories
General

Learning Kyra: Hit Detection

The Learning Kyra series to date:

  1. Learning Kyra
  2. Learning More Kyra
  3. Learning Kyra: Attack of the Clones
  4. Learning Kyra: Tiles and Z-Ordering

I covered collision detection already, but it was in a limited capacity in Attack of the Clones. Basically, I checked if a sprite was colliding with a specific object. But what happens when I want to check for collisions with objects that have been added dynamically and prevent me from anticipating them at compile time?

The code below creates a number of sprites from the same resource. Kyra comes with the Grinning Lizard Utilities, so those are prefaced with Gl. I think that it makes it confusing if you want to mix your code with OpenGL, but whatever. One of the utilities is GlDynArray, which acts very much like the C++ Standard Library’s vector class. While it is in the provided demo code, I couldn’t find any mention of it in the documentation. I simply followed along with the demo in shooter.cpp. I created an array and added 10 ghost sprites to it. In the code below, MAX_GHOSTS is equal to 10. I also add those sprites to the tree.

KrSpriteResource* ghostRes = engine->Vault()->GetSpriteResource(GHOST_ghost);
GLASSERT( ghostRes );

KrSprite* ghost = new KrSprite( ghostRes );
ghost->SetPos( GHOST_START_X, GHOST_START_Y - 64);
engine->Tree()->AddNode( midgroundTree, ghost );

GlDynArray< KrImage* > otherGhost;
for (int i = 0; i < MAX_GHOSTS; ++i)
otherGhost.PushBack( new KrSprite( ghostRes ));
for (int i = 0; i < (int)otherGhost.Count(); ++i) {
otherGhost[i]->SetPos( GHOST_START_X, GHOST_START_Y );
engine->Tree()->AddNode( midgroundTree, otherGhost[i] );
}

So now I have a bunch of ghosts bunched up in the center, which is where GHOST_START_X, GHOST_START_Y sets them. I placed the player’s ghost about two tiles higher. Since I was going for simplicity, and I mostly hacked out this code without designing it first, I just made the sprites in otherGhost move around randomly. Another utility is GlRandom, which provides random number generators that are superior to rand() provided by C++. The following code demonstrates how I used it:

GlRandom random;

...
//the following is in the main loop
for (int i = 0; i < otherGhost.Count(); ++i) {

...
otherGhost[i]->SetPos( otherGhost[i]->X() + (random.Rand(3) - 1) * moveSpeed , otherGhost[i]->Y() + ( random.Rand(3) - 1) * moveSpeed);

...
}

So now each of the sprites in otherGhost move in random directions. I move the original ghost much the same way as I moved my clone sprite in previous Learning Kyra entry. Well, there is movement for the player and other objects, but what about collision?

if (engine->Tree()->CheckSiblingCollision(ghost, &hit, 0) ) {
for (int i = 0; i < (int)hit.Count(); ++i) {
engine->Tree()->DeleteNode(hit[i]);
int j = otherGhost.Find(hit[i]);
otherGhost.Remove(j);
}
if (otherGhost.Count() < 1 )
done = true;
}

Very simply, if the main ghost collides with any of the other ghosts, those ghosts disappear. When the last one disappears, the main loop ends, and since I hacked this out instead of designing it, so does the program. Still, it is game-like. I experimented with other options to see what else I could do.

Instead of removing the ghosts from the tree, you could make them stationary, sort of like in Freeze Tag. As they get hit, I remove them from the otherGhost vector to keep them from moving about, but I also added the following to fade them a bit:

KrColorTransform color = hit[i]->CTransform( 0 );
color.SetAlpha( 50 );
hit[i]->SetColor(color, 0);

While it isn’t fun or polished in any way, I don’t think I can expect too much more from this specific project, at least not without struggling through painful changes. I didn’t set specific goals so the project simply evolved. I’ll consider this project complete and move on to a new project that will benefit from my new experience and some better design. You can download the project as it stands from one of the links below:


KyraGame-r1.tar.gz
KyraGame-r1.zip
Kyra Source in .tar.gz format
Kyra Source in .zip format

NOTE: You will need Kyra v2.0.7 to use this code. Also, the comments in the code weren’t all updated to reflect the fact that I’ve changed it. It is licensed under the GPL or LGPL as specified.

Categories
General

Learning Kyra: Tiles and Z-Ordering

Another entry in the Learning Kyra series. The series to date:

  1. Learning Kyra
  2. Learning More Kyra
  3. Learning Kyra: Attack of the Clones

The first three entries in the series documented my attempts at learning about the engine. I had a goal to become more familiar with the engine by the end of the month, so those articles were more focused. While that month has since passed, I am still learning plenty about the engine.

Recently I learned how to create tiles. Originally I was creating sprites, and they are sufficient for making games. However, I can also use tiles, but the documentation warns:

A Tile — in contrast to a sprite — is always square (width == height.) It can be rotated and flipped, however. You should always use Sprites unless you need to rotate and flip the image.

Making sprite images and making tile images are similar activities. When I use the Kyra Sprite Editor, I need to specify tile instead of sprite. Tiles are simpler since I do not need to mark hotspots and verify that they are aligned correctly. I was able to get three tiles very quickly, and saving created the .xml file to use. Then I used the Kyra Encoder and created the appropriate .dat and .h files. I copied those over to my source code directory.

The code to load a tile is different from the code to load a sprite, and the tutorial doesn’t cover it. I had to look at the Bug-Eyed Monster (BEM) demo code to find an example that I could use. To load a sprite, you have to do a few steps:

  1. Load the .dat file
  2. Get the KrSpriteResource as specified in the header file you created
  3. Create the KrSprite from the KrSpriteResource

Loading a tile is a little more complex:

  1. Load the .dat file
  2. Get the KrResource
  3. Get the KrTileResource by using KrResource::ToTileResource()
  4. Create the KrSprite from the KrTileResource

Ok, so there is only one more step, but it took me some time to find how to retrieve a KrTileResource. For instance, to get the KrSpriteResource, there is a function: GetSpriteResource(name_of_resource). To get a KrTileResource, however, you first need a generic resource by using GetResource(ALLCAPS_TAG, name_of_resource), and I couldn’t find the documentation on what that tag should be. It turned out that they were defined in kyraresource.h, and the one I needed was KYRATAG_TILE. Again, it was not in the tutorial so it took some work for me to learn what was needed. Here is the relevant code, keeping in mind that when I used the encoder, I prefaced everything with Tiles2_ (I already had a previous attempt with Tiles_) :

KrResource* res = engine->Vault()->GetResource( KYRATAG_TILE, Tiles2_tile2 );
GLASSERT( res );
KrTileResource* tileRes = res->ToTileResource();
GLASSERT( tileRes );
KrTile* tile = new KrTile( tileRes );
GLASSERT( tile );

tile->SetPos( 130, 98 );
tile->SetRotation(1);
engine->Tree()->AddNode(0, tile);

Anyway, I imagined that the tiles I created would be pretty cool to work with since they have alpha transparency. I could make clouds or chain-link fences, for instance. As I moved a sprite to the tile, I expected that the sprite would show through the tile’s transparent spots; however, when adding an image to the engine’s tree, the order matters. Since I added the sprite after the tile, the sprite image overlapped the tile image. I switched the order in the code, and it worked perfectly fine.

But then I was concerned. In a game, elements will get added dynamically. I wouldn’t want to find that a new enemy can walk over tunnels, or that the hero walks under floor tiles! Then I learned how the BEM demo handled Z-Ordering.

Everything that can be in the engine’s tree inherents from the base class KrImNode. KrSprite and KrTile are both KrImage classes, and KrImage is a KrImNode. KrImNode isn’t an abstract class, and it is the key to handling Z-Ordering.

Usually when I add a sprite or tile to the engine, I use the following code:

engine->Tree()->AddNode(0, tile);

AddNode()’s first parameter in this case is 0, which means that in the tree, it is a child of the root. If I add a second child, it will be drawn over the first child when the following code gets run:

engine->Draw()

BEM handles Z-Ordering by creating subtrees. Background images should be added to the backgroundTree while foreground images should be added to the foregroundTree. You create those trees in the following way:

KrImNode* backgroundTree = new KrImNode;
KrImNode* foregroundTree = new KrImNode;

engine->Tree()->AddNode(0, backgroundTree);
engine->Tree()->AddNode(0, foregroundTree);

Now, when I create a tile that goes in the background, I use AddNode(backgroundTree, tile1). Naturally I would have a separate subtree or two for entities I want to always be between the background and the foreground. If I need to create tiles for the foreground, I can add them to the foregroundTree:

engine->Tree()->AddNode(foregroundTree, tile2);

And tile2 will always be drawn on top of any images that are siblings to tile1, even if I add an image to backgroundTree after adding tile2.

Now that tiles and the Z-Ordering methods are added to my toolbox, I’m becoming much more dangerous with the Kyra Sprite Engine. Using just what I know now, I can probably make a fairly simple game without struggling with an unfamiliar library. There are still a few features to learn, however, including:

  • Fonts
  • Alpha blending and color transformations
  • Scaling
  • Canvases
  • Sub-window views

I may tackle one or two of these in the next Learning Kyra post.

Categories
General

Reading in 2005

Earlier this year, I noticed some developers are making book lists on their blogs. Sillytech and Joost Ronkes Agerbeek’s lists are two of them. I have been keeping a private list of books I am reading and have read, but I think it will be useful to post the list online as well.

I plan on having a sidebar similar to what is on Games From Within. In the meantime, you can see a listing in this blog post.

Books I Am Currently Reading

  • On Writing by Stephen King

Books I Have Read in 2005

  • 100 Ways to Motivate Yourself by Steve Chandler (Audio Book)
  • Alice’s Adventures in Wonderland by Lewis Carroll (ebook)
  • C++ Coding Standards by Herb Sutter
  • The Curious Incident of the Dog in the Night-Time by Mark Haddon
  • First Things First by Stephen Covey
  • Getting Things Done by David Allen
  • Live Without a Net by Lou Anders (Editor)
  • The Object-Oriented Thought Process by Matt Weisfeld
  • Ready for Anything by David Allen
  • The Seven Habits of Effective People by Stephen Covey
  • Through the Looking Glass by Lewis Carroll (ebook)

Some people try to read at least one book a week. It’s the 18th week or so for the year, so I am about six books behind. I never actually set such a goal, of course, but I should. I’ve found that I can have much more intelligent conversations and tell much funnier jokes (at least to me) since I’ve started reading regularly. I have learned so much more than I would have if I had neglected the literature, and some of it, such as Getting Things Done, has changed my life in amazing ways.

I’ve found that I’ve been focusing on personal productivity a bit too much, so I’ve tried to add works of fiction to the mix. Besides science fiction, I’m interested in mystery novels as well, but I am not familiar with what is good outside of Sherlock Holmes and Hercules Poirot. Anyone have any suggestions?

Categories
General

The Courage to Take a Seat

Last night I went to a seminar hosted by my university’s Alumni Association. It was called Four Under Forty, a play off of Crain’s Chicago Business’ annual Forty Under Forty. Four members of the list were on the panel at the seminar, including this past year’s David Marco and Mike Domek, as well as last year’s Thad Wong and Noreen Abbasi. The panel members were asked a series of questions, and it was an interesting event.

Among a few themese I noticed was the idea of courage. Thad Wong simply exuded confidence and made the claim that he believes he could do anything anyone else has done. Nothing should be impossible for him if someone else can do it. But even then, believing in himeself was key to his success. David Marco made similar comments.

I was thinking about courage when I went home afterwards. I was reading Stephen Covey’s book First Things First and specifically his treatment on the need for courage. And with this topic on my mind, I saw something happen on the train that seemed appropriate.

There was a woman sitting with a bag sitting next to her. The train was getting quite crowded, and I saw some people walking towards the seat, only to turn away once they saw her bag there. Maybe three or four people acted similarly, turning away as if turned away from a fountain. Then one person got on the train, walked up to the seat, and simply asked the woman if she could move her bag. The woman complied. This new person won her seat on the train because she wasn’t afraid of what might happen if she asked. She simply did it.

And if that isn’t an oversimplifed metaphor for what courage can do for your business, I don’t know what is. You can’t win unless you play. Whether it’s just getting a seat on the crowded train or starting your own business, if you don’t attempt to do it, you force yourself to stand and watch as someone else does.

Categories
General

Last Week of Class

Tomorrow is my second to last final of my graduate school career. Thursday is my last one. Then I am free.

Free to learn about the topics I want to learn about when I want to learn about them.
Free to learn at a faster or slower pace as I choose or need.
Free to use my time to make a difference in my own abilities for my own sake rather than for a higher GPA.

Some people want to go on for higher education, and that’s fine. Maybe in the future I might see a need for it myself. But not now.

Seth Godin wrote about some Harvard hopefuls who will not be able to attend because they found their admissions status early in Good News and Bad News:

The fact is, though, that unless you want to be a consultant or an i-banker (where a top MBA is nothing but a screen for admission) it’s hard for me to understand why this is a better use of time and money than actual experience combined with a dedicated reading of 30 or 40 books.

If this is an extension of a liberal arts education, with learning for learning’s sake, I’m all for it. If, on the other hand, it’s a cost-effective vocational program, I don’t get it.

So those rejected by Harvard (for a stupid reason, I might add) may in fact have been given a gift. Why spend years sitting still in school learning about the past, when you can blaze a trail onwards and read about the past at the same time?

It’s what I hope to do.

Categories
General

Comment/Trackback Spam

Ever since I started this blog, I’ve gotten comment spam and trackback spam. It used to just be someone using a handle that will link to some poker site, but now they are getting insulting. “It’s people like you are the problem with this country” was the latest one. Well screw you and your online poker website!

EDIT: And it seems that Seth Godin is also posting about blog spam, but this one is of a different nature.

Categories
General

Blogging is Advanced Netizenship

The concept of “citizen publishing” is one I heard originally from Ripples. It inspires images of any person being allowed to say what he wants to say without some corporation or government telling him he needs to conform to rules and regulations or satisfy some shareholders or appeal to some mass market. Naturally some people may not have much to say compared to others, but that just gives people the incentive to blog greatly. People read blog posts by Seth Godin because he is not only an authority in his area but also writes about important and compelling things. On the other hand, if someone blogs about inane things or makes stale arguments, it is less likely to be read. But the nature of blogs is that he’s still there, and if someone wants to listen to him, he/she can.

To paraphrase a line from The American President, blogging is advanced netizenship. You can post in an IRC channel, and within minutes your comments are gone, possibly remembered in some obscure log file. You can post in a web forum, among all the other posts there. Eventually it can drown out. But your blog is the online extension of yourself. Your commentary. Your views. Your growth experiences. People may have different opinions, but you have yours.

From Playing With Fire:

When we engage in blogging, we are playing with fire. We are harnessing the power of open communication in ways which will shape our future in ways we can’t even imagine.

To drive this point home, you should realize when we blog about something, we actually change our future in respect to that area on the fly. Now, if that isn’t that a sobering thought, what is?

Sobering indeed. Each blog post has the power to change viewpoints, politics, public opinion, and trust levels, and wielding such power should give people pause. One of the things analysts will tell you is that while blogging has had the power to topple major mainstream news figures and politicians, it is also something to be wary of. Someone may post something erroneous, and the nature of blogging is that it will spread like fire.

Of course, what this fails to take into account is how fast corrections can be spread as well. Print newspapers have to wait a day to post a correction, and the correction will usually be buried in some 12th page or something. Bloggers making corrections are front and center. Still, the concept of any one person being able to cause such a massive ripple through the World Wide Web, of any one person being able to publish his/her information to the world without placating some commercial publisher, of individuals all having so much more power than before is awesome. Nothing has probably had as much inspiring discussion about it as when the idea of “government of the people, by the people, for the people” was first introduced.