On Sun, 13 Apr 1997, Ling wrote:
:On Sat, 12 Apr 1997, Nathan Yospe wrote:
:
:> You mean, how does it decide to ask "you sure"? That's pretty simple.
:> There is a probability weight on prefered interpretation of a command,
:> with comparative risk being a crude product of action effectiveness and
:> consequences. This is part of the command interpreter, and is tied
:
:I would have thought that'll be fairly tough to calculate. Does it every
:ask 'You sure?' when it's obviously a low risk action?
I've had those show up, early in the modeling process, and undoubtably
there will be cases later, but the models cleared out on those with a
little tweaking. Since each potential action processor weights itself,
the confirmation request is simply a byproduct of the natural language
parsing process. Its not so much a risk assesment as a likelihood
assesment. The models (I have yet to port these skill objects into the
code, but the design allows easy porting of objects...) have used a large
number of factors, but they all boil down to the following:
- utility match
(do I have all the proper tools for the job, and if not, how close do my
substitutes come... IE. "You lift the shoe to hammer the nail, then pause,
noticing that its not exactly a proper hammer." >Hammer nail anyway.)
- clarity
(An ambiguous command will return a query as well... >ha m. usually gets
you a question, unless there is only one available command 'ha*' and one
potential target 'M*'.)
- unambiguity
(This is a sort of an imformation availabilty tracker. It is complex, but
its what keeps you from attacking a pair of glowing eyes in pitch
blackness without knowing what they belong to... IE. "Its rarely a good
idea to start a fight with something you cannot even see." >shoot eyes
anyway.)
- success probability
(This is based on the contemplation routines, which are a bit complex, but
essentially return a probability, based on _available_ information. This
does not take into account the unambiguity factor, which has already been
resolved)
- desirability/consequences
(This is what kicks in when you, say, type "eat grenade"... The verb "eat"
is going to kick back at you the desirability of eating anything inedible,
dangerous, or thoroughly repulsive. The grenade hits the inedible first,
then the dangerous. It would actually tell you that you broke your teeth
if you tried to chew the grenade after ignoring the report that the
grenade didn't look safe to chew, but eat would try swallow too, and there
is a species that could manage to swallow a grenade... I don't have
multiple warning support, though it could be coded specific to some new
verb... the inedibility warning would not catch the unsafe warning, which
means the fellow would get no warning about the fact taht the grenade was
primed to explode... looking at my code, there would be no such warning,
aside from the one that flashed up the moment the grenade was primed or
enttered the effective space of the character. As I said before, though,
with the NLP in place, the warnings followed with minimal effort.
:> :in reading through some of the old stuff. Just thought I'd bring the
:> :topic of game design back into the mailing list and pollute the optic
:> :fibres with my presence whilst I'm at it.
:>
:> Ah, now this is a fun debate. Personally, I like a system with feedback
:> between a list of attributes and a list of skills, all of which are
:
:Hmm.. I'll wait patiently for some development (like that Champion thing).
:Gonna be busy for the immediate future...
Hmm. I've always hated the numbered skill systems. Thus my verb/attribute
system.... the skill system I use, such as it is, is totally tied into the
NLP.
:Earlier, someone mentioned the possibility of the processor spending most
:of it's time time-slicing between multiple threads if there was a lot of
:connections. This number of threads business seems a lot like voodoo to
:me and being the unsure vulnerable type (while I'm in this mailing list
:watching all you masters chat), I won't mind some help. This is my model
:and it'll be great if someone commented (it's for a uniprocessor):
:
:Initial thread: Sets everything up, opens a socket, and waits to
: terminate.
:Signal thread: Sits in a sigwait() loop, handles signal for the entire
: process.
:Server thread: Waits for the next connection.
:Input Socket thread: Snoozes on select(), gets input from socket and
: plonks it in the input buffer, serves multiple sockets.
:Output Socket thread: Waken up whenever there's something in the output
: buffer.
:Input processing threads: Multiple threads which interpret the actual
: input, multiple meaning something like 1:10 ratio of
: threads to clients.
:Event processing threads: 3 threads sat in a pool (nicked from Lambert's
: I think).
:Area threads: The usual, I've not thought about this yet, it's gonna pose
: a problem.
:Compiler threads: Compiles I suppose...
:
:
:The main focus is on the socket threads. I can either use the above or I
:can: Combine the socket input and output threads by getting the signal
:handler to wait for SIGIO, use select() to figure out which client(s) have
:input pending and use semaphores to tell the appropriate threads, the
:socket threads would sit in a semaphore wait position (the semaphore can
:be released by the signal handler or be an event which has just popped
:something in the output buffer).
:
:The dilemma is: If I used select(), the socket threads will either have
:to use a loop to check input and output buffers or I can have input and
:output threads (the server thread can have SIGIO all to herself). If I
:depend on SIGIO, I will have to end up using select() anyway to figure out
:which socket it was and I may as well have one thread sleeping on
:select(), waking up the other threads when needed. What gets me is that
:if I used the later, won't there be an awfully high number of SIGIOs being
:sent out?
I'm as much of an infant here, in many ways... I think I might have a
problem if I don't start shuffling and pooling my threads. Not that that's
a problem, really... The OO structure that I wrapped my threads in is
nicely adaptable to the point that I could, quite easilly, assign a single
manager thread to move the sleeping threads into and out of a pool, rather
than letting them sleep.... I've got five sets of threads, but only three
types. The types are: socket IO (these could be split into I and O and
pooled, I think... or put into a polling loop, even...) management (pretty
much handles creation and destruction of all thread types, and a number of
similar things. Also adds and removes objects from the world.) and Event
manager (In three batches: global, area, and room... the latter two could
be pooled quite easilly, and should never exceed the number of players...)
that still leaves me with up to 2.2 times the number of players present...
which, with 200 players, hits a number closing on the 500 thread panic
mentioned earlier... I have at times slipped a nice little loop in in
place of the threads, tricking the process to switch to every wakeful
"thread"... the object model allows this without changing any code outside
of the SysThread.h and SysThread.cpp files. I suppose I could have a pool
of threads do a similar slight of hand act, but wouldn't that defeat the
whole point of the threads? I could easilly make the area threads take
over all of the room threads, and save on those... would require the area
to process all current events, then all room events (area already has
precidence) but I could use the trick of having an empty room event
dropped on the area queue when the room has an event to process in order
to make sure the area thread wakes up... Or tie the same thread directly
to all of the queues, so that any of them can schedule a wake for it...
The problem is, everything depends on these threads going to sleep and
waking on an externally scheduled wake signal... this is how I manage to
avoid concurency problems, as well.
__ _ __ _ _ , , , ,
/_ / / ) /_ /_) / ) /| /| / /\ First Light of a Nova Dawn
/ / / \ /_ /_) / \ /-|/ |/ /_/ Final Night of a World Gone
Nathan F. Yospe - University of Hawaii Dept of Physics - yospe@hawaii.edu