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.
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 email@example.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 firstname.lastname@example.org
Joost Broekens, TU Delft
Example gamesfriend_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 explainedHere 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.
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.
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..
//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:
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:
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.