Sequencer code for JohnsonBot AI Systems
Maybe you want your bot or submissive controller to carry out a *sequence* of actions in response to a particular simulus. Patrol a region, or check on a bunch of babies or pets, whatever.
One way to do that is with a series of SRDs linked by goto commands. There is a demonstration of this approach in the ai notecard, responding to the stimulus "count to three". However, the goto approach is subject to a few issues - one is that it is slightly tedious to write - you need to keep track of where the gotos are going to - and a second is that the ai system can be "distracted" by additional incoming stimuli that can interfere with the goto execution (just like a real brain).
You can easily add on a little bit of code that will add a new "sequencing" feature to the AI system that will make programming sequences easier and will be undistractable.
To add this, add a New Script to the ai prim, and rename the script "seq". Then paste into it the following code:
integer SEQ;
float TICK = 5; // tick rate of sequence clock
integer SEQON = FALSE;
key SPKR; // speakername uuid of person triggering the sequence
default
{ state_entry()
{ llSetTimerEvent(0.);
}
link_message(integer l, integer n, string t, key id)
{ t = llStringTrim(t,STRING_TRIM);
if(n == -2000 && t == "seqclear")
{ llOwnerSay("seq clear");
}
if(n == -2000 && t == "seqoff")
{ llOwnerSay("seq off");
SEQON = FALSE;
}
else if(n == -2000 && t == "seqon")
{ llOwnerSay("seq on");
SEQON = TRUE;
}
else if(n == -2000 && SEQON == TRUE && llSubStringIndex(t,"seqstart") == 0)
{ SPKR = id;
SEQ = (integer)llGetSubString(t,8,-1);
if(SEQ < 0 || SEQ > 999) SEQ = 0;
state seq;
}
}
}
state seq
{ state_entry()
{ llSetTimerEvent(TICK);
}
timer()
{ if(SEQON)
{ string cmd = "%seq"+llGetSubString((string)(1000000+SEQ),-3,-1);
llMessageLinked(LINK_THIS,-5235,cmd,SPKR);
// llOwnerSay(cmd);
if(SEQ > 1000)
{ state default;
}
SEQ = SEQ + 1;
return;
}
}
link_message(integer l, integer n, string t, key id)
{ t = llStringTrim(t,STRING_TRIM);
if(n == -2000 && llStringTrim(t,STRING_TRIM) == "seqend")
{ state finish;
}
else if(n == -2000 && t == "seqclear")
{ llOwnerSay("seq clear");
state default;
}
else if(n == -2000 && llSubStringIndex(t,"seqjump") == 0)
{ integer i = (integer)llGetSubString(t,11,-1);
if(i > 0 && i < 1000) SEQ = i;
}
}
}
state finish
{ state_entry()
{ llMessageLinked(LINK_THIS,-5235,"%seqfinish",SPKR);
SPKR = NULL_KEY;
state default;
}
}
This little script is similar to the "grabeseq" script you may have in your bot, but it is simpler and easier to program. Once you save this add the following lines to the ai notecard (could be near the bottom):
seq000|This is a test of....
seq001|...the seq system...
seq002|...and this is the end! By the way the seq was triggered by speakername!
seq003|ctrl seqend
seqfinish|Well this is really the end now!
# EXAMPLE SHOWN FOR TRIGGER PHRASE "testseq"
testseq|ctrl seqstart000
# TURNS ON SEQ SYSTEM
ctrl|seqon
Save everything and the AI system will reboot. Now - when the bot hears the word "testseq", that generates response "ctrl seqstart000" which starts up the sequence system at position 000. Then, the AI system will start triggering SRDs of the form seqNNN|RESPONSE where NNN will start with 000, then go to 001, then go to 002... and so on! The seq will stop when a "ctrl seqend" command is executed.
The numeric location of the start can be any three digit number from 000 to 999, so different stimuli can start different sequences. Just make sure you include a ctrl seqend command at the end of each sequence "program". A special "seqfinish" line is executed at the end of each sequence; it is not necessary to include that.
The script adds controller commands
seqstartNNN where NNN is the starting seqNNN "address", NNN = 000 to 999
seqend ends the currently running sequence
seqon turns on the sequence system
seqoff turns off the sequence system (default state after reboot, so use seqon if you want it on!)
seqjumpNNN "jumps" from the current step to step NNN
and you can easily add more commands! The time between "ticks" of the seq clock is up at the top (default 5 seconds) and easily changed. This is a nice demo of how you can add your own controller commands to my systems - it's easy!
Happy sequencing!

Comments
Post a Comment