[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Scripting

Steve Baker wrote:

> 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.

Well... I'll have a look at this one. I would have preferred an 
object-oriented language, but the overhead involved probably doesn't pay 
out with better code structure within the scripts.

>>>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!

True. The x86 hardware is just bloated. I don't have the need to execute 
binary code that has been created ten to fiveteen years ago. But every 
single cutting-edge Intel-compatible PC can run these binaries natively, 
although modern software no longer needed it, would the boot process be 
in protected mode already.

Correctly written code doesn't depend on platform anyway. So 
platform-dependency is mostly a curse of commercial software which is 
only available in binary form. But that's pretty much OT, isn't it?

 > I've done several projects on MIPS CPU's.


The platform one uses mostly depends on taste - and money :).

>>>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.

So you actually poll for events. As far as the engine is concerned it's 
similar to event handlers in implementation, but it removes the need for 
saving states within the script. Neat trick, but you'll have to take 
care that the script returns often and regularly enough, which is a 
minor concern actually (even OSes have depended on this and it has 
worked out somehow :).

>>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've thought about going that way, too, but never seriously enough.

>>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.

But I personally feal that I would be one of those who won't get this 
right. I just don't have a clue about how such an interface should look 
like. The major problem is to make it flexible, but yet it's a 
concatenation of algorithms with different arguments for each one of 
them, which will need to be converted and passed on. With that the ease 
of use might vanish.

>>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 ) ;

Yes, that's probably the way to do it. I'm already wondering about implementing the parser for such a language. Unfortunately, I've failed at similar things before:(.


* Gregor Mueckl                 GregorMueckl@gmx.de *
*                                                   *
* The ChallengeOS project:                          *
* http://challengeos.sourceforge.net                *
* Math problems?                                    *
* Call 1-800-[(10x)(13i)^2]-[sin(xy)/2.362x].       *