December 14, 2002
Orc A.I.
How do you shoot a film like Lord of the Rings -- which regularly has scenes of 10,000-Orc armies clashing with an equally massive sprawl of elves, humans and dwarves? Well, you could try to create computer-generated Orcs one by one, and figure out ways to animate them. But as it turns out, that makes the armies seem curiously stiff and scripted.
The solution? Use A.I. A New Zealand programmer for the movie created Massive, a program that gives each Orc a bit of artificial intelligence -- and turns them loose. Each individual Orc tries to kill opponents and stay away from bad situations, much like the A.I. opponents in games like Quake or Half-Life. The result is a scene that has the same level of realistic chaos you'd get if you had 10,000 actual human extras acting it out:
Like real people, agents' body types, clothing and the weather influence their capabilities. Agents aren't robots, though. Each makes subtle responses to its surroundings with fuzzy logic rather than yes-no, on-off decisions. And every agent has thousands of brain nodes, such as their combat node, which has rules for their level of aggression.
When an animator places agents into a simulation, they're released to do what they will. It's not crowd control but anarchy. That's because each agent makes decisions from its point of view. Still, when properly genetically engineered, the right character will always win the fight.
"It's possible to rig fights, but it hasn't been done," [Stephen] Regelous [creator of Massive] said. "In the first test fight we had 1,000 silver guys and 1,000 golden guys. We set off the simulation, and in the distance you could see several guys running for the hills."
It's a neat examplar of what I call the new "military/entertainment complex." It used to be that the military innovated -- and perfected -- the technology that was later used by entertainment (the way, for example, ballistics algorithms and computer circuity developed for warfare were later used for video games). That's frequently reversed now. As Wired noted several issues ago, the best A.I. work now is in video games and movies; they innovate, and the government follows. It's a side-effect of cheapening computer power and the infinite-monkeys rule: If you have a million geeks working on kewl stuff for fun, they're quite often going to develop toys faster and better than even NASA.
Posted by Clive Thompson at December 14, 2002 07:13 PM
| TrackBack
I'm not quite how accurate to say that the "best AI work now is in video games and movies".
I think that, like in graphics, the best looking technology is often in industry, but it isn't necessarily what will give us intelligent machines or computers, just things that appear plausibly realistic.
Mike Kulas, one of the original authors of Descent, told me that when he was in CS grad school studying AI, one of his professors told him that nothing interesting in AI will happen in the professor's lifetime. Obviously, the difference is that for commercial purposes, new just means "new to me" whereas in academia, new really means new, where nobody has done it before.
It's true that the word "best" as applied to A.I. is pretty subjective. After all, there's no single goal of A.I. Some people are working on ontologies and mapping out common-sense knowledge, like Doug Lenat with Cyc. Others are developing content-analysis tools like the Latent Semantic Analysis guys. Some are still slugging away at the original Turing proposition, like the chatbot guys. It's hard to say that one is "better" than the others, true, since each is pursuing quite different goals.
I think that, like in graphics, the best looking technology is often in industry, but it isn't necessarily what will give us intelligent machines or computers, just things that appear plausibly realistic.
I think that, like in graphics, the best looking technology is often in industry, but it isn't necessarily what will give us intelligent machines or computers, just things that appear plausibly realistic.
This code should compile and run just fine, and you should see no changes in how the program works. So why did we do all of that?
This is another function provided for dealing with the heap. After you've created some space in the Heap, it's yours until you let go of it. When your program is done using it, you have to explicitly tell the computer that you don't need it anymore or the computer will save it for your future use (or until your program quits, when it knows you won't be needing the memory anymore). The call to simply tells the computer that you had this space, but you're done and the memory can be freed for use by something else later on.
For this program, it was a bit of overkill. It's a lot of overkill, actually. There's usually no need to store integers in the Heap, unless you're making a whole lot of them. But even in this simpler form, it gives us a little bit more flexibility than we had before, in that we can create and destroy variables as we need, without having to worry about the Stack. It also demonstrates a new variable type, the pointer, which you will use extensively throughout your programming. And it is a pattern that is ubiquitous in Cocoa, so it is a pattern you will need to understand, even though Cocoa makes it much more transparent than it is here.
Earlier I mentioned that variables can live in two different places. We're going to examine these two places one at a time, and we're going to start on the more familiar ground, which is called the Stack. Understanding the stack helps us understand the way programs run, and also helps us understand scope a little better.
Seth Roby graduated in May of 2003 with a double major in English and Computer Science, the Macintosh part of a three-person Macintosh, Linux, and Windows graduating triumvirate.
For this program, it was a bit of overkill. It's a lot of overkill, actually. There's usually no need to store integers in the Heap, unless you're making a whole lot of them. But even in this simpler form, it gives us a little bit more flexibility than we had before, in that we can create and destroy variables as we need, without having to worry about the Stack. It also demonstrates a new variable type, the pointer, which you will use extensively throughout your programming. And it is a pattern that is ubiquitous in Cocoa, so it is a pattern you will need to understand, even though Cocoa makes it much more transparent than it is here.
This is another function provided for dealing with the heap. After you've created some space in the Heap, it's yours until you let go of it. When your program is done using it, you have to explicitly tell the computer that you don't need it anymore or the computer will save it for your future use (or until your program quits, when it knows you won't be needing the memory anymore). The call to simply tells the computer that you had this space, but you're done and the memory can be freed for use by something else later on.
When compared to the Stack, the Heap is a simple thing to understand. All the memory that's left over is "in the Heap" (excepting some special cases and some reserve). There is little structure, but in return for this freedom of movement you must create and destroy any boundaries you need. And it is always possible that the heap might simply not have enough space for you.
This code should compile and run just fine, and you should see no changes in how the program works. So why did we do all of that?
Let's take a moment to reexamine that. What we've done here is create two variables. The first variable is in the Heap, and we're storing data in it. That's the obvious one. But the second variable is a pointer to the first one, and it exists on the Stack. This variable is the one that's really called favoriteNumber, and it's the one we're working with. It is important to remember that there are now two parts to our simple variable, one of which exists in each world. This kind of division is common is C, but omnipresent in Cocoa. When you start making objects, Cocoa makes them all in the Heap because the Stack isn't big enough to hold them. In Cocoa, you deal with objects through pointers everywhere and are actually forbidden from dealing with them directly.