August 04, 2019

Using Prolog for creating text adventures


The Prolog language works different from normal programming languages like Python which makes it hard to for the newbies to get familiar with it. To overcome the issue a small example make sense which is a text adventure similar to the example at https://gist.github.com/JosephLenton/3191695
It's a small prolog program which contains of facts and rules. The facts are used to store the worldstate of the adventure which means, it contains the rooms and the objects in the room. The rules allow the player to take actions in the game, for example he can pick up an object. Basically spoken, Prolog was invented to create text adventure with less effort over normal programming languages like C.
Let us investigate what will happen after the game gets started. The user interacts with the system interactively. He can show the current situation and he can execute an action. If the player likes to take an object but the object is not there an error message gets printed to the screen. What makes the Prolog program different from procedural programming languages is, that no variables but only a fact list is available. It is a long list of information which can become true or false. If the operators (=rules) are executed the facts gets modified, very similar to the STRIPS action language. This formal description allows a solver to bring the system into a goal state. All what the solver has to do is to find the sequence of actions which will modify the facts into a certain direction.
OOP?
Until now, the question remains open if it make sense to use Prolog facts and rules to implement a text adventure. From the perspective of the AI language Prolog it's the prefered choice in doing so, because Prolog was invented around the idea to add and delete facts from a list and apply rules ontop of the knowledge base. The more interesting question is, if it's make sense for the ordinary programmer.
To understand what is maybe wrong with Prolog we have to ask which programming techniques is normally used for game programming. It's called object oriented programming and the idea is to create a simulation with the help of classes which can call each other. The fact storage of Prolog makes object oriented programming obsolete. But is avoiding objects useful for real applications? Let us make a thought experiment. The idea is to program a larger text adventure which contains of 5000 lines of code. Which programming style is the better choice, using prolog facts or using object oriented classes?
Perhaps it make sense to go a step backward. What is the reason why object oriented programming was invented? From a technical perspective there is no need for doing so. In the C language it's possible to store all the variables direct into the memory and get access with a pointer to the memory adress. If the programmer likes to store a new information, he reserves a new memory block at the end, and stores the value to that position. But real programming projects doesn't use this technique, instead it is more convenient to store the information in structs and classes. Not because the program would run faster, but because programming will be much easier.
The main question is, which programming technique is the right choice for creating large scale text adventures: the Prolog style which is based on rules and facts or the object oriented style which is using classes and methods.
If we are asking an expert programming which paradigm he can recommend for realizing a larger project for example a computer game or a desktop application he will recommend in 99% of the cases an object oriented programming language like C++, Java or C#. What he will recommend not is procedural language like C or a AI language like LISP. The reason for this clear voting is, that object oriented programming has become the standard in modern software development. But what is the case of a text adventure? Sure it is possible to use Prolog or Lisp but then it won't become a software project but an AI course at the university. That means, the goal is not to develop a text adventure but to explain the student who the Prolog interpreter works. If the idea is to develop a text adventure with maximum productive, an OOP language like C# or C++ is the better choice.
OOP textadventure
To understand why object oriented programing is the perfect choice for creating a text adventure we have to take a look into a real project. I've selected a template written in Python available under https://github.com/dexbarrett/python-text-adventure. It is working with classes for items, Non player characters and rooms. The idea is to take a class as a template and create subclass which contains all the needed variables. The text adventure will contains hundred of theses classes which are sending messages back and forth. It's the same principle used in normal graphics computer game, but only the rendering engine for painting the information to the screen is missing.
The interesting point is, that in the gaming industry nobody asks if object orientated programming make sense. All which are 99% of the developers are using this style. The only difference is, that programmer A prefers Python, programmer B is a fan of C# and programmer C likes C++ because C++ provides the maximum performance. But all these languages are using OOP. And the gaming industry is right. It is not possible to replace a language like C++ with Prolog. It would result into lower productivity.
mezzano os
Is a small project which is lisp based operating system. The problem is, that no clear advantage over C/C++ is visible. That means, the software looks like a barebone OS written in C code and it didn't even have a webbrowser. That means, it's easy to predict, that a LISP based operating system won't be successful in the future. Mezzano is similar to most Lisp projects a proof of concept but can't be recommended for practical applications. The problem with Lisp and Prolog is, that it doesn't support object oriented programming which makes it hard to program larger libraries in that language. Using existing libraries is the success factor why existing Windows and Linux operating systems are so successful. It allows to program large scale systems which contains of 10 million lines of code. This is not possible with the Lisp ecosystem.
The best example for a failed Lisp project is the Emacs texteditor. From a technical perspective it is well written software project, but Emacs isn't more powerful than other IDE tools for example Visual studio or Eclipse. Let us go back to the initial question. What is the best way to program a text adventure? If the idea is to show how Prolog is working in a practical application, then it's possible to use this language. But if the idea is to not focus on the technology and create a text adventure in a small amount of time, that an object oriented language is the better choice.
Avoid OOP?
Let us make a short thought experiment to investigate the advantages of object oriented programming. The work hypothesis is, that the concept of classes is overestimated and the better idea is to store all the code into a single main class. From a technical perspective the text adventure would run great. The class provides the world state which contains of 300 variables, and it provides all the actions which are round about 150. The methods have access to the variables and no problems are there with inheritance.
The main reason why such programming style isn't used in reality is because the resulting project is hard to maintain. The compiler is not the bottleneck but the programmer who should write the code. He will get confused after a short amount of time, because it's unclear which methods are allowed to access which variables. He will perhaps try to build modules which have a smaller problem space. This is equal to introduce object oriented programming. Using a single class for storing all the 300 variables is an anti pattern in software development. It will make the workflow much harder.
The problem with Prolog and LIsp is, that both languages are close to the antipattern. Either no OOP features are available or their importance is ignored. Instead other ideas are utilized for example the ability to modify the own code or to store facts as RDF-triple. The problem with these techniques is, that they can't replace OOP.
One to one comparison
A direct comparison between a Prolog style program and a object oriented technique is shown in the sourcecode. Instead of a Prolog interpreter a normal Python interpreter was used, but the programing style was oriented on Prolog. That means, the text adventure contains of facts stored in a list, and it contains of rules which have preconditions. in contrast, the second example was realized with normal Python classes which is more easier to read.

Sourcecode at the end of the blogpost 


From the game itself, both are the same. The world contains of a robot, a box and a gripper. The variables can be changed with actions like “moveto” and “setdirection”. The difference is, that in the first example with a fact database no object oriented advantages were used. Instead all the fucntions have access to all the variables. Even the game is small this can become a problem. It's unclear which function is allowed to change which variable.
In the second example, this question was solved with the well known OOP feature. That means, the variables are hold in different objects and the functions in the object can only modify the variables with within the object.
But let us talk about the first version of the program which is using a Prolog style. The interesting point is, that the program itself can be explained very well. At the beginning a fact database gets initialized and then some rules are implemented which are operating on the facts. After executing the program it works quite well and it's possible to solve the game autonomously with a graph search algorithm. The only thing what is missing is any kind of object oriented programming. Instead of using classes, the sourcecode is distributed around the fact storage and the rulelist. If the concept of OOP is unknown it will make sense, but under the perspective of OOP the question is what is the advantage?
From a perspective of computing history the reason why in the past non oop techniques were used was, that the problems were small. A blocksworld problem can be easily implemented in Prolog and a text adventure with 300 lines of code perhaps too. The reason, why OOP was developed is because the technique of storing all the variables in the same space will make programming too complicated in the amount of sourcecode is larger. This is especially true, if the facts are stored in a RDF triple storage and dedicated fucntions were implemented to add new facts. For the program and for the Prolog compiler as well the system is always in a healthy state, but which programmer is able to fix the sourcecode and adapt it to the domain?

"""
prototype for text adventure
- fact list
- tasks
"""
class Game():
  def __init__(self):
    self.facts=[]
    self.tasks=["setdirection","moveto"]
    self.updateworld()
    self.show()
    self.task("setdirection","south")
    self.show()
  def updateworld(self):
    self.facts.append(("gripperstatus","open"))
    self.facts.append(("robotdirection","north"))
    self.facts.append(("robotposition","waypoint1"))
    self.facts.append(("boxposition","waypoint2"))
  def changefact(self,action,name):
    if action=="remove":
      for i in self.facts:
        if i[0]==name:
          self.facts.remove(i)
    if action=="get":
      for i in self.facts:
        if i[0]==name: return i[1]
  def task(self,name,parameter):
    result=True
    if name==self.tasks[0]: # setdirection
      if True: # no precondition
        self.changefact("remove","robotdirection")
        self.facts.append(("robotdirection",parameter))
      else: result=False
    if name==self.tasks[1]: # moveto  
      p1=self.changefact("get","robotposition")
      p2=parameter
      angle1=self.changefact("get","robotdirection")
      angle2=settings.angle_between_two_points(p1,p2)
      diff=settings.anglediff(angle1,angle2)
      if abs(diff)<5: font="">
        self.changefact("remove","robotposition")
        self.facts.append(("robotposition",parameter))
      else: result=False

    return result
  def show(self):
    for i in range(len(self.facts)):
      print(i,self.facts[i])
    print(self.tasks)
    
if __name__ == "__main__":
  g=Game()



"""
second attempt for text adventure
  - using object oriented programming
"""
import sys
sys.path.insert(1, '..') # different folder for import
import settings

class Box():
  def __init__(self):
    self.pos=(100,100)
    self.angle=0
    
class Robot():
  def __init__(self):
    self.gripper="open" 
    self.angle=90
    self.pos=(200,100)
  def setdirection(self,angle):
    self.angle=angle
  def moveto(self,pos):
    a1=settings.angle_between_two_points(self.pos,pos)
    self.setdirection(a1)
    self.pos=pos

class Game():
  def __init__(self):
    self.myrobot=Robot()
    self.mybox=Box()
    self.plan1()
  def plan1(self):
    self.myrobot.moveto(self.mybox.pos)
    print(self.myrobot.pos,self.myrobot.angle)


if __name__ == "__main__":
  g=Game()    


July 29, 2019

GOAP Textadventure


Even if GOAP was introduced in the literature already, it make sense to give a simple example. In the following sourcecode a GOAP planner for solving a textadventure is presented. It contains of the action model itself and a randomized solver for determine the action sequence.
"""
description: GOAP Textadventure 2019-07-29
"""
import random,copy

class Actionmodel():
  def __init__(self):
    self.worldstate = None
    self.tasklist=("openbox","closebox","takekeyfromtable","putkeyinbox","takeball","placeballatgoal")
    self.reset()
  def reset(self):
    self.worldstate = {
      "ballpos": "inbox", # inbox, atrobot, atgoal
      "keypos": "attable", # attable, atrobot, atboxkeyhole
      "boxstatus": "close", # close, open
    }
  def task(self,name):
    result=True
    if name==self.tasklist[0]: # openbox
      if self.worldstate["keypos"]=="atboxkeyhole":
        self.worldstate["boxstatus"]="open"
      else: result=False
    if name==self.tasklist[1]: # closebox
      if self.worldstate["keypos"]=="atboxkeyhole":
        self.worldstate["boxstatus"]="close"
      else: result=False
    if name==self.tasklist[2]: # takekey
      if self.worldstate["keypos"]=="attable":
        self.worldstate["keypos"]="atrobot"
      else: result=False
    if name==self.tasklist[3]: # putkeyinbox
      if self.worldstate["keypos"]=="atrobot":
        self.worldstate["keypos"]="atboxkeyhole"
      else: result=False
    if name==self.tasklist[4]: # takeball
      if self.worldstate["boxstatus"]=="open" and self.worldstate["ballpos"]=="inbox":
        self.worldstate["ballpos"]="atrobot"
      else: result=False
    if name==self.tasklist[5]: # placeballatgoal      
      if self.worldstate["ballpos"]=="atrobot":
        self.worldstate["ballpos"]="atgoal"
      else: result=False
    return result
  def show(self):
    print(self.worldstate)

class Solver():
  def __init__(self):
    self.mymodel = Actionmodel() 
    #self.plan1()
    self.randomsearch()
  def randomsearch(self):
    planlength=5
    trialmax=100
    for trial in range(trialmax):
      engine=copy.deepcopy(self.mymodel)
      actionlist=[]
      for i in range(planlength):
        name=self.validaction(engine)
        actionlist.append(name)
        engine.task(actionlist[-1])
      if engine.worldstate["ballpos"]=="atgoal":
        print("trial",trial,actionlist)
        engine.show()
  def validaction(self,engine):
    maxtrial=16
    for trial in range(maxtrial):
      localengine=copy.deepcopy(engine)
      r=random.randint(0,len(localengine.tasklist)-1)
      name=localengine.tasklist[r]
      temp=localengine.task(name)
      if temp==True: break
    return name
  def plan1(self):
    m = Actionmodel() 
    print(m.worldstate)
    m.task("takekeyfromtable")
    m.task("putkeyinbox")
    m.task("openbox")
    m.task("takeball")
    m.task("placeballatgoal")
    print(m.worldstate)

class Game():
  def __init__(self):
    self.mysolver =Solver()   

mygame=Game()
The textadventure contains of a robot who has to place a ball into a goal position. Unfortunately, the ball is located in a box, and the box is secured with a key. For modeling such a game, a worldstate is created in form of a Python dictionary. The worldstate holds the ballposition, the keyposition and the status of the box. The user can send tasks to the textadventure like “openbox” and the game engine analyzes if the task is valid. For example, the box can only be opened if the key is in the box.
For testing out, if the action model works the method “plan1()” was created which sends a sequence of actions manual to the game engine, similar to playing the game interactively. After “plan1()” works, the solver can be implemented which finds the correct sequence autonomously. The solver is using a random generator for sending all possible action sequences to the action model. If the desired goal states is reached the solver stops.
Let us describe the system more abstract. in contrast of a STRIPS solver no dedicated planning language was used, instead the check if the preconditions are fulfilled are done within the class in computercode with if-then-statements. Additionally, the solver is not very advanced but because of the small state space it's working fast enough. In less than 100 lines of code it was demonstrated how a GOAP action model can be realized in Python and how a solver plans the action sequence.
Let us take a look into the core function which takes an action and calculates the next worldstate. The idea is, that the user sends a predefined command like “openbox” or “takeball” to the task-subfunction. The first thing what the method is doing is to check if the precondition is fulfilled. For example, the box can only be opened, if the key is in the keyhole, otherwise the task fails. The inner working is based on a if-then-statement plus direct manipulation of the worldstate. That means, the function changes the worldstate to the new value. For the programflow the action names doesn't need to be formulated in natural language. The method would work the same, if only the actionid is send. But for reason of debugging it make sense to use English descriptions. This allows the user to interact with the program in a pseudo-engish language. That means, the user can send a request like “putkeyinbox” to the game engine, and the program is doing something.
The GOAP model works similar to a textadventure. That means, the worldstate and the allowed actions are formulated in a textonly language and no graphical representation is allowed. The most interesting result is, that the resulting statespace of all allowed actions is very little. Overall the game consists of 6 actions plus 3 variables in the worldstate dictionary. That means, for the solver it is very easy to find the desired goal state by simply testing out random actions.
Nobody cares of a performance increase of factor 1000
What if a technique would be available which is able to run a Artificial Intelligence algorithm 1000x times faster? The surprising fact is, that such speed up is easy to achieve. All what the programmer has to do is switch from the Python language to C++ language which results into a speedup with the factor 10, and then he prefers rapidly exploring random trees (RRT) search technique over a normal random solver which makes the program run 100 times faster. In a direct comparison, a RRT graphsearch in C++ is around 1000x faster than a Python randomized solver.
But there are some reasons who speaks against this kind of speedup. The problem is, that RRT is harder to implement because a complicated graph has to be maintained, and the C++ version needs more time to type in than the Pyhon language. Another surprising fact is, that a speedup of factor 1000 is not big enough in Artificial Intelligence. In normal computing such improvements is great, but for problems in Robotics and AI the needed performance speed up is much greater. In AI, only a speedup in the size of 1 million times faster and more is something which should be mentioned. Or to explain it the other way around. If an AI search algorithm is too slow, this is equal that the algorithm needs instead of milliseconds the amount of years. To overcome the issue it is not enough to switch from Python to C++, because the result is, that even in C++ the algorithm would run too slow. Most AI problems can only be fasten up with additional abstraction layers, which modifies the problem itself.
Unsolved problems
On the first look, the Python program works great. It calculates the action sequence and can bring the system into the goal state. The open question is, if the simplified textadventures simulates the reality accurately. That means, if the real world and the goap model are working the same.
Storing the task into a dictionary?
From a technical point of view it would be interesting in storing the actions as a dictionary. This would allow to add new actions during runtime. The same technique is used in the STRIPS language and in the ACT-R cognitive architecture as well. All these planner are based on the principle that the possible actions are not stored in sourcecode direct, but as data.
But in reality the advantage is only low. Sure, some lines of code can be safed, but I'm in doubt if the concept would scale very well. If we take a look into more complicated textadventure, the game engine is usually create with normal Python code, but not with code which run modify during runtime. Sure, the LISP language allows to treat sourcecode as data as well, and it's interesting to describe the details, but the resulting system is very complicated to understand. The reason why the documation of the ACT-R project doesn't make much sense, is because self-modifying LISP code was used everywhere in the software. I think the more beginner friendly idea is to use only static code which is modified with a version control system like git. That means, if we need a new action, we have to add a if-then-entry in the sourcecode.
Suppose, the textadventure is able to parse not only single word statements but two word actions for example “take ball” or “open box”. The resulting parser would work differently. The sourcecode has to be modified. I think it's important if some sourcecode is there which can be adapted to new requirements. So i decided against storing the code in a dictionary. For the user the only thing which is important is, that he can send an action name to the game engine and the engine is changing the worldstate. How this is done internally it's up to the Python programmer.

The difference of computer science and artificial intelligence


Computer science is taught on most universities. The aim is to take an algorithm and convert it into a runnable program. The software is started on real hardware and solves a problem the normal user has. A typical example in which computer science can help a lot is to search for a node in a graph. Computer science describes which algorithm for graph search are available (for example depth first search), it provides a programming language (for example Python) and it makes recommendation who to run the software (with the help of the Linux operating system which runs on a Laptop).
Unfortunately, Computer science fails if the problem doesn't fit to this structure. This is true for most Artificial Intelligence problems. AI has the goal to transform a problem into a computer science problem. A typical example workflow is, that AI invents a theory about a robot control system, this theory is converted by computer scientists into software and then it can be executed on a real computer. If computer science is about algorithm, compiler design, operating systems and computer hardware what is the topic of Artificial Intelligence? It's about observing humans and create machine readable models from it. AI experts call these models forward models or knowledge models and they are describing who humans solving a problem. The aim of AI is to create universal models which fits to many situations.
Let me give an example to explain the difference between computer science and Artificial Intelligence. AI is about inventing neural networks, STRIPS notation and expert systems, while computer scientists are converting these ideas into runable code.

Measuring Artificial Intelligence with the AI in the box experiment


The simple reason why the AI-in-a-box experiment is so effective is because it is able to hold down Artificial Intelligence. This feature is important because otherwise the human has no chance. To understand the issue we have to go back to the first computer chess matches in which human experts played against the computer. Usually such a match ends with the winning of the machine.
The same match can be done in any other domain. For example Starcraft or Pong. No matter how well the human plays, he will loose the match against the computer. That means, there is no game available which can be played only by a human but which is to hard to a game AI. The AI-in-the-box experiment is the logical next step after the recognition that the human will loose any game. If the human is not able to win against the machine, because the AI can think much faster and try out more creative approaches, then the human needs a different option to hold down the AI. In a normal match this is called cheating, and exactly this is done in the AI in the box experiment. The idea is not to let a human play against the AI under equal start conditions, but the idea is, that the AI starts in the starcraft map with less resources and is encapsulated after a big wall. That means, the human is no longer a player in the game, but the human controls the resources and observers what the AI is doing with limited access to energy.
The simplest possible AIbox experiment can be realized within computerchess. All what is needed is a chessboard which allows to start with synthetic board positions. One side gets only a king and a pawn, and the other side has build a wall of queens around the king. Now, the king has to win against the stronger opponent, and the king is played by the AI. Even if the AI is the most advanced chess engine ever created which runs on a supercomputer, he is not able to beat the human. Because the human has more physical resources. The human player is in the social role of the environment. He controls all the pieces on the board and even his movements are not planned great, the AI has no chance to win the game. This gives the human the flexibility to study an advanced chess player in a controlled environment.
In contrast to a normal chess game between AI and human such experiment make sense, because the human isn't forced to win the game. He starts with a better position from the beginning and can relax.

GOAP planning for Sokoban


The game of Sokoban consists of a robot, a box and a goal. The robot has to execute some actions which pushes the box to the goal. Instead of creating the overall gametree the better idea is to describe the problem from an abstract perspective. In the GOAP (goal oriented action planning) technique the robot has the following actions:
- movetobox (precondition: robot far from box, effect: robot is at box)
- adjustposatbox (precondition: robot is at box, effect: robot has push position)
- pushbox (precondition: robot has push position, effect: box is at goal)
The planner can generate an action sequence. A sample plan would look like: movetobox, adjustposatbox, pushbox.
This is the basic idea behind GOAP. But perhaps it's possible to somplify the overall pipeline with conditional planning. Conditional planning means to create a more abstract plan which works in different situations.
The main idea behind the GOAP problem solving technique is to transfer a domain into a language. In the Sokoban example, three actions are available plus some world descriptions like “robot is at box”. This new kind of problem is a textadventure, it is played interactively and the visual representation is no longer needed. A pleasant sideeffect is, that the state space was reduced dramatically. Even the Sokoban map has a size of 100x100 fields, the planning space for the solver is reduced to the textadventure.
The open question is, if the problem space can be reduced further. A possible idea would to a use constructive grammar which produces the textadventure. In the literature this is called "procedural grammar". A GOAP model has the syntax:
rulename, if feature then feature
Rule induction
If the GOAP action model is not known in advance it make sense to collect a dataset and try to determine the rules with machine learning algorithm like Decision tree learning algorithm C4.5. At first, we need a vast amount of data:
case id
name
precondition
effect
0
movetobox
robot far from box
robot is at box
1
movetobox
robot far from box
robot is at box
2
adjustposatbox
robot is at box
robot has push position
3
adjustposatbox
robot is at box
robot has push position
4
pushbox
robot has push position
box is at goal
5
pushbox
robot has push position
box is at goal
In the table some cases are recorded. They were acquired from plan traces in a learning from demonstration scenario. To make thinks simple, the precondition / effect variables are the same, that means every action was successful. The idea is to first record all the interaction with the Sokoban game, extract features, group these features into actions and then give the actions a name. The result is GOAP forward model which predicts the outcome of an action in terms of feature values.

July 27, 2019

How to win against an AI


In the game OpenRA there is an option to play against an Artificial Intelligence. It is working with scripting AI and the AI is cheating. Not in the sense, that it's playing to well but the opposite. The build in feature of the AI is, that the programmer has reduced it's performance. Otherwise the human player would always loose.
Somebody may think that's easy to win against a computergenerated force. Because the human player has the ability to think abstract and the AI not. The problem with modern AI systems is, that they have a lot modules builtin which can plan ahead and additionally the AI can press in one minute more often a keystroke so overall the human player has no chance.
From a strategy point of view the question is how to win against an opponent who is stronger and nearly unbeatable. The first thing to do is to measure the performance of the AI precisely. The newbie may think that the AI has an advantage of 30% or maybe 40% and as a result it's possible to overcome the gap with some tricks. The sad fact is, that the advantage of the AI is much greater. A normal programmed AI is at least 10 times stronger, and a well realized AI is up to 100 times stronger. The advantage can't be measured in a challenge similar to the ELO score in a chess tournament, but it's an absolute value which has to do with how many actions the AI can execute each minute, and how little error the AI is doing during runtime. A single AI can play easily against 10 human players at the same time.
How likely is the chance to win against such a player? Right, the chance is zero. Even if the human player trains hard he can't beat a computer program. It's a physical limit he has. A human player can press each minute around 60 times a mousebutton and activate an action. In contrast, a computer generated force can press in the same time the mousebutton 600 times and more. Especially if the situation is more complex the computer has an advantage because the same algorithm can handle hundred of detail problems in the game and he can decide each issue with maximum efficient.
Some years ago during the last AI winter there was a time, in which philosophers were optimistic that computer's can't do everything. They imagined, that the strength of computers is located in repetitive tasks, while creative complex tasks can't be handled by computers. At this time the philosophers were right, because in the early 1990s there was no example available of well playing game AI. If the programmer struggle to program such an automated player it is easy to maintain a position in which the human is always superior to a machine. Unfortunately, the gap is only a technical detail. If somebody programs an AI, then the AI is able to beat the human.
The only chance a human player has to win against a game AI who plays OpenRA is, if no such AI is available. That means, the human acts in an environment in which game AI are not highly developed, because the AI experts are not available or they are not able to solve the issue. The programmer takes a short look at the problem, comes to the conclusion that the state space of OpenRA is too complex and then he admits, that it's not possible to create a simulated force.
Putting the AI Into a weaker position
A normal game of OpenRA starts with the same conditions. That means, the AI starts with the same amount of ressources like the human. In a short amount of time, the AI is using it's strength to increase the gap to the human. That means, he will build more units and conquer a larger space of the map. The result is a very strong AI which has occupies more ressources and the human player has become much weaker.
But what will happen, if the AI is put into a weaker position, somewhere in the middle? That means, the AI has less units and less ressources, while the human controls the map? Right, then the game is fair. Which means, the AI has fight hard to beat the human. The AI needs all the power to overcome the weaker starting position. From a philosphical point of view, such experiments are called “AI in a box”, because the aim is not to play a match against the AI, but the idea is to put the AI into a prison, and then observe what the system is doing with the limited ressources. The human player doesn't compete with the AI but it's forming an environment for the AI.
The situation is comparable in a computer chess match in which the AI has only the king and the human player dominates the match with the entire collection of all the powerful pieces like queen, bishop and so on. If the AI will become too powerful, the experiment gets stopped.

Again, GOAP architecture explained


Goal oriented action planning is basically an explanation how to implement the STRIPS planner in a computer game. The first step is to create a table with actions:
name, precondition, postcondition, costs
The table gets filled with actions like “walktolocation”, “getupobject”, “opendoor”. The table can be seen as an abstract textadvanture, in which the robot can execute actions which brings the system into a new state. If the textadventure contains some possible actions, it's possible to start the simulation with an inputstate for example “robot is in the middle” and a goal state “robot is at the exit”. And now, the planner calculates the steps in between. The solver works with a graph search algorithm, similar to a pathplanner but only for symbolic actions.
And now comes the funny part, what will happen if an action like “walktolocation” should be executed? Right, the details are not stored in the table. The action name has to send to the physics engine in the game. That means, the game has the same table which is enriched with the details how to execute an action. In most cases, it is realized with normal computer code. That means, in the game engine there is a method called “walktolocation”, and this method contains of some statements.
Explaining the difference between GOAP and STRIPS is a bit difficult. From a technical perspective it's the same. I would go a step further and call GOAL a slim down version of STRIPS. That means, it's a step backward. The advantage of GOAP over STRIPS is, that the surrounding documentation is easier to read. All the philosophical and mathematical parts of the STRIPS project are missing, and GOAP is some kind of tutorial how to realize a non player character for a game. It's not an algorithm nor a framework and be programmed with any language like Python or C++. GOAP is some kind of documentation how to create a symbolic planner from scratch. The tutorial explains, that the first thing which is needed is a table which contains of actions, also the precondition/costs and postconditions are stored in the table. And then a planner figures out the next steps for the robot. GOAP can be seen as software engineering pattern for creating a simple planning robot.
No Algorithm available
Computer programmers are trained to search for a library, an algorithm or a framework which can solve a task. Unfortunately, GOAP isn't an algorithm and even some example sourcecode is available at github it makes no sense to use this code in the own project. The inner working of GOAP is to create a textadventure around a given problem. That means, it won't solve an issue but it will make things more complicated. GOAP can be described as an abstract game engine which is traversed by a solver. It is not located within the domain of computer science and algorithm theory, but has to do with software engineering.
Let us observe how existing GOAP solvers were created in the past. In all cases, the programmers are using an existing programming language like C# or Python and build their own GOAP datastructure. Then, the table is filled with actions from the domain. The problem is, that the process of doing so is highly individual and can't be reproduced very well. What we can for sure is, that an object-oriented programming language was used and that the GOAP framework fits into the normal version control contributions which are made with the git tool. The programming of a GOAP solver is motivated by the requirements to program a non player character which has a certain feature set. And the understanding of the AI programmer how to realize such features in software.
It's interesting to know, that GOAP was first described by practical game developers. Perhaps one reason is, that it can't be formalized in algorithmic notation and can't be described with mathematical terms. I would located GOAP next to software engineering discipline which is a highly individual discplines which is dominated by personal stories from real projects. It makes sense to explain how a certain game was upgraded with a goap solver, and it make sense to summarize different software projects in comparison. But the attempt of explaining GOAP from a theoretical perspective will fail.
Text adventure generator
A GOAP model is equal to a text adventure. Producing such models can be realized with a text adventure generator. This is a piece of software which is producing a game. In the game, it's possible to do actions like “opendoor” or “walktolocation”. The textadventure which is the GOAP model will figure out what happens next. The advantage of a textadventure is, that a solver can determine the needed actions easily because the overall state space is small. It can be converted into a graph and the solver will take under a second to find complex action sequences.
The open problem is how to convert a normal game into a textadventure. The term textadventure generator implies that the process can be done autonomously, but in reality most GOAP models are created in a software engineering process by human programmers. They take a look at the game and write for the game a text interface. This results into the agent architecture which can solve the game autonomously.

Create an AI box experiment with computer games


The AI box experiment is the logical step after a human has recognized that he will loose any game against the AI. After a chessplayer has lost 10 matches against the computer player, he will come to the conclusion, that he needs a controlled environment in which he can observe the behavior of the AI. This is possible be given restricted ressources to the AI. That means, the human player has the normal chess pieces, while the game AI starts only with a king. Now, the AI can use all it's strength and the human can't be beaten. The ability to think very fast, and the ability to think 100 moves ahead won't help a single king to win against a human controlled setup.
The same AI in a box experiment can be realized with the realtime strategy game OpenRA as well. :The idea is, that the game AI starts with lower ressources than the human. And then the AI has to overcome it's restrictions. Even if the human player doesn't play very well the game, the AI can't beaten him because the AI is in a weaker position. Similar to be restricted to a prison.
What would happen, if the AI is able to understand the situation, can it escape from the prison? Yes and now. Let us observe first the situation with computerchess. A single king, even if it's controlled by the strongest AI player in the world is not able to win against a normal equipped situation which contains of 16 pieces. No matter, which kind of trick the AI is trying to explore, the human is always stronger.
The problem is, that not all prisons are secured very well. In some movies it was shown, that the prisoner can escape. And if a human can do so, an AI has perhaps the same capabilities. The point is, that in an escape game, the AI starts in weaker position. The idea is not to figure out who plays a game better, but the idea is, that the opponent controls the game, and the AI has to overcome the restriction.