It's been too long since I did one of these. Let's look at AI, since that's about where I've got to. The aim here is to let girls make intelligent, (or at least humanlike) decisions about what they're going to do.
Essentially, each girl gets a list of possible actions. Each action has a weight, which says how likely she is to do that relative to other activities. So, for instance if we have something like this
local girl, a_sleep, a_frig
--
-- create a test girl.
--
girl = Girl:new {
name = "Alice",
desc = "Alice is a test girl",
}
--
-- and give her a possible action
--
a_sleep = Action:new {
name = "sleep",
weight = 10
}
girl.add_action (a_sleep);
--
-- and another one
--
a_frig = Action:new {
name = "masturbate",
weight = 40
}
girl.add_action(a_frig)
Then we have a girl who is going to split her time between diddling herself and sleeping. The weights give us the ratio, so that's 10:40, which means she's going to spend 80% of her time jilling off. The advantage of doing it this way is that when we add a new action, we can easily adjust the percentages.
We can also test that it works as it's supposed to work. This throws an error if the percentages aren't as we expect.
assert_equal(20, a_sleep:percent())
assert_equal(80, a_frig:percent())
This is what most of the dev work I've done on this so far has been like: writing tests to make sure the code does what I think it does. The technique is called test driven development, and it's cool becuase it means I can make sure all my bits still work in six months time. It also means that there's a lot of examples of what everything is supposed to do, and how it's intended to be used. The tests are all in svn and live in Resources/Tests. The files are all called test_something.lua and you can run them from the command line with "lunit test_whatever.lua".
OK, back to the topic at hand:
Action weights go from -100 to 100. Negative values count as zero for weighting, but you can use them to make it harder to coerce a girl to do something, or to provide some initial resistance to training.
OK. So we can give her a set of priorities, and she'll choose randomly from them. But what happens if an option isn't available. We need to add conditions:
local girl, a_sleep, a_frig, a_whore
--
-- create a test girl.
--
girl = Girl:new {
name = "Betty",
desc = "Betty is a test girl, too",
}
--
-- actions...
--
a_sleep = Action:new { name = "sleep", weight = 10 }
a_frig = Action:new { name = "masturbate", weight = 40 }
girl.add_action(a_sleep);
girl.add_action(a_frig)
--
-- suppose customers are waiting?
--
local customers_waiting = true
a_whore = Action:new {
name = "whore",
weight = 50,
condition = function
return customers_waiting
end
}
girl.add_action(a_frig)
So we have a third condition that's only valid if some external test reports that there are customers waiting to get their balls drained. The external test here is similated by the customers_waiting variable which we can set and unset to test both conditions.
So with the customers_waiting flag set to true, we expect 10:40:50, which gives us 10% sleep, 40% frig and 50% whore. With it false, the numbers are 20:80:0
customers_waiting = true
assert_equal(10, a_sleep:percent())
assert_equal(40, a_frig:percent())
assert_equal(50, a_whore:percent())
customers_waiting = false
assert_equal(20, a_sleep:percent())
assert_equal(80, a_frig:percent())
assert_equal( 0, a_whore:percent())
OK, so we can get it so the girls recognise new possibilities as they emerge. We also need a way to influence probablilties. So we need modifiers, too.
a_sleep.add_modifier("tiredness", 10, "*")
So that adds a 10x multiplier to the sleep weighting. So the ratio is now 100:40:50 if there are customers giving her a 53% chance of going deciding to go to bed the next time she gets a decision point. If there are no customers needing attention, the ratio goes up to 100:40:0 whch gives 71%.
So why not just change the weight? Well, the idea is that the weights are part pf the girl's personality, and change slowly if at all. Modifiers however are dynamic and change is the circumstances change. For instance, the sleep modifier goes up over time until she finally gets her head down. Keep her awake for long enough and she won't want to do anything but sleep. And we can do the same with other drives. Like boredom. Or libido.
And because we can detect when a girl is badly in need of something, we can key events based on that. Like having a girl fall asleep in the middle of screwing client (some might enjoy that, of course). Or having one wreck the docking gantry because she was bored and horny and tried to bring herself off by rubbing up against the ship release button...
So: we have a flexible system that allows you to create a girl with preferences for behaviour, but which allows her to respond to changing circumstances, and for her behaviour to evolve over time. And I've got the test routine to prove that it works. There's a couple more tricks still up my sleeves, but I'll keep them for another time