[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Scripting
Gregor Mueckl wrote:
> > I've written a real simple parser to translate a C subset into a very
> > simple bytecode - it's not especially fast - but it seems good enough
> > for my needs.
>
> That's the drawback: I don't know of any open implmentation of a
> bytecode interpreter that allows you to specify how many instructions it
> should execute from which script. So you would have to take it into your
> own hands - with all the problems involved in reinventing the wheel once
> again (I don't think that I have to go into detail here).
Mine is OpenSourced - but you'll have to extract it from the guts of
TuxAQFH. I should probably make a separate package out of it sometime.
> > The main problem (as far as I'm concerned) is that you kill any hope of
> > portability if you generate machine-code. That's why I use a simple
> > byte-code. It's slower - but not unacceptably so for the relatively
> > simple things I expect interpreted code to do in my games.
>
> Well... how many platforms do you want to support with your code? My
> guess is that at least 80-90% of the players will have Intel-compatible
> hardware, maybe even more. The rest is far from being an uniform
> environment: UNIX Workstations, Macs, PS(/2), etc.
I believe that portability is important. I don't want an x86 monopoly
any more than I want a Microsoft monopoly. I often run my code on other
CPU's though - so whilst 90% of people may not care, I'm one of the other
10% and when I'm the one writing the code - I get to choose!
I've done several projects on MIPS CPU's.
> > I don't anticipate interpreting thousands of lines of code per
> > frame for each script - I rather expect to execute just a few
> > dozen bytecodes for each one.
>
> Wouldn't it be better to revert to an event handler system then? If the
> scripts are that simple (I'm refering to your emamples below now) it
> could be far better to do it this way than letting your scripts loop
> within a virtual thread and thereby wasting time *every* frame instead
> of wasting time only when really needed.
They don't have to run every frame - they have a 'Wait until...' bytecode
that puts them on a list of processes that are stalled waiting to run.
> The overhead required to
> determine whether and / or which event handler should be called can be
> neglected in these examples.
>
> But again, your approach makes perfectly sense if at least some of your
> scripts are a *lot* more complex than in your examples.
That is indeed the case.
> OK. Two notes here:
>
> 1. It's OK to call compiled helper code in scripts (although that might
> depend on one's taste).
Absolutely - definitely - CRITICALLY!
The script is (in my way of thinking) just a convenient way to tie together
a bunch of pre-designed building blocks that are each written in C++.
> I believe, however, that the design of such
> helper code could become very difficult to get right. It should be
> lightweight but at the same time flexible enough to support different
> behaviour models, at least different enough so that scripting isn't lead
> ad absurdum, because if it's too specific to the creature you're
> designing the AI for you could easily have left out the interpreter
> entirely. It's difficult to ge this right.
Yes. But at least if the game programmer gets it right, life will be easy
for non-programmers such as the level designers and artists - the pre-built
modules will work and be efficient. All they should have to do is to plug
them together using the scripting language.
> 2. If you execute only a certain segment of the code in each game cycle
> you end up having yet another problem (it would be one for me if I ever
> took that approach in my current project): It's hard to write frame-rate
> independent scripting code, i.e. code that does calculations based on
> the elapsed time. Consider the following (pseudo-)code that could be in
> the AI of a racing simulation:
>
> int time, lasttime;
> Pos lastpos, pos; // the car's position
>
> while(some_condition) {
> lasttime=time;
> lastpos=pos;
> time=get_time_since_start();
> if(distance(lastpos,pos)/(time-lasttime)<desired_speed) {
> accelerate(current_acceleration()+1);
> } else {
> accelerator(current_acceleration()-1);
> }
> }
>
> Admittedly it would not be a good driver, but it shows up a problem when
> it is interrupted for too long. Asume it's execution is paused for some
> 10 msecs just after having fetched the time and the physics simulation
> of the game calculates another cycle. The result is that the calculated
> velocity of the car is out of date and it's likely that the script takes
> the wrong action when the car's speed is near desired_speed. This leads
> to a somewhat unstable driving behaviour with at worst somewhat random
> behaviour from time to time.
That code isn't right though. You shouldn't increase or decrease the
accelleration by the same amount regardless of the elapsed time - that's
why this code is unstable.
But at any rate, I'm not suggesting that you execute a fixed number
of byte-codes per frame. Instead there should be some kind of 'wait until...'
command built into the scripting language that would tell the byte-code
execution unit when to cease executing - and what the conditions are to
restart it.
In this case, one might toss in a line inside the 'while' loop that says:
wait_until ( ELAPSED_TIME_AT_LEAST, 0.1 seconds ) ;
----------------------------- Steve Baker -------------------------------
Mail : <sjbaker1@airmail.net> WorkMail: <sjbaker@link.com>
URLs : http://www.sjbaker.org
http://plib.sf.net http://tuxaqfh.sf.net http://tuxkart.sf.net
http://prettypoly.sf.net http://freeglut.sf.net
http://toobular.sf.net http://lodestone.sf.net