Categories
Game Development Linux Game Development

Still Learning SDL

I was rereading Programming Linux Games the other day. I love rereading books because there will always be something that you didn’t notice the first few times through. This time, I learned two ways to render sprites much more efficiently than I was currently doing. I had heard about these two techniques, especially from my first readings, but I forgot about them.

Understanding colorkeys

In Chapter 4, Mastering SDL, John Hall talked about setting colorkeys to simulate transparency when drawing sprites. If you’ve ever seen the image files in many games and tutorials, you’ll notice that they aren’t transparent images. See Aaron Cox’s sprite tutorial for an example. Usually the sprite being rendered will be surrounded by a certain color, sometimes hot pink, but no matter what, there is a color instead of complete transparency. The reason why the sprites render as if they are transparent is because that color is set as the colorkey, and SDL knows not to render it.

Why not just use alpha values in an image? You get the same effect, right? While the end result might look the same, the amount of processing power you need is not the same. To render alpha values properly, there are calculations needed for each pixel. The surrounding pixels are taken into account, and the final value is determined before the color is set. With colorkeys, the pixel is either rendered or not rendered.

If you have a game in which it is possible for many sprites to overlap, calculating alpha blending for otherwise blank areas of multiple sprites will slow down rendering time. Maybe faster computers won’t even blink, but you might be increasing your game’s minimum hardware requirements needlessly.

Understanding Display Format

SDL allows you to load images from a file into an SDL_Surface. To render them to your screen, which is also a surface, you simply blit them together using SDL_BlitSurface(). Hall also warns that doing so with slightly incompatible surfaces can slow down rendering. If your sprite is in one format, and your screen is in another, SDL must convert the sprite to the screen’s format before rendering. It does this transparently so you don’t need to specify anything, but do you really need to do these calculations every time it renders?

No. SDL_DisplayFormat() will take a surface and return a surface that is in a format that is optimal for fast blitting to your screen.

Here’s what threw me off. My code was organized like so:


if (!isSDLVersionUpToDate() ||
!initializeSDL() ||
!initializeWindow()) ||
{

My code first checks to make sure you have an up-to-date SDL version on your system. Assuming that’s cool, it initializes SDL using SDL_Init() and gets my program ready. Then it creates the window and sets up my main screen surface for rendering.

I then changed the sprite loading code from:


m_sprite = IMG_Load("foo.png");
if (NULL == m_sprite)
{
// output error
}

to


SDL_Surface * tempSprite = IMG_Load("foo.png");
if (NULL == tempSprite)
{
// output error
}
m_sprite = SDL_DisplayFormat(tempSprite);
if (NULL == m_sprite)
{
// output error
}
SDL_FreeSurface(tempSprite);

All fine and good, except my sprites were getting loaded in initializeSDL(). (NOTE: Yes, this is bad. The name of the function didn’t indicate that it was also loading sprites. I was the one who wrote this code, and I was the one getting burned by it). When I tried to change my sprite loading code, SDL_DisplayFormat() kept returning NULL, which indicates failure. Why was it failing, though?

After asking on IRC and doing research online, I found out why. SDL_DisplayFormat() converts your surface into an optimal format for fast blitting to the screen. Well, until you create a screen, how does it know what that format should be? In my code, SDL_SetVideoMode() gets called in initializeWindow(), which was after the sprites got loaded, so of course SDL_DisplayFormat() would fail. It didn’t know what the optimal format would be because we hadn’t created the format target! Well, that’s an easy fix. I just moved the sprite loading code to its own function, which I called AFTER initializeWindow(). Now SDL_DisplayFormat() returns a valid surface.

Of course, I hadn’t set the colorkey yet, and I wasn’t ready to make the changes to the graphics as it was getting late, so to make sure my game otherwise looked the same, I changed all calls to SDL_DisplayFormat() to SDL_DisplayFormatAlpha(). Now it converts the surface to allow for faster blitting, and it handles alpha transparency correctly. It isn’t the most efficient, but it is definitely an improvement over what I had before. I still intend to convert my transparent images to opaque ones that get rendered properly using colorkeys since there is still a performance gain there.

Hopefully, my efforts helped someone out there, if only by allowing them to play games without needing to spend the money on upgrading hardware.


Categories
Game Development Personal Development

Thousander Club Update: August 18th

For this week’s Thousander Club update:

Game Hours: 409.25(previous two years) + 114.5 (current year) = 523.75 / 1000
Game Ideas: 710 (previous two years) + 36 (current year) = 746 / 1000

I managed a few hours of development this past week, which is quite a few less than I expected to do, but progress is progress. I reorganized my subversion repositories with the goal of separating common libraries into their own project that can be included by my own projects. Before this change, each project was in its own repository, and they had the same build scripts for the same custom libraries, which was a lot of duplication. Subversion has something called svn:externals which allows my checked out project to essentially include a different project under it. It should be pretty handy for common tools, scripts, and code across projects.

I finally got around to changing the drawing of the goal in Minimalist from a blue filled rectangle to an actual sprite image.

Goal

I want it to animate with the text spinning around it, but the important thing is that it does a better job of standing out from the red rectangles.

Also, I would like to change the name of the game. Minimalist got its name from the theme of Ludum Dare #11, but I think the game should be named something more appropriate. I’m thinking Walls, since the game now features obstacles that close in on you.

[tags]game, game design, productivity, personal development, video game development, indie[/tags]

Categories
Game Development Games Marketing/Business Personal Development

Cliffski Was Civil with Pirates?

If you’ve ever discussed copyright infringement, indie game business models, or even chess with Cliffski, you would know that he vehemently HATES so-called piracy. In fact, if you even argue that it isn’t the same as stealing and that piracy is a silly name for it, get ready to be flamed.

Or maybe you don’t have to worry about it as much. In a move that surprised many, he wrote a blog post asking “Why do people pirate my games?” in which he invited people to explain their true motivations. In fact, it would have been expected if he would have turned around and tried to prosecute anyone who admitted it to him, but instead, true to his word, he kept an open mind, and came away with some lessons.

He details what he learned in Talking to Pirates, and he’s changing some aspects of his business.

A big one: No DRM.

I only used DRM for one game (Democracy 2) and it’s trivial. It’s a one-time only internet code lookup for the full version. I’ve read enough otherwise honest people complain about DRM to see that its probably hurting more than it help’s. I had planned on using the same system for Kudos 2, but I’ve changed my mind on that. I have also removed it from Democracy 2 today. I now use no DRM at all.

Again, I’m surprised that of all the indies out there, Cliffski was the one to not only ask why people prefer to not pay for his games but also listen to the responses, but I’m pleased. I know that I’ve made these arguments, that people don’t like DRM because they don’t like being treated as a criminal, but I’ve been dismissed before as not knowing what I talk about. Now Cliffski comes and does this, and getting rid of DRM is justified as good for business? Huh. Who’d have thunk it?

I suppose even if he didn’t get this beneficial feedback, his sales would still pick up significantly from getting the publicity from Slashdot and Digg. Whether or not he expected to get this much traffic from this article, or such good feedback, I don’t know, but hopefully we’ll find out soon.

Categories
Game Development Personal Development

Thousander Club Update: August 11th

For this week’s Thousander Club update:

Game Hours: 409.25(previous two years) + 110.25 (current year) = 519.50 / 1000
Game Ideas: 710 (previous two years) + 36 (current year) = 746 / 1000

Wow, I did a lot of game development this past weekend! Ludum Dare #12 wasn’t a big success for me, but I’ll have more to say in a post-mortem of Tower Defender. Along with my LD#11 entry, Minimalist, I intend to properly finish these games and release them. Minimalist should hopefully be out by the end of August at the latest.

[tags]game, game design, productivity, personal development, video game development, indie[/tags]

Categories
Game Design Game Development Geek / Technical Linux Game Development Personal Development

LD#12: GBGames Time Lapse!

My first time lapse was over 10 minutes long, and so I had to cut out a lot of the repetitive images to shorten it. I also found a way to combine music with it.

Categories
Game Design Game Development Geek / Technical Linux Game Development Personal Development

LD#12: Final Submission

Tower Defender Game Play

Tower Defender source. This is a source only version, and it is 8MB!

Get your smaller Linux-binary here: Tower Defender for Linux

A Win32 binary should be forthcoming.

Unfortunately I only got game play in at the last few minutes, and there are problems. For one, there is no way to win or lose. The enemies don’t know that they’ve already stormed the walls and will keep going until they hit the sky, but they do this cool floating thing…which is a bug. Mousing over the archers will make them fire arrows, and they take a bit of time to reload before letting you fire again. The arrows do hit the enemies and make them disappear.

I’ll have a post-mortem up soon.

Categories
Game Design Game Development Geek / Technical Linux Game Development Personal Development

LD#12: Lunch with Gizmo

Gizmo tends to like to hang out with me whenever I’m doing anything related to programming. I nicknamed her Hacker Kitty. She’s helping me eat my vegan pizza and apple juice.

Gizmo helps me with food preparation

Diego, on the other hand, just wants to know when I’ll be done.

Diego wants to know if I'm done yet

Well, I’m not done yet, but I have a few more unit tests, and quite a few more lines of code without tests. Progress is being made.

Categories
Game Design Game Development Geek / Technical Linux Game Development Personal Development

LD#12: More Design

I was sketching out some of the interactions and just trying to make myself aware of what it is I am tackling with only 8 hours left.

More design

Based on these notes, I think my schedule should be as follows:

  • Code to draw tower based on height (determined by difficulty, a nice to have later on).
  • Draw an enemy sprite.
  • Code to move enemies up the tower.
  • Code to determine that game is over if they reach top of tower.
  • Code to mouse over an archer.
  • Draw an arrow.
  • Code to move arrow.
  • Code to handle collision of arrow and enemy.

And after all of that, I should have a good base to work with. I’ll see how much time is left and make further plans when those are done. The cool thing is that I can start writing unit tests again for the classes I’ll be writing.

Categories
Game Design Game Development Geek / Technical Linux Game Development Personal Development

LD#12: Good ol’ Jarritos

It’s strawberry flavored!

My kitchen is a mess and I’m out of clean glasses, but at least Jarritos doesn’t need a glass to be enjoyed!

Strawberry Jarritos...and grape juice...

And while taking the picture, I realized I have a bottle of…grape juice…and some clean glasses for it. Hmm…

Categories
Game Design Game Development Geek / Technical Linux Game Development Personal Development

LD#12: Tower Defender’s Best Knight

The Knight Owl!

The Knight Owl

He’s 32×32, and I’m worried he won’t show up too well after all the work I put into it. Note to self: learn how to use the Gimp better.