Showing posts with label Games. Show all posts
Showing posts with label Games. Show all posts

Friday, December 09, 2011

Scripting

So I was recently linked to an article about using scripting languages instead of 'real' languages. tl;dr, he talks about how scripting languages are just as powerful, just as fast, and frequently use a simpler syntax. They also compile separately, and can literally be treated as content, almost like a texture, or a map.

But, he somehow managed to briefly brush past the biggest reason why scripting languages are important to game development. They allow you to code for your game using a far higher level of abstraction! This is especially true for custom scripting languages, created for a specific game, a whole genre of games, or merely for games in general. One of my favorite examples of this is Age of Empires II, a game I spent significant amounts of time building and testing AI scripts for.


Though technically, I preferred it without the expansion. Martyrdom made monks really boring.

The fun thing is just how simple AI scripting is for AOE II. It lets you completely define the personality of the AI player, the style they play in, their priorities, the types of troops that they build, and on and on. Here's a quick snippet of what the language looks like:

(defrule
(strategic-number sn-minimum-town-size == military_townSize_1)
(soldier-count < military_townSize_army_1)
=>
(chat-local-to-self "Lowering town size to level 0.")
(set-strategic-number sn-minimum-town-size military_townSize_0)
(set-strategic-number sn-maximum-town-size military_townSize_0)
)

;Attack Now
;start timer
(defrule
(true)
=>
(chat-local-to-self "Activating attack delay timer.")
(enable-timer military_timer_attack_delay 1)
(disable-self)
)

;acknowledge timer w/ other conditions
(defrule
(strategic-number sn-minimum-town-size == military_townSize_6)
(not(enemy-buildings-in-town))
(timer-triggered military_timer_attack_delay)
=>
(chat-local-to-self "Attacking without town size attack.")
(chat-to-allies "31 Attack an Enemy Now")
(attack-now)
(disable-timer military_timer_attack_delay)
(enable-timer military_timer_attack_delay military_attack_delay_min)
)

As you can see, the syntax is extremely simple, almost LISP-like, but it's set up in a fashion where it's incredibly easy to define rules for the AI to follow. AOE II still uses an AI framework built into the game itself, but it does that to simplify the scripts that people would work with on a more frequent basis. It does mean there are a few things that are impossible for the scripter to change the behavior of, but that's alright in moderation.

Compare the above snippet with this bit from an XNA game that I'm currently working on.

case AIState.Check:
{
 AIFish fish = FindFish();
 if (fish != null)
 {
  target = fish;
  if (fish.size > size)
  {
   state = AIState.Run;
   stateTime = (float)gameTime.TotalGameTime.TotalSeconds + 3 + RandomUtil.CreateFloat(0, 2);

   Vector2 runDir = -(target.position - position);
   runDir.Normalize();

   dest = position + runDir * 400 * size + RandomUtil.CreatePoint(new Rectangle((int)(-200 * size), (int)(-200 * size), (int)(400 * size), (int)(400 * size))); 
  }
  else
  {
   if (RandomUtil.CreateFloat(0, 1) > 0.5f)
   {
    state = AIState.Hunt;
    stateTime = (float)gameTime.TotalGameTime.TotalSeconds + 3 + RandomUtil.CreateFloat(0, 2);
   }
   else
   {
    state = AIState.Wander;
    stateTime = (float)gameTime.TotalGameTime.TotalSeconds + 4 + RandomUtil.CreateFloat(0, 2);
    dest = position + RandomUtil.CreatePoint(new Rectangle((int)(-200 * size), (int)(-200 * size), (int)(400 * size), (int)(400 * size)));
   }
  }
 }
 else
 {
  state = AIState.Wander;
  stateTime = (float)gameTime.TotalGameTime.TotalSeconds + 4 + RandomUtil.CreateFloat(0, 2);
  dest = position + RandomUtil.CreatePoint(new Rectangle((int)(-1000 * size), (int)(-1000 * size), (int)(2000 * size), (int)(2000 * size)));
 }
} break;

Yeah, definitely not my prettiest bit of code, but that seems to be a theme with basic Finite State Machines when I code them. Imagine if I set up a basic framework, and did this in a custom scripting language? Quite possibly, I could reduce this into 3-4 lines of script, and easily swap out for different fish, types of fish, or even fish with different personality. When you have a really simple scripting language with which to express your ideas, then it suddenly becomes far easier to express more complex thoughts!

I think I'm going to leave it at that, there's plenty of other thing that the author of the article left out or glazed over, but I think this was one of the more important bits. Thanks for reading~

Tuesday, March 15, 2011

ImagineCup Spring 2011

I've participated in the last 3 ImagineCup competitions, it's a great competition, and it definitely pushes me to work towards something great on a deadline. This is actually the first time my team has decided to go 2D instead of 3D, so it was a little different for me this time around. This also means I now have a delightfully fantastic framework for making 2D games in the future!


New World Africa was my first IC game, and it took Danny and I to the world finals in Cairo, Egypt.

This is also the first time I didn't just land in the middle of a team, I get to work with a couple members from Team To Be Announced, who won last year's US ImagineCup with Sixth. All of them are delightfully talented, so they're a lot of fun to work with.


Qualia was my second IC game, which honestly was quite a masterpiece... too bad the judges didn't agree.

Another new thing for me, was that I wasn't making my own world editor for once. The nice thing about 2D games is that there's a lot more resources for building worlds in a generic enough format. We used the delightful Tiled editor for making maps, and I couldn't have been happier with it! I'm planning on making it an integral part of my framework, and using it in future projects I have in mind.


Split Reality is the working title for our current game. We'd have changed it by now, but other things are more important.


We went for a pixel art style, which I think is one of the better ideas we had for the project. It really made it easy to fill the screen with stuff and create new art resources quickly. That's another thing I'm going to remember for the future! It's almost like cheating, except it still looks good =D


Yay for cutscenes! We have another one, but it still needs some cleaning up.

I've got a list of things I still need to code for the project... Prefabricated objects for one, Tiled is a nice editor, but it's a horrid environment to be designing game objects inside of. A cleaner event system, I had to hack the current one in before Spring break got started, so it's a fair bit messy. I also want to do a little more with the cutscenes, pathing, loading from file and all that good stuff. I might even bring in an old cutscene editor I made for Zimbie the Zombie, a game I worked on for my first Game Jam.


Everything came together in such a short amount of time, why, oh why did I start with 3D games?


He does the "Master Chief jump", as Nic says. A better prefab system would help with that >.>

We also had a smashing video for the judges. We'll see if it gets us through to the next round. I'm not counting on it, it wasn't quite where we wanted it to be by the deadline... but you never know! If it doesn't, I can take the stuff I've learned so far, and start chowing down on Umbra, which I've been itching to work on for a while.