Showing posts with label causality. Show all posts
Showing posts with label causality. Show all posts

Monday, November 17, 2008

Ignorance Is Bliss

Having written twice about the dangers of believing everything you are told, I'd like to give some face time to the opposing argument:

Ignorance is bliss.

It's all well and good to say, "You should understand things, not just follow blindly." But to be pragmatic, there is only one time this is a serious improvement: when the blind belief is wrong. What about the times that blind belief is right? Humans survived for centuries without understanding how gravity truly worked and that didn't stop them from creating some awesome things. They were even able to use the fact that "things fall towards the ground" to great effect, such as building water clocks, without ever learning Kepler's laws of motion.

Even if someone did want to totally understand the world today, it wouldn't be possible. There is such a vast corpus of information that learning even 1% of it is literally impossible in the span of a human life. Mathematicians who are experts in their field rarely have the chance to keep up on other branches of mathematics, to say nothing of physics, chemistry, or medicine.

The fact of the matter is that most of the information we've been told is correct. If I get a bus that says "Downtown" as its destination, it really is going there. The driver could take it anywhere but I'm very certain that the destination is downtown. When I order a meal at a restaurant, I take it for granted that the cook can actually make the things on the menu and that I'll be served food that's reasonable close to the description provided. The waitress serves me food assuming that I will pay the price listed. I suspect that less than 1 in 10,000 people really understands what a computer does when you turn it on, but hundreds of millions of people use a computer every day. Understanding is a luxury, not a necessity.

Like it or not, our lives as humans are anchored in faith, not reason and understanding, and this is the cornerstone of the religion well all share: Causality. If we do something ten times in a row and got the same result, we expect that the eleventh time will produce the same result. And it does, even though we rarely know why. Understanding everything is impossible, and the whole purpose of culture is to provide structure so that everyone can use the discoveries other people made.

If that's the case, why bother thinking about anything at all? Why not let someone else do your thinking for you? The primary purpose of education isn't to give people information, but to teach them how to think. And most importantly, to teach them when to think. Thinking is really important in uncharted waters. In any situation that doesn't match your typical life experience, thinking will give you a much better idea of what to do than trying something at random.

Unsurprisingly, the same problem comes up in artificial intelligence. There's only so much processor time to go around. So if seven bots all need the same piece of information and they will all come to roughly the same conclusion, it's much faster to do a rough computation once and let them all use those results. This leads to an information dichotomy, where there's general "AI Information" and "Bot specific information". Each bot has its own specific information, but shares from the same pool of general information. In BrainWorks, all bots share things like physics predictions and the basic estimation of an item's value. If a player has jumped off a ledge, there's no reason for every bot to figure out when that player will hit the bottom. It's much faster to work it out once (the first time a bot needs to know) and if another bot needs to know, it can share the result.

These are the kinds of optimizations that can create massive speed improvements, making an otherwise difficult computation fast. If you think about it, it's not that different from one person researching the effects of some new medicine and then sharing the results with the entire world.

Monday, May 12, 2008

The Emperor's New God

Last week, I ended by explaining how I came to realize I didn't have a relationship with God. In short, I empirically tested whether or not God was speaking his words into my mind and I concluded that at least some of the time, things that "felt" like they were from God were not. Specific things I thought God had promised me didn't happen, so that must not have been from God. Moreover, even simple thoughts that were no more specific than a horoscope were also no more accurate. In short, I realized I had no evidence to conclude I had ever communicated with a higher power. And lacking a relationship with God, I realized I was not a Christian.

That is not the same thing as giving up my faith.

Indeed, for a few months I desperately wanted "back in". There is a categorical difference between not having a relationship with God and being unable to have that relationship. Even to this day, if it turns out God exists, then I really want a relationship with that God. Who wouldn't want to be friends with the creator of the universe?

So having lost the evidence supporting my religious faith, I started from first principles, to see if the tenets of Christianity logically made sense. In other words, I wanted to logically test whether Christianity was truth but modern Christians had pursued the faith in the wrong manner, or if the religion just didn't make sense and I should give up on it altogether.

For those of you who aren't that familiar with Christianity, here is the core doctrine:
God loves people, but God is perfect and righteous, and therefore cannot allow sin to exist in his presence. Because all humans are innately sinful and God loves them in spite of this, God devised a plan that would allow him to have a close relationship with humans on an individual level. God sent Jesus, who is himself fully God and fully human, to live a perfect, sinless life and then become a penitence sacrifice for all of humanity. Jesus suffered the penalty of death instead of me so that I could live and have a relationship with God. And Jesus.
When I broke the dogma down to this description, there were three potential logical issues that I spotted. If any one of these things is false, the religion doesn't make logical sense. Here are the issues:
  • Why can't God let sin exist in his presence?
  • Why is the penalty for sin death?
  • Why is someone else dieing for my sin considered justice?
According to the Bible, Jesus spent a lot of time with prostitutes, drunkards, and other "sinners", expressly because these were the people who needed ministering the most. If Jesus is fully God, why wasn't Jesus bothered being around sin? That sounds like a strong logical contradiction.

I don't have a problem accepting that everyone is a "sinner", meaning that no one lives a perfectly righteous life, never mistreating or hurting other humans, or taking advantage of them. But why is it fair that living unrighteously should be met by death? Jesus himself talks about how some sins are worthy of greater punishments than others, and a spiritual death in hell is clearly the worst punishment someone could earn. By and large, most people never do anything so disruptive to society that death is a just punishment for them. It doesn't make logical sense that all kinds of unrighteousness should be worthy of the same death sentence.

Last, there's the question of why, if I'm guilty and deserving a death, it's fair for someone else to die on my behalf. This kind of thing goes against the basic philosophy of penal systems. If I'm sentenced to serve 10 years in prison, the courts don't consider it fair if someone else chooses to serve 10 years instead, or even 30 years. That option is simply not allowed because it doesn't even relate to the issue at hand. The Bible supports this opinion as well, according to Ezekiel 18:20:
The soul that sins shall die. The son shall not bear the iniquity of the father, neither shall the father bear the iniquity of the son.
Historically there have been some penal systems that allowed, by consent, some people to receive the punishment intended for others. The result has always been that rich people pay poor people to serve sentences for them, and in most cases the systems were changed to disallow this abuse. So if I really am worthy of death for my sins, I don't logically understand why it would be okay for Jesus to die instead of me. That simply doesn't make sense.

I sent this list of questions four Christians whose opinions I respected. All of them were pastors at the time or had been in the past, and two of them had served time as missionaries in the third world as well. Of them, one actually tried to answer the questions. Two said they would think about it and get back to me, which never happened. The last didn't even respond. And all the answers I received boiled down to, "God knows better than you. It makes sense to God and that's what matters."

I'm sorry, but that's not a strong enough argument for me to base my life around a religion. The overall silence spoke louder than words and confirmed what I had suspected all along: the Christian religion is fundamentally flawed. A God might exist, and I certainly hope he does. But he is not the Christian God. A sentient being that could create the beautiful physics behind our universe can create a religion that doesn't have glaring logical holes in the core of its doctrine.

Now all that said, I'm still a big supporter of many Christian ideals as they relate to society. "Love your neighbor as yourself" is a good general rule for life, and creates a society that's better for everyone as a whole. Just because I've given up religion doesn't mean I've given up ethics.

At any rate, thanks for taking the time to hear my story. Next week I promise I'll be back with more AI themed discussion.

Monday, May 5, 2008

The Man Behind the Curtain

Last week I wrote about the Christian philosophy I had. The basic conclusion was that if someone has sufficiently strong reason to believe in a religion, nothing external from that religion can ever make them lose faith. Rather you will see them modify the fringes of their beliefs to fit whatever counter-evidence they encounter, without changing the core beliefs.

For example, a Christian may start claiming that God created the world in seven days. When presented with scientific data demonstrating the world is older than 6000 years, they might claim Satan just planted the dinosaur bones so deceive people into believing God doesn't exist. (Yes, I've heard someone present argument in all seriousness.) The more rational believers can apply Occam's Razor to this situation and conclude that maybe "day" isn't the right translation, and perhaps end at the conclusion that God used evolution to create humans. But no amount of external (scientific) evidence will convince a believer that their religion is wrong. I was familiar with all of those arguments and they didn't make me lose my faith in God. Only an internal inconsistency could fracture my faith.

I moved to California in the middle of 2000, a year and a half before I started work on BrainWorks. I started the project by programming on evenings and weekends, but after almost a year I realized that writing truly good AI would take more time than that. My wife and I talked about the options, and after a lot of time spent in prayer, we came to a rather dangerous conclusion. I decided to quit my day job and work on BrainWorks full time as a way of building my portfolio, live off savings, and then look for a job in the game industry. Even though this was a crazy idea, we felt assured by God in our prayers of four things:
  • God would provide for us
  • God would vindicate this audacious decision to others upon completion
  • I would truly meet God through the work I did
  • I would finish the project before we left the state of California
In the years following, we would return in prayer during difficult times, and also ask for the prayers from others, and we were continually encouraged when we heard these promises repeated, both in our minds and from the words of others.

Concurrently, there were other issues we had lifted up in prayer. Most notably I had back problems for over a decade. Having tried multiple chiropractors, doctors, physical therapists, exercises, and received countless prayer on the issue, I was at a loss. Nothing seemed to work. But I believed in a God that could do real miracles, and healing my back was certainly not the hardest of them. After years of prayer, I kept hearing that God really was going to heal my back, at the proper time, and that receiving healing was about more than just freedom from physical pain. It was about encountering God in a deeper way, which is why the timing mattered and why God didn't just heal me immediately. We felt like God spoke to us that he would give me full healing for my back before we left California. In some sense, our sojourn in California was an opportunity to witness the miraculous works of God, in my work and in my life, and to encounter God.

So what happened? In case there is any doubt about the story's outcome, let me set the record straight. While we did have enough to live while I was unemployed, I did not "encounter God" through the work. I received a job offer in Boston in January of 2007, which my wife and I prayed about and decided I should take. I did not complete BrainWorks before I left California, nor were my back problems healed. In our cross country drive from Los Angeles to Boston, the two of us were faced with a rather uncomfortable situation. Several things we thought we heard from God, including the prayers of others, all agreed with each other, but they were all wrong. That's really not supposed to happen. At the end of that drive, we came to one undeniable conclusion:

We are not very good at hearing from God.

Maybe the reason is that there is no God, or maybe just no Christian God. Or maybe the Christian God exists, and the problem is with us. When we arrived in Boston, we set aside one month for God, each day praying, "God, if you're real, undeniably reveal yourself to us." Since we are very bad at hearing from God, if we are to have a relationship with God, the effort must be his. After one last month, we still experienced nothing. And at that point I came across one truth, written in the Bible, that forever shattered my faith.

If you're not familiar with the Old Testament, one of the most common themes is the warning against idolatry, the worship of false gods through graven images rather than the one, true God, the "I am". The Hebrew scriptures are littered with hundreds of these warnings, but the best story is from 1 Kings 18, where Elijah confronts the prophets if Baal. Here is an excerpt:
Elijah went before the people and said, "How long will you waver between two opinions? If the Lord is God, follow him; but if Baal is God, follow him." But the people said nothing. Then Elijah said to them, "I am the only one of the Lord's prophets left, but Baal has four hundred and fifty prophets. Get two bulls for us. Let them choose one for themselves, and let them cut it into pieces and put it on the wood but not set fire to it. I will prepare the other bull and put it on the wood but not set fire to it. Then you call on the name of your god, and I will call on the name of the Lord. The god who answers by fire—he is God."
Naturally the prophets of the false god Baal have no success, but Elijah has success:
At the time of sacrifice, the prophet Elijah stepped forward and prayed: "O Lord, God of Abraham, Isaac and Israel, let it be known today that you are God in Israel and that I am your servant and have done all these things at your command. Answer me, O Lord, answer me, so these people will know that you, O Lord, are God, and that you are turning their hearts back again." Then the fire of the Lord fell and burned up the sacrifice, the wood, the stones and the soil, and also licked up the water in the trench.
The basic argument is always the same. What separates idols from God was the success rate. You should worship God because God is real and will provide for you. A true God produces results and a false God does not. After all, what purpose does God have if he can't make an impact on you? When I remembered this, I could not escape its conclusion in my life:

God is my idol.

I could not deny the promises that hadn't come to pass, and those promises that had were easily explained by things other than God. At the very least, the Bible I believed in condemned my God as an idol, since it also did not produce results. I had peeked behind the curtain, expecting to see the magnificence of God, and instead encountered a mirror. All this time, I was the man behind the curtain. The things I thought I heard from God in prayers were just my own desires and fears. I am not good at being God.

To continue worshiping this God would be worshiping an idol, something the religion condemns as an obviously pointless and worthless activity, but it was the only God I had ever known. From that point on, I knew I could no longer be a Christian. I realized Christianity did not have practical applications in my life. But that's different from saying Christianity is ideologically false. Next week I'll explain how I concluded the core ideology of Christianity was flawed, and how I went from an outcast of Christianity to living in the freedom of heathenism.

Monday, April 28, 2008

In the Cleft of the Rock

As I mentioned earlier, I was a devout Christian when I started programming BrainWorks, and now that I've finished, I am an agnostic with no particular religious leaning. My work in artificial intelligence was not the only reason I gave up my religious faith, but it is part of the reason. Moreover, it is a story worth telling, and I hope it will help both Christians and non-Christians gain a greater understanding of each other, something that is sorely lacking in this world where rational justification often takes a back seat to dogmatic conclusions.

To understand the process of giving up my faith, however, you must understand the faith I had. Many people who call themselves Christians, perhaps most, don't have much to do with the actual tenets of the religion. To the average Christian, being a Christian means that God and Jesus love you, and Jesus died for your sins so you that when you die, you go to Heaven instead of Hell. In other words, Christianity is a nice feeling in your heart and your insurance policy for when you die. It has little impact on your actual life, except for a general imperative to "do good things", which many Christians ignore, or act as if it only applies to other Christians.

I was never this kind of Christian.

My core belief has always been in causality, and by extension rationality. I have always believed that if something is true, you can trust in its consequences to be true as well. So I believed in the core tenet of Christianity, which is:
Jesus died to pay for my sins and rose from the dead so that I could receive God's spirit and thereby have a loving, personal relationship with the God in this life, and be with God in heaven after I die.
And I believed everything that logically follows if this is true. So yes, I believed that God can and does do miracles, even in this day and age. Real miracles too, not "I saw the face of Jesus in my pop tart". Stuff like "I was born blind and now I can see". I believed that people can and did hear from God, and that if you pray to God, he hears you as well.

Note that this is fundamentally different from saying that the Bible is the 100% true, infallible word of God. There are some clear logical inconsistencies, and I just wrote that off as "I guess they didn't hear correctly from God about that part", or "someone corrupted this text for their own purposes". The most glaring example is the book of Daniel, which purports to be written during the Babylonian captivity. However, the book contains words whose linguistic roots trace back to Persian empire, a culture the Israelites didn't encounter until well after Daniel died.

There were also some religious statements that don't logically make sense. The traditional explanation for these things, such as "don't eat pork", is that they apply to older cultures for some reason but don't apply to the culture of today. However, I took the stance that maybe people just didn't hear correctly from God and the Bible's authors recorded the wrong thing.

For example, even as a Christian I did not think homosexuality was immoral. There is no logical reason that consenting sex between people of the same gender would be wrong but between opposite genders would be okay. "God hates it for some reason" isn't a good argument. According to the book of Jeremiah (Jeremiah 7:19), things that are wrong because they are detrimental to humans. There is certainly nothing humans can do to injure God! Our actions can only harm humans, so if an action does not hurt anyone, it cannot be immoral. Consensual sex falls into this category regardless of gender.

So as a Christian I had no problem admitting that the Bible flawed and even wrong about some things. I disagreed with some very popular Christian opinions, and not just regarding homosexuality. But I still considered myself a Christian, because you can still believe the Bible is wrong about some things (bacon, homosexuality) and right about other things (Jesus died so God can have a relationship with me). I still believed that I could hear from God, talk to God, and witness the supernatural miracles of God.

But around one year ago everything changed, for two very different reasons. One reason convinced the pragmatist in me and the other convinced the idealist, and the two arguments together made me undeniably admit that I had been very, very wrong for the past 30 years of my life.

Please believe me when I say that I was not looking for a reason to leave my religious faith. As a Christian, I felt totally in love with God. To this day, I have never felt more joy in my life than during a Sunday worship service, singing hymns and praises. Being confronted with the irrefutable reality that I was wrong about God was agonizing and heart wrenching, and met with many tears. For months I felt devastated, and I still wonder if I will ever find something that brings me as much joy. But I had no other choice. I do not worship God; I worship truth, and by extension reality. If the truth is that there is no God, or at least no Christian God, then my only option is to act on that truth.

I am confident that most atheists and agnostics do not have the faintest idea how much safety and security a devout Christian gets from their religion. From the agnostic point of view, it's easy to think of Christians as weak minded for taking so much on faith and so little on reason. If a Christian doesn't change their mind when presented with solid reason, the conclusion seems natural. But it's difficult to comprehend the amount of mental and emotional security that even a religion brings, even a false one. The sheer fear of being wrong is enough to make most religious people flat out ignore solid arguments to the contrary.

I'm glad I took the red pill, but the blue pill would undoubtedly have been less painful. It is my hope that godless people would have compassion on those who still have religion, and understand that even though many may fear they are wrong, they lack the emotional strength to take the large steps that seem easy for us.

Monday, April 14, 2008

BrainWorks 1.0.1 Released

I've just released the latest update to BrainWorks implementing the fixes I talked about a few weeks ago. Basically there's a much more sophisticated algorithm for tracking and estimating how likely a bot is to shoot a weapon in a given situation. You can download them using the links on the right if you're interested in trying it out. Let me know what you think!

Related to this, I've been thinking about the question of when software is done. In some sense I still stand by my answer in The Attitude of the Knife, which is "when you say it is". The flip side is that as long as you still have ideas and commitment, there's always room for continual improvement. For a simple program meant to meet a specific purpose, such as reading your email, there comes a point where there isn't much more room for feature development. Artificial intelligence isn't like that though. To this day, researchers are still trying to figure out how different areas of the human brain work. And contrary to popular opinion, humans are not the end of evolution. The human brain itself continues to refine and advance itself through generations.

I believe the line dividing things that can be finished and things that cannot is the line of self reference. When the problem is best solved by something that can analyze and correct its own mistakes, a whole new field of issues apply. For an in depth explanation of why this is, I highly recommend the second of three books that influenced my mental framework for understanding the world. That book is Godel, Escher, Bach: The Eternal Golden Braid, and it is about the nature of intelligence. Very roughly paraphrased, the book talks about the mathematical theorem known as Godel's Incompleteness Theorem, which says that any system capable of describing itself can describe statements that are true but unprovable. Originally the theorem was discovered in attempts to work out some issues in Principia Mathematica, an attempt to derive all mathematical truths from first principles. However, the incompleteness theorem sheds unanticipated insights on the areas of philosophy and by extension the nature of thought and intelligence.

Viewed in the context of intelligence, you could conclude that there are things which an intelligent person would do, but there is no describable algorithm that could conclude what those things are. Perhaps this represents acts of creativity, intuition and insight. Or perhaps those things are describable, but other things are not.

Applied to Artificial Intelligence, it means that there are some aspects of AI that we cannot solve; we can only approximate. And there's always room for better approximations. This is the real that AI development can last forever. You're never really done. At least not until you say you are.

Monday, March 17, 2008

Release Retrospective

While people have been overall pleased and impressed with the BrainWorks release, I've received one common bit of negative feedback. Many people have said the bots use the shotgun too often, especially in situations where it's flat out the wrong weapon to use. Now I don't have the luxury other people have of saying, "that's not a bug, that's a feature!" Or more commonly, "that's working as intended." BrainWorks is intended to feel realistic. If many people say a portion of it doesn't feel realistic, they are right. I have no grounds on which to disagree. There really is a bug in the code because you say there is.

Of course, if you've ever been told quite literally, "this thing doesn't feel right, so go fix it," you know how challenging of a request that is. One downside of fundamentally basing the BrainWorks AI on causality is that debugging is extremely difficult. There's no magic number that tells the bot how often to use the shotgun. Instead, the bot analyzes its situation and incorrectly decides the shotgun is the right weapon to use. To solve this problem, I need to walk through the entire analysis and see how it reaches that conclusion. To make matters worse, the bots don't always choose to use the shotgun. And there are surely situations where the bot correctly chooses the shotgun. It's very hard to isolate the situations where the mistake as made and then narrow down why that mistake occurred.

My solution was to write some debug code that outputted all the data the bot used at each step of weapon selection analysis, starting from accuracy and fire rate data and ending with its final valuation of how quickly a given weapon would score a kill. I had it output this data for all weapons available and just stared at the numbers, checking if each data point was an accurate value of the concept representing it. I found three key contributing issues, two of which are solvable.

#1) The estimation of weapon fire rate was incorrectly bounded

Knowing how frequently the bot will fire a weapon is crucial to determining the actual damage rate of the weapon. If a bot spends 3 seconds aiming at a target and only fires for 1 of those seconds, it will do one third the damage as a bot that spends all 3 seconds aiming-- provided it's always lined up for a good shot. The bot tracks how often it actually fires the weapon, but I gave this value a lower bound of 50%. In other words, the bot assumes it will spend at least 50% of its time firing with the weapon, possibly more.

I added this assumption to deal with another problem. Bots would switch to a weapon they had never fired before, not have a perfectly lined up shot, and think... "I've spent 0 seconds firing and 100 milliseconds aiming, so I spend 0% of my time attacking. This weapon is terrible. I'm going to use something else." And they would never try out the weapon to see that they could in fact make shots with it. One problem with relying on historical data is wide variance in the initial data sets. I ran some tests with most of the weapons and found the fire rates were in the 60% to 80% range, so 50% seemed like a good bound.

The problem was that the shotgun only had a fire rate of between 30% and 50%, meaning it's hard to line up good shots with the weapon. There were situations where the bot would think it fired 50% of the time when in reality it had only attacked 30% of the time, which inflated the estimated value of the shotgun by a solid 60%. (160% of 30 is 50.) So it's no wonder they thought the weapon was good. Lowering the minimum bound to 30% had other problems though. When that happened, sometimes bots would stop using genuinely good weapons like the rocket launcher. That's a sign that a lower bound is not the correct way to solve this problem.

Related to this is the second issue:

#2) The estimation of weapon fire rate doesn't take location into account

If you're wondering why the shotgun is generally a bad weapon, it's because it's so situational. At point blank range, it can do more damage than the railgun in two thirds the time. But the spread on the weapon makes its value decrease rapidly at medium and long range. There are situations where the shotgun is good, but not many of them. In contrast, weapons like the railgun are consistently good in a wider variety of situations.

This means that a bot might shoot more often with the shotgun at point blank range than at long range because the shots are easier to line up. If the bot had a 40% fire rate with the shotgun, that might be a 50% rate when close to the enemy but only 30% when far away. Similarly, it's easy to line up shots with the rocket launcher when the target is below you, since you can just shoot at the floor. If the target is above you, you need a direct hit, and that's very hard.

If the bot knew how the firing rate could change depending on the combat situation, it would have a much better understanding of whether a weapon is a good choice against the current target. Unfortunately, the code only tracks a single firing rate for each weapon. The concept of where the enemy was located doesn't factor into the data, and that's a real issue.

The drawback of tracking fire rate data across each of the bot's 12 combat zones is that it will take much longer to get good estimates on actual fire rates. If there were problems before with bots accumulating fire rate data into one data "bucket", now that there are 12 "buckets", it will take 12 times longer before the data stabilizes. In other words, the issue that the 50% minimum fire rate was trying to address has now gotten 12 times worse.

I'm still thinking about the best way to solve this problem, but I'm leaning towards seeding the data with some reasonable estimates of how often the weapons really should be firing. If there's enough seed data, it should encourage the bot to act reasonably until it has enough of it's own data to make conclusions. That just leaves one more issue:

#3) Bots do not take into account how a good choice now could be bad later

The major drawback a situational weapon like the shotgun has is that when you use it, you give your opponent some control. They have the power to make your weapon worse just by backing up. While this is a concern for all weapons, the more situational a weapon is, the worse it is when your opponent exploits your weapon's weakness. In other words, the shotgun isn't just bad because it's only useful at close range. It's bad because your opponent can choose to be at medium or far range after you spend the time to pull out the weapon.

This is unfortunately a much harder problem to solve, since it has to do with the local level geometry. If your opponent has no escape routes, the shotgun is still excellent in close quarters. I haven't thought about this problem very much, but my intuition says that solving it in BrainWorks is well beyond the scope of the project. You might be able to analyze past reactions opponents had to your weapon choices, but it's not clear how good this data would be, how it would affect the bot's choices, and if this problem is even large enough that it needs such a sophisticated solution.

At any rate, I apologize if this post is a bit more technical than normal, but that's the nature of the work. I'm very interested to hear your ideas for how to tackle these problems. I plan on thinking through possible solutions over this upcoming week and writing the fixes next weekend. If you have thoughts on this, I'd love to hear them.

Monday, February 25, 2008

At the Heart of it All

As I outlined last week, the item pickup problem in First Person Shooter games is very difficult to solve, and that goes for humans as well. How do the truly advanced players approach this problem? At the heart of it all is one central question:

How will this benefit me?

If you want to know whether to pickup item A or B, you first must know how much item A benefits you, and how much it costs (in additional time to get the item). BrainWorks solves this problem using a customized resource prediction model, handled by ai_resource.c. Be warned, this code is not for the feign of heart. It's gratuitously well commented and documented, but there are so many bits and pieces it's very hard to get your head around everything at once. Think of it like opening the hood of your car, removing the engine block, and taking everything down to the nuts and bolts. Very interesting, but good luck assembling it into a working vehicle.

First, the AI's resource engine must encode the player's current state. This is handled by the resource_state_t structure (defined in ai_main.h). In brief, that information is:
  • Health
  • Armor
  • Weapons
  • Ammo per weapon
  • Powerups (eg. Haste, Quad Damage)
  • Activatable items (eg. Portable Teleporter)
It's easy to predict the results of picking up a specific item. If you want to imagine what happens when the bot grabs a rocket launcher, you'd just change the player state to have a rocket launcher and some rockets for ammo.

Determining how many points a given resource state is worth is significantly more complicated. Why is that? What other information does the bot need to estimate the points it would gain if it had this set of items? In short, it needs information about possible encounters with enemies:
  • Chance of encountering an enemy near the bot
  • How much damage the bot will deal with each weapon
  • How much damage is required to score a kill
  • How much damage an attacking enemy will deal to the bot
Once the bot has this information, it can estimate the points gained for any duration of time. The encounter rate can (and does) change based on where the bot is, of course. There will be higher traffic near popular items. As a result, the bot needs to remember when it does and doesn't see other players in different regions of the level. This is actually a complicated enough problem that I'll do a full post explaining how it works another day. For now, assume the bot magically knows how likely it is to find an enemy.

The three damage values should be independent of any changes to the resource states. The amount of damage a weapon deals depends on the bot's accuracy-- getting more ammo will let the bot deal that damage longer, but it won't ever make one weapon deal more damage per second than another. As a result, the bot sorts every possible weapon it could use in a priority list at the very start of prediction. The list might read something like, "Use the plasma gun until out of ammo, then the rocket launcher, then the shotgun, then ..." Now that might not be what the bot actually does when it gets in combat, but it uses this as a rough estimate of what might happen.

Naturally the estimated damage each weapon will deal is computed from the bot's historical data of previous weapon use. If in the past the bot had 30% machinegun accuracy and fired 90% of the time the machinegun was loaded, the machinegun's effective damage rate is 27% of it's maximum possible damage rate.

So when the bot needs to predict 20 seconds of time, it might say, "Well I'll get this many points from firing my rocket launcher for 8 seconds, until it's out of ammo. Then the next weapon is a railgun, which I shoot for the remaining 12 seconds and get this many extra points." There would be 2 distinct calculations in that situation. The code uses a similar system for powerups wearing off. In that example, if the bot had a quad damage that wore off after 15 seconds, it would break the time into three segments (0 to 8, 8 to 15, 15 to 20).

Of course this is all well and good if the bot survives, but what happens if the bot predicts its own death? Surely there must be a penalty if the bot needs health but considers options other than getting it. When the bot thinks its health will reach zero, the resource prediction engine stops giving points, and the bot takes a (1 / opponents) point penalty, since getting killed gives one opponent a point.

All that work just to figure out how many points the bot will gain, not even to select the best item for pickup! Next week I'll explain how exactly the item pickup algorithm uses this resource prediction engine to determine the best item to pickup.

Wednesday, February 6, 2008

The Attitude of the Knife

When I was 15, I read one of the three books that shaped my early attitudes, perceptions, and thought process. That book was Frank Herbert's Dune. The book is about an extremely gifted 15 year old who rises to political power because of his talent and training. But he has trouble finding people who relate to him as a person because of how special he is. As another gifted 15 year old, the entire story resonated with me, and many sections of the book left their mark on my memory. My favorite quote isn't the popular "Fear is the mind killer..." quote, however. It's about finishing things:

Arrakis teaches the attitude of the knife--chopping what's off what's incomplete and saying: "Now, it's complete because it's ended here."

The attitude of the knife is an attitude of firm boundaries. It is the decision of royal fiat, the parent's "because I said so". The attitude of the knife is the act of will that sacrifices short term opportunities for long term gain by ensuring that things never grow beyond the size of usefulness.

Once you've embraced the attitude of the knife, you have significantly more peace in life. If you stain your favorite shirt, you might be able to wash the stain out, but you'll be stressed until you know one way or the other. If you accidentally rip that shirt in half, there's nothing you can do-- that's the end of the shirt. Certainly you'd rather have the shirt intact (and unstained) than not, but that's no longer an option. The shirt has met its end and your only option is to throw it out. The attitude of the knife reduces many choices to just one, even if it's not the "best" one. It is the recognition of when a problem is not solvable, at least by you, despite being a real problem.

You might be wondering what this has to do with writing Artificial Intelligence. One of the bigger problems in software development is feature creep, the desire to add "just one more feature" or extend the usefulness of an existing feature. But things can easily grow out of control, beyond the ability of the project's developers. Often the features become so numerous that it's difficult for users to do what they want to do. All the features you don't care about get in the way. (Microsoft Office and Window's Vista, I'm looking at you.)

The attitude of the knife puts an end to feature creep. It says, "Sorry, that problem is out of my jurisdiction. I understand that's a real problem and you have to accept that it will continue to be a problem." Because Artificial Intelligence is so complicated, there's an awful lot of problems and it's very easy for a project to grow out of maintainability. You need to the attitude of the knife to write AI, or you'll never finish.

When I first started BrainWorks, I decided on two strict boundaries. First, every piece of source code has to be run on the game server alone, only running when the server requests AI processing. No changes to non-AI parts of the server were allowed. Second, no modifications to the core game engine were allowed either. The core engine that ships with Quake 3 runs the most complicated AI algorithms, such as navigation, motion prediction, and item pickup. If I found issues in the engine, I was allowed to write my own version but I could not modify the engine, even to fix bugs I found.

As fate would have it, all of the core engine algorithms for AI were dysfunctional. I did end up rewriting most of them-- weapon selection, item pickup, and motion prediction were all rewritten from scratch. But the one unsolvable problem was navigation. The core engine doesn't do a good job of navigating anything but a flat, two dimensional map. What's worse is the core engine doesn't even give the AI code enough map information for the AI to try a better job of making navigation decisions. The problem simply cannot be solved given the constraints of the system.

That's a real problem, but thankfully it wasn't my problem. There were enough other issues to tackle in writing BrainWorks. Many times it was a relief to find a bug that could immediately be ignored. Not because it wasn't a problem, but because nothing could be done about it anyway. And to be honest, most of the time the navigation decisions are actually correct. It only messes up in certain areas of certain levels. On the other hand, the core engine's item pickup and weapon selection decisions were universally wrong.

For those of you curious what two other books formed my life attitude, they are Godel, Escher, Bach: An Eternal Golden Braid and the Christian Bible. While I'm no longer a Christian, I've still taken to heart the positive humanitarian parts of the Bible. And I've not forgotten my promise to explain why I'm no longer a Christian and what part Artificial Intelligence played in that story.

Wednesday, January 2, 2008

Artificial Causality

Previously I said that causality was the foundation for BrainWorks. Since the objective of the AI was to produce bots that seemed human-like, the bots needed to do things humans would do at the same times humans would do them. That "at the same time" restriction is particularly important. A human player will pickup health, armor, weapons, and ammo during a game, and it's not enough to make a bot that also picks up those four kinds of things. If the bot decides to pickup an extra weapon when they are low on health, or armor when they are healthy but low on ammo, then they aren't playing very effectively. It will be obvious to their human opponents that the bots are making mistakes when they die so easily or just don't have weapons to put up a good assault.

When a player picks up health, they do it for a reason: they don't want to die. The proper time is to pickup health is when the player is in danger of dieing. So if a bot is going to do the same things players do at the same times, then:

Bots must do things for the same reasons players do them.

That means making great bots for a first person shooter game comes down to understanding why human players do the things they do. Why do players miss more often against dodging players? Why do players time the respawns of armor but not health or ammo? Why do players choose to fight with a rocket launcher sometimes and a machine gun other times? You have to understand how you play the game before teaching someone else how to play. If only the external details match but not the internal decision process, it's very easy for the bot to appear inhuman, picking up ammo when its low on health and so on.

This intense focus on well understood focus causality automatically disqualify some important AI tools however: genetic algorithms and neural networks. You can think of these things as black boxes with fixed inputs (eg. your location, what enemies are nearby) and outputs (eg. where to aim, whether to shoot). The boxes try things at random and their effectiveness is graded. Then the most successful ones are mixed together and the process repeats. Eventually you get one black box that does a good job of solving a particular problem with well defined inputs and outputs. For many applications, genetic algorithms are great. You can get 90% or better effectiveness without really knowing how the AI works. In practice that means that 9 times the AI does the right thing and 1 time they do something stupid, but it all washes out in the end.

The problem with using genetic algorithms in BrainWorks is that humans notice a flaws much more than correct decisions. As the ultimate objective is bots that feel human, a bot that does ten things 90% well meets that objective. But a bot that does nine things perfectly and one really stupid thing doesn't.

In effect, writing BrainWorks was teaching a computer how I, Ted Vessenes, play first person shooter games. And the teaching required me to learn for myself why I make certain subconscious decisions. In the upcoming posts, I'll dive into a few specific applications. Up next week: Weapon Selection.

Sunday, December 30, 2007

Artificial Intelligence is Hard!

For the past six years, I've been working on a "little programming project" called BrainWorks. It's a full rewrite of the Artificial Intelligence for Quake 3. (Check out the side panel for links to the release and source code.) Before I started in 2002, I had done some work on other game modifications for Quake 3, including one of the first Real Time Strategy / First Person Shooter hybrids, Art of War. I quickly realized good AI was crucial to any team game, and became increasingly unhappy with the level of intelligence in the basic Quake 3 release. And with that, I set out to create a good framework for AI in Quake 3. My original plan was to fix up the code and I estimated a mere 6 months for this work. As I spent more time in the code, however, I realized something crucial:

Artificial Intelligence is hard!

And large portions of the original AI code were architecturally flawed from their foundation. To really do a good job with withe First Person Shooter Artificial Intelligence problem, I would have to start from scratch. Six months turned into six years, much longer than I'd have liked, but the work on BrainWorks has given me insight into a wide variety of issues in both real and artificial intelligence. In this blog I'm posting about the different problems I encountered, how I solved them, and what this says about intelligence. The focus is artificial intelligence, of course, but there will also be discussion about human intelligence and the nature of God and the universe. I started BrainWorks as a devout Christian and as I finished the project, I am now an agnostic. The work on BrainWorks was instrumental in changing my theological perspective, but I'll save that topic for another day. For now, I'll leave you with the one axiomatic belief that influenced everything in this project and defines the way in which I view the world:

There is a cause for everything that occurs.

In other words, I believe in causality. Causality is the foundation of all intelligence, both genuine and artificial.