Welcome to the the GAMYGDALA homepage! GAMYGDALA is an easy to use emotion engine for games. It enables developers to simulate emotions in NPC's. GAMYGDALA can be used in a black-box game-AI independent manner. We currently distribute a javascript version of the GAMYGDALA engine. Further, we have developed two Phaser Plugins and an example of how to use GAMYGDALA that builds upon level 9 of the Phaser tutorial (so do that one first to get to know Phaser). This website includes info on how to use GAMYGDALA, as well as links to several running example games based on the Phaser game engine.
To download locally all you need to start playing with it, as well as to contribute post requests and bugs, see the GitHub project called gamygdala

GAMYGDALA is released under the MIT license.
For questions, contact joost.broekens@gmail.com
GAMYGDALA is based on the following publication, so please refer to it when you use it or find it useful (or check it if you want to understand how it works in depth):

GAMYGDALA: an Emotion Engine for Games Alexandru Popescu, Joost Broekens, and Maarten van Someren (2014). IEEE Transactions on Affective Computing, 5(1), 32-44

Please note that the iconic facial expressions have been based on drawings made by Valentijn Visch (credits to him).

For questions: contact joost.broekens@gmail.com

Joost Broekens, TU Delft

Example games

friend_or_foe.html is an example of an "Emotional Arcade Game" where the bad guys' relations to you influences their behaviour.
Is contains assets from the Phaser tutorial, and copyrights are thus owned by others not me.

everyones_friend.html is an example of an "Emotional Puzzle Game" where your goal is to make everyone happy by giving them the price they desire.
It contains copyrighted assets of others (e.g., Pixar, Nintendo), so please keep in mind that this is FOR EXAMPLE PURPOSES ONLY!!

The gamygdala website and GitHub site will be updated soon to be better looking and to contain more examples.

GAMYGDALA usage explained

Here we come to the emotion part you've been waiting for. This explains the use of the GAMYGDALA emotion engine.
It is the textual explanation of the gamygdala_demo.html running example build on top of the Phaser tutorial level 9. You can find all code on GitHub.
If you are a more practically oriented, learn-while-you-are-doing kind of person, we advise you to get the code and simply go through this example in code, as it contains the same info.
Note that the plugin classes are Phaser specific, but if you dont use Phaser, you can use Gamygdala stand-alone.

See the full javascript documentation for more details on classes, methods and useage. See the IEEE paper for more details on how gamygdala internally works.

Let's start...

First create the main emotion engine (using the Phaser plugin wrapper class, but this can be done directly too, see below).
The engine is needed to interpret how events (Belief in Gamygdala terms) relate to goals resulting in emotions.
The following three lines create one instance of Gamygdala that is used by all emotionAgents, and registers this as a Phaser plugin.

gamygdalaPlugin=new Phaser.Plugin.GamygdalaWrapper();//create the Phaser plugin.
game.plugins.add(gamygdalaPlugin);//add the plugin to the game, as required by Phaser
emotionEngine=gamygdalaPlugin.getGamygdala(); //this gives you a ref to the actual underlying emotion engine, so that you can do what you need to do.

If you don't need emotional decay (the fact that emotions decay,i.e., if a guy is angry he will slowly become less angry) to be managed by the Phaser plugin engine, then you don't need to do all this, instead you can do the following:

emotionEngine=new TUDelft.Gamygdala(); //this simply creates an emotion engine without plugin support.

From now on we can do everything we need with the emotionEngine object reference, as this is an object of type Gamygdala
We create a new agent that represents the players emotional state. The method createAgent makes a new Agent, and registers it with gamygdala, and returns a ref to the agent.
We store the ref in the Phaser player object for later convenience.


Now let's give the player some goals: survival and winning are both good, but survival is better.

emotionEngine.createGoalForAgent('player','survive', 1);
emotionEngine.createGoalForAgent('player','win', 0.7);

Alternatively, you can do the necessary goal management yourself instead of having gamygdala do it for you with the create method.
This involves creating the goals and adding them to the agent(s) that have these goals (there can be more owners of the same goal so you can create group goals), and registering the goal to gamygdala.

player.emotionAgent.addGoal(new TUDelft.Gamygdala.Goal('survive', 1));
player.emotionAgent.addGoal(new TUDelft.Gamygdala.Goal('win', 0.7));

Now we are basically done for the player's emotions, apart from the fact we want to see something, so we add expression to the player.
This is not really part of Gamygdala, just an easy and crude way of visualizing the emotions using Phaser

game.plugins.add(new Phaser.Plugin.GamygdalaExpression(game, player, player.emotionAgent));

We are now done with setting up the player, but we want the monsters to be emotional guys too (to showcase relations NPC's can have with other NPC's or player agents)

for (var i=0;i {
   //create the Gamygdala agent and store it in the bad_guy object for easy reference later, because when the player gets hit, we need to tell gamygdala who did it.
   //add a relation between player and monster for fun, the first monster hates the player, the second one likes the player, the third hates, etc..
   emotionEngine.createRelation('monster'+i, 'player',(i%2)*2-1);
   //add expression to the bad guy so we see something
   game.plugins.add(new Phaser.Plugin.GamygdalaExpression(game, bad_guys.getAt(i), bad_guys.getAt(i).emotionAgent));
   //We don't need to set goals for these bad guys. In our setup they achieve nothing, just react to what happens with the player: feel pity, gloating, etc...

Finally we need to tell gamygdala to decay emotional states over time (you don't stay angry, the intensity should go down right?)
There are three ways to do emotional decay:
1. Either you use Gamygdala as standalone module, not requiring Phaser.
In this case , Gamygdala will manage the emotional decay itself, and you need to tell it to do so.
In the following line, you tell Gamygdala that every 100 Millis it decays the emotional state of all agents (using the default exponential decay with a factor of 0.8 per second).


2. You use the phaser plugin update to manage emotional decay, you should tell the plugin to do so using the next line.


3. Finally, you can choose to call emotionEngine.decayAll() yourself when you need it.
This is usefull if you have a lot of agents and need to be efficient, or, if some agents dont need decay at all, or you want to write your own timing routines
In such a case you need to manage decay yourself using the desired timing, so you have to manage the interval yourself.

Should you want, you can set the type (exponential or linear) and speed of decay [0..1], for example with a faster exp decay speed using:

emotionEngine.setDecay(0.4, emotionEngine.exponentialDecay);

Now you need to calibrate the overall emotional intensity. This is more an art than a science.
If you notice the emotional intensities are too low in general, you set the gain higher, otherwise you set it lower. Gain must be between 0 and 20
How gain works can be seen in the Agent.getEmotionalState();
Normally, you decide the gain for the whole game, but if you know that certain NPC's need a higher or lower one, you can set the gain for each NPC separately using Agent.setGain(gainFactor);


If you want to enable debug output to the console, than uncomment the next line


Some final remarks...

GAMYGDALA is very flexible. You can make use of it in many different ways, and this example is only one way. For example, the degree of agent specific emotion control is flexible.
To name a few ways in which you can do this:
  • You can choose to run the engine for only those agents you know have received new beliefs (using Gamygdala.appraise(Belief, Agent), where Agent is the one for whom you appraise the belief)
  • Define a common goal for multiple agents so that they all react to beliefs that changes the goal likelyhood of being achieved
  • You can define completely different dynamics for each agent, using different decayfunctions and decay factors
  • You can have only one "agent" for all bad guys, e.g., an agent called "bad_guys", if you want them to be all bad, with the same relation. Then being hit simply results in an event caused by "bad_guys", and you can then use that same agent ref for all expressions for the bad guys.
Also notice that Gamygdala's classes use String references in the constructors, e.g., new Belief(likelihood, causalAgentName, affectedGoalNames, goalCongruences).
This is true for new Agent(name), new Goal(name, utility), new Relation(...) and newBelief(...). This makes is very is to script/config the emotional setup, because you can simply use string refs to the objects.
Also the Gamygdala.createAgent(..) and Gamygdala.createGoalForAgent(..) work with literal refs, so an alternative is to have a sequence of these be loaded from a txt file and executed.