Categories
General

Open Source Business Models

Forbes.com’s article “The Open Source Heretic” is about Larry McVoy, the CEO of Bitmover, and his comments on how open source business models are not sustainable.

Bitmover makes BitKeeper, a version control system system ideal for distributed developers. The Linux kernel currently uses it, and it has been given to the open source community to use free of charge. Until now. Apparently some developers wrote add-ons for the product, but doing so is in violation of the licensing terms. After arguing with some members of the development group, McVoy decided that he wouldn’t provide free support anymore. For more info, see Red Herring’s “An End to Free Linux Support”.

Anyway, McVoy made a lot of comments in the Forbes article regarding open source business models. Nothing truly innovative comes from it. If you take away the hardware companies that are funding most open source developers, the model fails. He can’t think of any way that open source can fund itself…

And though open source software may be “free,” sometimes you get what you pay for, McVoy says. “Open source software is like handing you a doctor’s bag and the architectural plans for a hospital and saying, ‘Hey dude, if you have a heart attack, here are all the tools you need–and it’s free,'” McVoy says. “I’d rather pay someone to take care of me.”

Oh! Oh wait! What’s this?! One of those business models! McVoy, you’re a genius! Since most people don’t give a damn about the code, and they don’t care to learn, and if they are willing to PAY for someone else to do it for them, THAT’s a business model. There is a demand, and you supply it. Huh. Who’d have thunk it?

I didn’t like how the Forbes article kept insinuating that “open source” means you have to give away your code for no cost. For instance, I use Debian as my distro of choice, and I use many of the packages. I only get the source for something when I explicitly ask for it. With Debian and most distros, I can get the source independent of the binary, but legally Debian doesn’t have to provide the source unless they provided me a binary for code under the GPL.

There are other business models. Dual licensing works wonders. Just ask Trolltech about their Qt library. Or id, which gives away the source to their old game engines and yet doesn’t find people trying to redistribute the original and proprietary Doom game data with the source code. There are embedded devices running open source, and I’m sure those hardware manufacturers aren’t too keen on going back to running proprietary and expensive operating systems. Zope was way more successful after the source was released than before it.

Support. Consulting. Custom development. Web services. Hosting. For some reason these are supposed to be the exclusive domain of software that is not open or Free? Right.

Once again, “FOSS” is not mutually exclusive with “commercial. “McVoy understands open source as well as anyone on the planet”, according to the Forbes article because his non-open source was used by many open source developers. While it is possible for someone who is against FOSS business models to be an expert on it, I’m a bit skeptical. Time and time again we’ve found that Coca-Cola isn’t exactly an expert on drinking patterns when they release drinks like “New! Lemon-Lime-Grapefruit-Extreme-Diet Coke”, and yet lots of soft drink drinkers use their products.

Categories
Geek / Technical General

Support for Gnu/Linux Systems

People who use Windows have a couple of huge advantages over people who use Gnu/Linux: games and hardware/service support.

Defeating the no-help desk is an article on Newsforge that talks about how to get around tech support that isn’t helpful if you run something other than what is explicitly supported.

What you should never reveal

Many call centers bill by the call, so they are focused on the number of calls they complete, not the number of problems solved or the degree to which customers are satisfied. In these situations, the phone support person you’re calling has one duty: to get you off the phone as fast as possible without breaking the rules. There may not be as much concern for whether your problem is solved as you’d like. That means that the support person’s first strategy may be to find a reason why he cannot help you. If so, your response should be to eliminate every reason that he might have to end the call.

I’ve worked part-time at a help desk for a few years. In the beginning the goal was to solve problems. Near the end of my employment I was told by someone that the new goal was to get off the phone within two minutes. I wasn’t told in an official way, so I didn’t pay attention to it. What I found was that I was making a lot of people happy by actually solving their problems, especially after others might have gotten them off the phone fairly quickly.

But this post is not about poor service. This post is about support issues when running Gnu/Linux.

A lot of companies have a policy of not supporting anything but users running Windows and maybe Mac OS X. Sometimes this policy makes sense, such as ActiveX controls or DirectX issues. Fine.

How about ISPs? They provide a network connection, and NOTHING about the operating system you use should matter. Yet if you don’t run exactly what they require, you’re out of luck. In my area, I had a choice between cable and two DSL providers. I asked questions. The general idea:

Cable company: “We offer one package. You can use one computer. It must run Windows.”
Local phone company’s DSL: “We offer PPPoE, so it isn’t always on, you must login to use it each time, and we require you to run Windows.”
Speakeasy DSL: “We give you a network connection. So long as it isn’t illegal, you can do whatever you want with it.”

Speakeasy was way more expensive than either of the other options. I went with Speakeasy anyway. I don’t have to pay extra for each machine on my network. I don’t have to pretend to be using a different OS. I don’t have to lie. I also get very knowledgeable tech support whenever something goes wrong. When I move into a new place, I am making damn sure I get Speakeasy again.

Similarly, if hardware fails, the fact that I am using Gnu/Linux shouldn’t matter. A bad hard drive is a bad hard drive. A fried motherboard or CPU is just that. No, I highly doubt that the fact I was running Firefox instead of IE matters. I don’t think that Gnu/Linux use prevents someone from replacing the CD drive. At this point, drivers don’t matter. The fact you don’t support the use of the device under Gnu/Linux doesn’t matter. Imagine telling someone using Windows that a failed hard drive can’t be supported because Service Pack 2 isn’t supported or the use of non-Microsoft products on the system voids the service support contract.

Well, in that case, there might be enough people that think that they have no choice in the matter and give up. They’re used to it by now. People have been conditioned to be afraid of the computer. If something goes wrong, they are conditioned to believe that it is their fault and nothing can be done. “We don’t support it” is simply translated as “Do exactly as we say or else you lose all of your photos and term papers!!”

I like computers. I am not intimidated by technology. I made sure I was knowledgeable enough to have a choice. I didn’t like the idea of Microsoft’s Activation, so I made Gnu/Linux my main operating system. These days it is easier than ever for people to do this switch, especially with distros like Knoppix, Ubuntu, and others. Unfortunately, “we don’t support it” forces people to stay with an otherwise lacking system like Windows. “My digital camera won’t on Gnu/Linux?” “I just paid $300 for this printer and there are no drivers for it?!” “I have to run Windows just to check my email?!?”

So there are a few options to get support:

  • Keep Windows around, either on a second machine or a dual boot configuration.
  • Lie about what you’re using, requiring that you’re knowledgeable.
  • Not use the service or hardware.

Some people find one or more of the options unbearable. Hardcore Free Software people wouldn’t want to use Windows nor would they want to lie about what they use. Others would be hard pressed to do without the service or hardware. Either way, everyone loses.

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.