Thursday, June 23, 2011

Short little post about C++ const-correctness

Ok, so I don't really like the concept of "const-correctness" in c++, but I never really had a solid reason to dislike it besides laziness. Hence I never really bother to mark class functions as const (except in basic numerical types like Vec2D) unless the compiler whines about it.

Well, until yesterday that is. I was writing a rational number class for the hell of it (mostly as a little exercise for myself). Internally, it's represented as a numerator and denominator value. Now here's the thing: Rational(10, 4) and Rational(5, 2) are effectively identical and behave exactly the same way as far as any user could tell, even if they're represented different internally. A function, Rational::reduce(), changes the internal representation of the number without actually changing the value of the number. For all intents and purposes, this function is constant.

A few operators require reducing the rationals first, notably operator== (which most would agree should be a constant function).

Yet, reduce can't be labeled const because it changes numerator and denominator, therefore operator== either has to work with temporaries or also can't be labeled const.

Solutions:
- Marking numerator and denominator as mutable, but that's just stupid and unsafe since at this point you basically completely throw the notion of const correctness out the window and you may as well just not mark anything as const [which ends up happening in most of my personal projects].

- const_cast<Rational*>(this)->numerator = blahblahblah
[this is quite ugly, though it does work]

-
void reduce(){ //reducenumbercodehere }
void reduce() const {const_cast<Rational*>(this)->reduce();}
[this is also ugly and boilerplate-y]

//////////////////////
What c++ SHOULD have is a way to mark a function as "mutable const". We can do it with variables already, why not also with functions? Yes it could be abused but so can mutable variables and const_cast.


I'm sure there's other examples of this problem occurring, but I figured this is a pretty easy to understand real-world example.

Thursday, September 2, 2010

Spoilertastic Criticisms of Metroid: Other M

Metroid: Other M was a good game, not by metroid standards at all (i think metroid prime is the best game of all time though, so its tough to live up to it) but the action parts and bosses were usually top-notch (the controls were ugly, but they worked since they built the game around them). This post isn't about what I liked about the game, it's just a general criticism of a lot of decisions they made gameplay-wise. I'm not gonna cover the stuff everybody says, just the things I noticed that didn't seem to get much mention in other criticisms of the game. Spoilers do follow, so be warned.


Team Ninja's "explanation" for why you can't use your powerups is shoddy at best. Some sort of explanation like, "super missiles could damage the hull of the ship" or "wave beam might have unforseen consequences in a contained environment, so we won't let you use them unless you absolutely need to for success" could have gone a long way. Not, "Oh you can't use your varia suit right now, even though you're burning to death". You know, give some context as to WHY adam makes these decisions for samus. After all, there's a strong theme that samus trusts adam since he makes good decisions (and it's his only role in the game really, as commander), so explain then, why it's a good decision to not allow use of grapple beam. In most cases, this doesn't effect gameplay all that much (replace "plot event" with "collect item") but it definitely defeats the impact of collecting a powerup.

For example, when you get the grapple beam. Anthony is in trouble and you need the grapple beam to get to him. Adam won't give it to you until you lock on to the grapple target. But, hey, why the FUCK would I look at the grapple target if I don't have the grapple beam? I lost about 5 times there before going, maybe I can just use the grapple beam out of desperation.

Then, adam goes missing, and samus is like "fuck that I'm using space jump" ("any objections adam?" = best line in game), then adam dies, and samus is like "well I guess I can use my powerups now, but I'm gonna wait till I need to" and over the course of like 10 minutes you get all your powerups. The last hour of the game you get so many powerups in a row it's just like..... come on man, make me work for them a little bit. It also doesn't tell you you can use power bombs when you get sucked into the last boss's stomach, I actually tried using a power bomb and it places a regular bomb so I figured I don't have them yet. As it turns out, I didn't charge for long enough (some feedback would have been nice for that). So I had to use an item I didn't know I had for the final boss. The one spot it doesn't give you a tutorial for how to use an item.

Also, team ninja was too lazy to make a new model of samus for the different suits, so they just put glow around her when the "feature" is active. WTF? That is just laziness.

The game feels unfinished. Only 3 sectors? Fusion, the game it borrows from, had 6, and they were interconnected. The sectors feel small for how few they are. I was really looking forward to sector 0, then adam is like "No i have to blow it up, sorry". This SHOULD HAVE BEEN PART OF THE GAME. Adam's "heroic sacrifice" doesn't seem that heroic when you don't know the dangers of the place he blew up. Also, they blow up the entire ship at the end, so really, what was the point? Adam doesn't seem to make very smart decisions, which is funny since his JOB is to make decisions. Also the end had rapid-fire powerup getting. I really think they originally intended to have sector 0 in the game, and more of the other 3 sectors, but time restrictions had them finish early. So they cut sector 0, and give you all your powerups at like the same time, and don't even bother modeling the gravity suit or the varia suit.

The Nightmare boss fight was totally awesome though, the fusion version was my favorite boss fight ever in the entire series (cause of its backstory and the melty creepy face). I was like, gravity suit here I come. Then you don't get it right then. And you get it a while later. The awesome part of metroid is how, when you beat boss that does gravity like that, your reward is the gravity suit. You know what's coming since each boss relates to the powerup it grants as a reward. Not in this game, the bosses are just there. No "Cool I get a powerup after this boss". Just, "oh hey another boss".

My end percentage was 34%, but since missiles are absolutely pointless, I really felt no desire to go back and search for the rest of the powerups.

Also, they never explain "The Deleter" (samus's nicknames for things really suck). He comes in as a plot device, then they ignore him completely in the end.

Saturday, May 1, 2010

Playing around with genetic algorithms

I played around with some genetic algorithms today for the enemies in my next flash game.

Here's a quick overview of the game (without giving away too many spoilers about it):
The player is given a planet which he can grow trees on. Trees which attack against these swarms of space bugs that are coming to do something to the planet. There's a lot of customization and balancing the player needs to do when growing trees, and a lot of options there. It'd be a shame for them to discover a dominant strategy within 5 minutes of starting the game and not try anything different to defend against incoming bugs. That can be prevented by making different kinds of enemies that counter common strategies, but that still leaves open a possibility for a dominant one based on the limitations of having a finite set of enemies or a hand controlled difficulty curve.

There's 2 parts to each "enemy". The "swarm" and the "bugs". A swarm has one behavior. It is invisible, but moves around the world physically and contains data about how it wants to orbit the planet and how fast it can move and how spread out the bugs in it are going to be. Each bug has its own behaviors and variables too, life, speed, how fast it keeps up with its swarm, how often it changes direction etc. With some defaults set it looked very "swarmy" and felt like very much like a swarm of gnats orbiting a planet.

Anyway, the thought came up today to use some genetic algorithms to make the enemies dynamic. I don't like to do too much research on topics before experimenting (rather learn for myself after knowing basic knowledge about it), so I didn't. Some issues that came up, there wouldn't be enough enemy swarms throughout the game to make for interesting adaptation or fast enough for how much control the player will have (although there'd definitely be enough individual bugs), so there had to be some sort of a way to "control" the evolution or speed it up a bit. Secondly, there's more than one type of enemy, each with different classifications for what counts as "success". I haven't actually implemented more than one enemy yet (or made them attack you) so I didn't worry about that one right now, but I have some ideas.

This is the structure I came up with and implemented today.
There's a base class called "Breedable" and a class called "Gene". Breedable contains a basic interface for species, with a mother and father reference, a "score" (ranking on how well it performs), and a function called "Breed" which child classes need to override. Gene is a wrapper around a Number (flash's "double" type) which defines mother and father genes, which breedable owns it, and some constants for how to combine genes during breeding. "Mix" specifies if the parent genes get averaged, or if it just randomly picks one or the other. "Mutation" is a range for how much to randomly mutate the number during breeding. "Inertia" is my solution for "speeding" up evolution. During breeding, it looks at it's parents' scores and their parents' scores to see if the previous mutation made the species "better" or "worse". It will then use that to randomly mutate the number again to lead it in the direction of "most success".

A "GenePool" contains a list of species and the scores they got. It has a maximum size (for how many of an individual species can exist at once in the pool). Before breeding, you refresh it which sorts itself by score and extincts the species which make it go over the limit. You then get species from it by calling "extract", which grabs 2 randomly (weighted by score), breeds them, and returns the new species which you pass on to the bug or swarm to create itself out of. When the bug/swarm is done, it grades it's species and puts it in the gene pool. When a species breeds, it's marked as old and gets sorted near the end of the pool the next time it's refreshed to ensure old species don't hang around forever (as species never get rescored once they're in the pool, just their new children do).

There's 2 species types I have right now. "SwarmSpecies" and "BugSpecies". Each swarm species contains a GenePool of bug species. When breeding swarm species together, it combines the bug genepools together too. The main game controller contains the swarm's GenePool. At each wave, it refreshes the pool and generates new species from it. Since enemies don't have a good metric for how well they performed right now (as I don't have the enemies being dangerous yet), the "score" is just how many ticks they could stay alive for.

Initial results look promising. After killing some basic bugs, I played with it a few times. Enemies realized that when they were close to the planet they were harder to hit (since less bullets could reach them when the planet was in the way), so new generations got progressively closer to the surface of the planet. I didn't like this cause if they were inside it makes them impossible to kill, so I added a minimum orbit distance. Yet again though, they found a way to burrow into the planet by orbiting fast and moving slow (they never had much time to catch up to where they were orbiting, so they lagged behind, conveniently inside the planet). After about 6 waves I had enemy swarms completely inside the planet, unable to be hit, effectively invincible. Trying again, I shot just the swarms who liked to bunch together before clearing out the rest, and sure enough the enemies got smaller and more spread out (= way harder to hit with big powerful shots, but much easier to hit with lots of tiny low power shots). I had to impose some limits on the speed too, enemies found out that if they moved very slowly, it would take them way longer to get in range of being shot in the first place. I even had an enemy just sitting there on the blind side of the planet not orbiting cause I couldn't hit it there. Variables that mattered less for survival tended to stay pretty random throughout the game, as expected too.

I'll probably keep this in the game. It makes it interesting, even though it still needs a lot of tweaking to get right (and of course, I need to make real enemies too).


Enemies have learned to burrow and grow huge

Monday, March 15, 2010

Things That Happened at GDC This Year

Important secret meeting with secret people
Awesome secret indie party, played spy party
Had a vodka-wasabi cocktail
Awesome gamma party (didnt get carded)
Broke my laptop
Met the Mega64 guys
Met JOHN CARMACK
Won the IGF audio category
Had another nice chat with Tim Schafer
Complained to a Kotaku guy in person about them not posting my trailer
Got denied from the Speaker party for not being 21
Hit Tommy Refenes on the head with an NVidia balloon
Talked for 5 minutes in front of an audience... about nothing
Ate $40 of sushi in one night
Had an AWESOME TIME

Monday, December 21, 2009

Airline horror

Ya, just flew cross country yesterday. Seattle to Chicago to Hartford. I usually fly Southwest, but I let my mom book my ticket and she booked me a ticket on United.

Anyway, the boarding process was the most unorganized POS I've ever seen. Southwest might get flak for their first come first serve pick your own seating thing they got, but I've never had a problem with it, and it's usually very efficient. United has this thing where there's 4 groups, and people board in order by their group, to assigned seats. Only problem is, there's no line! It's just a mob, and people with higher numbers sit in the mob too crowding up the place. It took forever to board people.

Also the seats are more cramped than the other planes I've flown. I'm 6'5'', so I never fit in any of the seats anyway, but this one was especially bad and I couldn't even move my legs out of the way to grab my laptop from under the seat, and it barely fit under the seat in the first place.

None of this is THAT bad really, except my luggage is in chicago right now (it might be on its way here I hope). Not only is just my luggage in Chicago, but the ENTIRE FLIGHT'S luggage is in Chicago. The ENTIRE FUCKING FLIGHT. Nobody got their bags. It took them a half hour to even start the baggage claim, then a half hour for it all to go around while nobody grabbed their bags since they were the wrong ones. It got jammed even, and they had to offload the bags to a waiting area. And nobody's bags came. They couldn't have told us that our bags didn't make it on the plane? I can see them missing one or two, accidents happen, but for gods sake if you miss the whole flight at least have the common decency to tell people that and not wait for an hour hoping your bag shows up.

To exasperate matters, everyone had to wait for an hour in a line after that to file the claim, as there was only one desk open for lost bag claims, and 200 people missing bags. Bags which they charged us $15 to check in the first place. At least we'll get refunded that money, but we have to go online and file for a refund. If you lose an entire flight's worth of luggage, you ought to refund the bag check fee automatically.

Damn it United, worst flying experience I had all year, out of the 9 or so flights I've taken this year. Merry Christmas.

Friday, October 16, 2009

Target Audience: Animals!

A concept recently struck me, has anyone actually made a video game whose target audience isn’t humans, but animals (or a specific kind of animal)? Of course, there are some challenges with designing a game for a non-human audience. Anyway I’m going to pick cats to target for this concept, because of the way they play with laser pointers. I haven’t actually made this because I don’t have the money, space, resources, or cats to properly test (my cats live with my parents, 3000 miles away).

Anyway the simplest setup I can think of for getting this to work requires a projector, a wall, and a camera. The camera and projector are going to be at the same spot, and the camera is going to be used to detect the cat’s motion. The simplest game I can think of for this involves a red dot moving around, avoiding the cat, and the game awards the cat a “point” every time the cat “catches” the red dot.

What is going to make the cat care about it’s score though? I know it naturally enjoys chasing red dots, but this is more important when the game gets a little more complex than this; the cat needs to know when it’s doing something right, and the rewards need to be immediate, not delayed. So, I guess have a machine that dispenses kibbles of food when the cat gets a point.

If this works, it’d be interesting to see how much more complicated you could make the game before the cat gets overwhelmed. The next step, I’d say, would be a variation on “Duck Hunt”. Have the birds fly across the screen, if the cat hits a bird, the bird “dies” and the cat gets a point. I’ve seen videos of cat’s hitting birds on a screen online, but has anyone actually made that interactive?

What about Doom? The cat wouldn’t be able to control the camera very easily (although the game could pan left and right if the cat moves to the left or right, but the cat probably wouldn’t be able to understand that). Turn it into an on rails shooter, and have the monsters die when the cat hits them. Simple, would probably be very amusing to watch and very amusing for the cat.

One last idea: Guitar Hero. There’s no way you’d get the cat to strap on a plastic guitar, but what about just hitting the notes on the wall to a rhythm? You’d probably have to remove a lot of the additional distractions on the screen, and I wonder if the cat could understand when its supposed to hit the dots to get its points. At the very least, it’d be an interesting experiment.

Oh ya and then there’s marketability. I don’t have any ideas on that one, would anyone care that much about their cats to buy them an expensive toy when a $2 laser pointer works just as well? Oh wait, some people DO do that. It’s a niche market I guess, although “Cat Plays Doom” is an instant multimillion view movie on youtube.

Friday, October 9, 2009

The Plot of my Next Game

In the year 30N, a child was born. His parents were hiding from the Institution, aliens who rule over the galaxy with an iron fist. Shortly after being born, their hiding place was discovered. The kid was teleported to the nearest moon base, and holographically disguised as one of the Institutionalized (colloquially abbreviated as the Ized). He was raised by them to be a fighter, not knowing the details of his human past, but programmed to learn at age 30.

One day at age 30 he was going about his normal alien business when the holograph was deactivated, and he suddenly looked like a human pig. Knowing he would be killed if he was seen by the ized, he ran into hiding trying to figure out what was going on, when a video chip implanted in his brain suddenly explained everything to him. HE KNEW WHAT HAD TO BE DONE. He needed to avenge his fallen parents. Luckily there was a gun shop nearby. He wanted the awesomater, which shot laser bullets made of explosions, but he had no money so he was given the squeaker instead, which shot airsoft pellets. It was enough to protect him until he could afford a cooler gun, or upgrade his current gun.

The first thing he needs to do is clear: get a better gun. So he decides to rob a bank, which involves a lot of stealth since he can't hurt people yet. It's an easy mission, the kung-fu training he was given as a child helped him find the safe. With a new supply of money he could finally afford a good gun that could make aliens bleed and die, and could always make money by robbing the corpses of the aliens he killed so he can upgrade and make more awesome the guns he has, or even get the awesomater.

He realized he needed some defense, so he had to go get some space armor. The only armor shop in the galaxy was in a different space system though, so he had to find his way to the nearest wormhole generator instead. It was heavily guarded by ized troops, so he had to go shooting and kung fu on them to clear a path, before entering the wormhole (when an awesome cutscene plays). He gets the armor and is now ready to infiltrate the main ized base in the garkoblurger system. Along the way he meets a sexy alien chick named Bragana with 3 giant boobs, and they fall in love and fight together for a rest of the game.

He enters the base and starts shooting, guns ablaze. Flashbacks of his mysterious childhood play as hes shooting the evil aliens. Was this right? He is faced with a tough moral decision, but decides to keep killing to avenge his real parents.

Finally he reaches the control room. But what a twist! The chief ized leader is... the ALIEN WHO RAISED HIM AS A CHILD! He says "We may have killed your real parents... but I RAISED YOU. I may not be your real father, but I acted as a father to you. Surely that means something to you?" He replies "But but... you killed them!". He is faced with a moral dilemma, before deciding to kill him. He shoots and an awesome final boss battle begins. When the alien is dead, he hits the self destruct button and he needs to escape the galaxy before it implodes in on itself. On the way out, Bragana slips and falls down. Our hero catches her, but she says it's too late for her and falls into a pit and dies. He screams "NOOOOO" but continues escaping. He gets to a spaceship, and flies it away. As he watches the galaxy implode, a single tear streams down his eye, and the credits roll.