Monday, December 3, 2012

Starting AI

Took the starting steps to implement the storytelling AI. There's a lot left to do, but I've been seeing tremendous results even in these early stages.

Right now I've done two things:

  • Removed the hardcoded "turn" termination of the program. Before now the program ran until each character had been granted an x number of turns. Now I've adopted a "storytelling" approach based on screenwriting formatting - a story is made up of 3 major events, commonly referred to as "the inciting incident," "plot point 1" and "plot point 2". As a result, the simulation now runs until three actions of AIV level 5 (the max) have been performed. After the turn of the third one, the simulation ends. This is rudimentary - I still need to figure out a way to allow for the story's "conclusion" - but so far it's proved incredibly effective at keeping the focus of the "story" fairly narrow.
  • Made it so any actions below a certain AIV don't print. It's amazing how much of a difference this makes... At some point I'll try to do a test where I output the same "story" with this suppression and without it so that it's clear just how important omission of irrelevant/boring details is to telling a good story. This is also far from complete... In the finished version, we need to select a "main character" (in a game, this would always be the player), then we construct a tree of degrees of separation (Kevin Bacon style) in which a lower degree means that less relevant information is still important. That is, any AIV prints for the main character, any above AIV 2 prints for a character of degree 1, any above AIV 4 for a character of degree 2, and for degrees 3 and higher we never see what they do. Right now we're just equally suppressing everyone's "uninteresting" actions, which goes a long way towards telling a story but doesn't factor in concepts of protagonists and story focus. That comes next.

The Unity Problem

I've discussed in the past my fears concerning Unity and how difficult it would be to use. Those fears were mostly quelled thanks to a one on one meeting with Aline a couple of weeks back. Though one or two were also substantiated.

Aline sat down with me and helped me build a basic framework for a character walking around a scene and a movable camera that I would theoretically be able to expand to incorporate my simulation. Unfortunately, we hit trouble when Aline tried to help me port the program back to my computer. Luckily, she was able to get it up and running on my PC, and while I'm still not entirely sure I understood how she set up some of the more complex animations, I believe she taught me enough about how the program works that I could start moving the code over without any major catastrophes. If you are reading this, Aline, thank you so much for the foothold into Unity. It's given me a lot of confidence about the graphics side of things, and I'm sure will be invaluable going forward.

I've started shaping up my code to work with how the Unity simulation works, in preparation for porting it over. Characters no longer look for other free characters to start interactions with, but wander from (x,y) location to (x,y) location, randomly generated on a predefined grid (room, playing field, whatever you want to call it - this will be defined in the world .txt file starting soon). When a player takes a turn to look for a free interaction partner, they check only with the character closest to them. If the character is busy, they continue to wander. If not, they stop and talk. Once they reach a selected point, a new one is generated for them to wander to. I chose this wandering implementation to coincide with the Unity file I set up with Aline, where a character needs a set point to walk to passed into it.

At some point I'm going to have to address user functionality. It's looking like, if I work over my vacation, I might be able to enter next semester having a very basic "story generator" implemented using Unity. If that's the case, based on a conversation I had with Norm and Aline at the "Beta" review, I might shift gears and try to actually apply this generator to something by implementing a Unity based mini-game, something like a detective story where the murder/murderer/circumstances are different every time.

Back Where We Were

So last week I presented my "Beta" (only not really, because the majority of my work will be done next semester). There's a lot that's happened since the last time, I suddenly realize. I think I forgot to do a blog the week of the beta, but we'll rectify that now.

I'm back where I was in terms of the code, which is to say I have a functioning text based simulation that generates randomized interactions for characters for a given number of turns. It's radically different in that the construction of the world is done entirely outside of the code in .txt files of a format I created myself (and outlined in past blog posts). Here's an example of a simple simulation world structure:

emotions
3
love
hate
boredom

actions
3
kill.txt
converse.txt
search.txt

characters
3
Bob
m
random

end


A world file contains names of emotions, names of text files containing actions, and then the number of characters. Characters can be explicitly defined using gender and name. If after a certain number of defined characters the person building the world would rather just randomize them, they can put in "random" to randomly generate characters until the number they requested has been reached.

Here's an example of a simple action file:

converse
1
talks to
1
boredom
30
.05
.05
partner
end

The action file has the name of the action, the "Action Importance Value" I discussed in an earlier post (important for storytelling), a text phrase for implementation of the action (to be replaced with a file linking to a specific animation to play in a fully implemented solution - since I won't be generating these animations, I'll probably just leave them with text expressions). Next it lists all emotions relevant to the action, first by name, then by what the ideal value is for implementation of this action (the closer to the ideal value the emotional state of the character, the more likely they will select that action), then how much that value should be increased by for the character and for the interaction partner. Finally, there is a list of specific commands (partner/solo,samesex/oppositesex,kill,suicide,stop) that can be used to specify when the action is used and what built in commands (like killing) does it cause when it is implemented.


Below is a "story" generated using just three or four actions and emotions. Whereas adding new emotions and actions in the previous implementation could take hours, now adding a new one of either takes a matter of minutes, and doesn't require the code to recompile. Ignore the "0,0" printed between every turn cycle... That was a test of something that will come up in a later post.