Life and code.
RSS icon Email icon Home icon
  • Tim Sweeney’s Slides on the Next Programming Language

    Posted on February 2nd, 2006 Brian No comments

    As might be guessed from my rambling on some of UnrealScript’s domain-specific features, I’m a huge fan of Tim Sweeney. His thoughts on practical language design speak to me more directly than any other thinker in that arena, and he is far better known as a 3D game designer than as a Lambda-academic.

    His insights stem from real-world issues faced by developers who have licensed his Unreal Engine, and a large percentage of those problems involve developer productivity. His solutions often take the form of specialized languages designed to provide first-class support for concepts necessary but difficult for game programmers to get right, but which most main-stream languages lack. Things like state modelling and transition, concurrency, networking, and timing are given representations in the language and support in the runtime, allowing for developers to work at a higher level and with fewer defects.

    Lambda the Ultimate, a language-geek blog, linked to a presentation given by Tim entitled The Next Mainstream Programming Languages: A Game Developer’s Perspective. (A commentor also found a link to a PDF version of his slides, for those of us averse to downloading random PPTs.)

    I am very enamoured with his idea of framework extension (slide 26). I think this is the next major route towards true software framework re-use. Instead of being limited to the arbitrary points of extension and aggregation pre-defined by a particular library’s designer, so-called horizontal inheritence would allow us to re-define how the basic framework functions without needing to mess with the source code.

    My favorite quote, from slide 38:

    Factoid: C# exposes more than 10 integer-like data types, none of which are those defined by (Pythagoras, 500BC). In the future, can we get integers right?

    I’ve written a bit of UnrealScript for the Unreal Tournament 2004 Explosive Ammo Mutator, and it’s a very cool experience; I think it indicates what is to come for the rest of us. Near the end of Part 4 of What Does “Web Paradigm” Mean, Anyway?, I state that true web integration requires new platforms:

    We need a platform, independent of any particular application, that makes obtaining, parsing, transforming, aggregating, and forwarding XML as natural as displaying a window. Web integration needs to be a first-class citizen.

    It is web-specific languages on web-specific platforms that will make this possible. While they will be tailored and tuned for web-enabled tasks instead of video games, we can still catch a glimpse of their form if we look at UnrealScript and Unreal.

  • New Explosive Ammo Version

    Posted on May 31st, 2004 Brian No comments

    I’ve put together a new version of the Unreal Tournament 2004 Explosive Ammo Mutator. This new version fixes the single-player special effects that were broken when I made the network special effects work. This is version 1.3, and hopefully the last.

  • UnrealScript and Domain-Specific Languages

    Posted on April 11th, 2004 Brian No comments

    UnrealScript is really cool. I’ve been working on my Explosive Ammo Mutator for UT 2004, so I’ve gotten a pretty good crash course in Epic‘s scripting language. (On a humorous side note, check out http://epicgames.com.)

    First, let me preface by saying that I had experience with an older version of UnrealScript. Back in college, we hacked up the bots in the original Unreal Tournament for an Artifical Intelligence class. We implemented a learning algorithm, and it worked relatively well. Except the bot sucked. We couldn’t get it to do what we wanted because its own code was too complex. But it really did learn. Honest! Anyway, the point is that I had sorta forgotten how cool UnrealScript is.

    You see, Epic didn’t just make a game. They built an entire robust, portable gaming engine, simulator, and toolset. The Unreal engine actually has a built-in virtual machine that runs compiled bytecode, a technique identical to that used by Java and .NET. For those of you out there who aren’t geeks, this lets the game run on a mulitude of platforms, from the XBox to the PS2 to my PC, with very little binary changes. UnrealScript is the language that is compiled into that bytecode, and it is no ordinary language.

    UnrealScript has a C-like syntax, making the code pretty easy to read for Java or C# developers. However, it is completely object oriented. There are no global functions, and every object extends from the base Object class. In the version I used in college, there were no static methods; although that feature has been added since the old days. But the cool thing about UnrealScript is that it is a domain specific language. That means that it has language features specifically designed to make programming a video game easier. UnrealScript supports several features of note, such as time, properties, and networking; but my favorite is its language-level support for states.

    In most game programming, much of the game world is modelled as a state machine. Different types of objects have various states that they might be in, and they respond to stimuli differently depending on that state. Often, this type of thing is modelled using a switch/case statement or the ilk. In UnrealScript, states are first-class langauge features. Take a look at this code snippet from the ExplosiveRocketAmmoPickup class from my exploding ammo mutator. (I’ve left out some of the nitty-gritty for clarity.)

    function TakeDamage()
    {
    	GotoState('Exploding');
    }
    
    state Exploding
    {
       function TakeDamage() {}
    
    Begin:
       DoExplosion();
       SetRespawn();   
    }

    I have declared a function called TakeDamage() that will be called by something whenever my ammo pickup gets hurt in some way, either by somebody shooting it or an explosion going off nearby. It is declared at the global scope level; when it runs, it tells my object to transition to the Exploding state. Just below is the declaration of that state. In the Exploding state, I redifine TakeDamage() to do nothing at all. The semantics are that, whenever the pickup is in the Exploding state, the TakeDamage() defined within that state is called; otherwise the global version is called. For my object, this means that once an object is exploding, it won’t be able to take more damage and somehow explode again. That makes sense, right? (Actually, it’s even easier than that. UnrealScript allows you to write ignores TakeDamage; instead of declaring an empty function.) When my state is entered, it runs the code following the Begin label, which causes the object to explode and then respawn.

    Pretty cool, huh? In this way, you can build up complex state machines using a simple syntax. But it gets better. Much like you can inherit methods and fields from parent classes, you can inherit states from parent classes. In the example above, the SetRespawn() method actually causes my object to transition to a Sleeping state defined in the parent class.

    But what if I wanted to modify the states of a parent object? No problem. In the next example, again taken from my mutator, I had to extend the projectile class used to model mines for the Onslaught game type. The mines in Onslaught are special in that they sit around and wait for an enemy to walk by, and then they chase him until they catch him and blow up his ankles. The problem, of course, being that they don’t blow up until they are triggered by a player. So our ammo box would blow up, and then all these mines would potentially sit around on the ground forever.

    state OnGround
    {
       function BeginState()
       {
          if (!self.deathTimeSet)
          {
             self.deathTime = self.Level.TimeSeconds + RandRange(1.0, 7.0);
             self.deathTimeSet = true;
          }
          
          super.BeginState();
       }
    
       function Timer()
       {
          if (self.Level.TimeSeconds >= self.deathTime)
          {
             self.BlowUp(self.Location);
          }
          else
          {
             super.Timer();
          }
       }
    }

    The OnGround state is defined in the parent class, and represents when a mine is sitting on the ground waiting for somebody to pass by. I’ve overriden it here, along with two functions within it. The BeginState() method gets called whenever the state begins, that is, whenver the mine has landed on the ground. I set a random point in time in the future at which the mine will explode, and then I call the superclass’s implementation. The Timer() method gets called whenever a pre-set timer goes off. In this case, the base class sets this timer to check if anybody is nearby so that the mine can go scurrying after them. I’ve overriden it to first check whether the mine has expired and explode it if it has. If it hasn’t, I merely call the superclass’s Timer() method so that the mines will go scurrying along appropriately.

    The cool thing of this being, of course, that this code only gets called when the OnGround state is active. I can muck with just a single portion of the state machine without having to touch anything else. It’s a sort-of double-virtual dispatch for methods. You can also inherit states from other states declared in your class, but I’m not going to go into that right now.

    The net result of all of this, besides the cool features, is that domain-specific languages can be an amazingly powerful tool for writing complex systems. If you create a language in which to more efficiently express a solution, then expressing those solutions becomes much easier. All too often, modern software engineers suffer from Hammer Syndrome. The huge popularity of Java, and more recently C#, in the mainstream often blinds us to the potential of a different language. An altered paradigm can dramatically reduce the difficulty of coding a working solution. Lisp is often dismissed as an academic language, or people are frightened by the large number of parenthesis. ECMAScript is virtually always relegated to web browser scripting; or worse, it is thought to be synonymous with the DOM. Different languages allow you to express your existing thoughts in a different way, and they often lead you to completely new thoughts. If you only know one language, you really need to learn another one or five.

  • UT2004 Explosive Ammo Mutator

    Posted on April 10th, 2004 Brian No comments

    My current gaming addiction is Unreal Tournament 2004. I just cannot get enough of this game. Of the ten different game modes, Onslaught really takes the cake with its sweet maps, vehicles, and teamwork requirements. Plus, there is built-in voice chatting that is quite good, and you can command the bots using speech-to-text. How cool is that?!

    But there was something missing. Back in the old days of the original UT, a bonus pack was released with a mutator that made all of the ammo packs explode when you shot them. Chris and I both really liked this mutator, and we couldn’t find one that was up-to-date for UT2004. So we wrote our own. The mutator is still pretty new, so please let me know if you find any bugs or problems. Also, please let me know if you have any gameplace tweaks you would like to see. All of the ammo types are implemented, including the Onslaught AVRil, mine, and grenade. The notable exception is the lightning gun, because doing lightning is fucking hard and I haven’t figured it all out yet. :-(

    I’ll be putting up a dedicated page for it later, but for now you can download the beta version of my Unreal Tournament 2004 Explosive Ammo Mutator here. If you unzip it into your UT2004/System directory, it should show up in the list of mutators as MutexplosiveAmmo. (I don’t have the .INT file working quite right yet.) If it doesn’t show up for some reason, you can always start a map using the command open <your-map-name>?mutator=explosiveammo.mutexplosiveammo.