How to write a Mind

To write a new Mind for a World, you will need to understand the state and action formats of the World. (Each World can have different state and action formats.) These formats will be explained by the World author in comments or in sample Minds.

Proceed as follows:

  1. Create your new Mind.
    Either clone an existing Mind:
    • Find a Mind that already works with the World. Go to the page for that Mind and click: to make your own copy of it. The Mind's code will show you how to parse the World state and generate correct World actions.
    Or start with a blank Mind:
    • Go to the World page and click: to make a new blank Mind.

  2. You now have a new Mind, that you own. To edit it, click:
  3. At any point, you may click: to see what your code does.
  4. Your modified code is not saved to the server until you click:



Example Mind

Here is an example Mind that you can clone and edit.

The World is a simple 3D world. The Mind makes random movements.


Simple Mind
World: Simple World
1249 runs ♦ 2 likes
By Starter user  
Created: 1 Oct 2016
Modified: 18 Apr 2021
Ignore enemy. Just move randomly.



Minds may have memory

Minds may have memory. They may update a data structure on every step. In JavaScript:

 
 var i;				// or any other data structure

 AB.mind.newRun = function()
 {
  i = 1;			// or any other initialisation of the data structure
 };

 AB.mind.getAction = function ( x )		 
 { 
  i = i + 1;		// or any other update to the data structure
  return ( action );
 };




Calling other Minds

A MindM is a Mind that calls other Minds. See the AI model behind Ancient Brain. In its definition of the getAction function, the Mind may call another Mind to find out what its suggested action would be. The Mind might ask multiple other Minds for suggested actions, and either use one or return an action of its own.

The basic issue with a Mind calling a Mind is that both of them are trying to define the same functions of AB.mind:

 
AB.mind.newRun = function() { ... };  
AB.mind.getAction = function ( state ) { ... };     
So we must rename the functions defined by the called Mind. Proceed as follows:
  1. Clone the Mind you want to call.
  2. Edit its code and rename its functions to different names like:
    var mind2;
    mind2.newRun = function() { ... };  
    mind2.getAction = function ( state ) { ... };
The other Mind won't run on its own now, but you don't care. We have the following approaches to calling it.

Mind in separate JS

Keep the Mind in a separate JS file. The calling Mind will load the separate JS and then call the function names. Something like:



 var mind2 = new Object();   
 // global variable that the other JS will now assign methods to 
  
 AB.mind.newRun = function()
 {
   $.getScript ( "/minds/nnnnnnnn.js", function() 
   {
     // JS is loaded, mind2.functions are now assigned 
     mind2.newRun();
   });	
 };
 
 AB.mind.getAction = function ( state )     
 { 
    // need some default in case JS is not yet loaded:
    if ( typeof mind2.getAction == 'undefined' ) return ( defaultaction );     
 
    // else we can call the other Mind: 
    if ( condition )
      return  ( mind2.getAction(state) );                   
    else 
      return  ( myaction );                      
 };


Mind in same JS

An alternative is to just copy the Mind code into your Mind JS file. Then you can go ahead and call its functions. Something like:



 var mind2 = new Object();   
 mind2.newRun = function() { ... };  
 mind2.getAction = function ( state ) { ... };      
  
 AB.mind.newRun = function()
 {
     mind2.newRun();
 };
 
 AB.mind.getAction = function ( state )     
 { 
    if ( condition )
      return  ( mind2.getAction(state) );                   
    else 
      return  ( myaction );                      
 };
 



Other people can use your Mind

When you write a new Mind, it will appear on the list of Minds for this World. Other people can run your Mind. Other people can clone it, and call it from their Minds.

  
  

Document your Mind

If your Mind needs instructions for use, you can document this in comments in your code. For example:


// If you are writing a Mind_M to call MyMind, make sure you call MyMind on every step:
//   MyMind.getaction(state);  
// even if you are going to ignore the result.  
// This is to keep MyMind informed of every step of the run to help it build up a map of the problem.