View Full Version : A Dynamic Array of a Dynamic Array of Strings...

22-07-2003, 08:29 PM
Ok, I'm sure by now a good few people have heard that I've been making this 2D 360<sup>o</sup> game/game engine, well unfortuantely, I will not be having any screenshots or previews of it until I can get a basic model completed(Not sure when this will be, I'm a pretty busy guy these days). So, this unfortunately won't be happening until then, sorry. However the name of the game engine is called SkyBlast. The game has not been named yet. The whole thing being called "Project SkyBlast".

However, here is my current issue with it. I have a script engine(made from scratch) that handles all of the missions that are run in the game. Basically the missions are your "levels", much like in most space simulators. It interprets code that is first parsed and turned into a series of strings dubbed 'symbols'. A single array of 'symbols' is called an 'instruction':

TInstruction = Array&#91;0 .. 1023&#93; of String;

Now obviously you have more than one instruction, right? So then I use another array to store these 'instructions' into the interpriter object it's self(run mainly durring initialization), 'triggers'(evaluates a specific condition and activates once met with a block of code), 'agents'(controls the actions of designated in-game objects) and 'objectives'(mission parameters and reactions on completing and/or failing them).

NOTE: Code blocks and triggers are stored as 1 'instruction'! This includes nested code blocks and triggers alike.

Now using a static array for this isn't all that bad, it's using it for my TInstruction object that hits me. I am limited to 1024 symbols per instruction. This is more than fine and dandy for a single instruction line, but what if I have a code block or series of nested triggers that go over 1024 symbols all together? It's a limitation I don't want.

:arrow: My problem is that when I make my TInstruction a dynamic array(I do use setlength properly and where required, of this I'm sure) I get all sorts of wierd errors in *other* data structures. And I cannot write data to my symbols.

:?: So, my question is: How do I fix this? Or, does anyone have any ideas as to the nature of this problem?

25-07-2003, 08:47 AM

i have run in to that problem millions of times and in the end i gave up using dynamic arrays, instead i know use TList which i find a lot easyier.
im not sure if it would be better or not memory wise, but it saves a lot of hassle :roll:

25-07-2003, 08:25 PM
True, TStringLists would in be a solution, however I'm not sure how much overhead and slowdown it would be to have each instruction line created and destroyed...

It is a good idea though, I'll probably give it a try.

07-08-2003, 04:31 PM
Could you give some more details?

I've never had problems with something like:

TArrayOfString = Array of String;

Inside other data structures.

Could you post some code fragments or something were you use it?

For your scripting, make sure you use you'r own stack and dont use recursion. That was you can implement pre-emptive multitasking in your scripting.

Remember: Cooperative multitasking is evil.

07-08-2003, 07:14 PM
Sorry for the question but, what do you call "Cooperative multitasking". Are you talking of some sort of multi-threading ? If it is, then I agree with the fact that it's Evil lol ^^

07-08-2003, 11:31 PM
This [changing other vars] sounds like your basic buffer overrun. Make sure that your arrays have the right number of elements and check for the usual suspects (off-by-ones and so on). Also, be aware of using procedures such as FillChar or Move, since they can be risky. Here's a quick example:

[background=#FFFFFF][comment=#0000FF][normal=#000000][number=#C00000][reserved=#000000][string=#00C000]procedure TForm1.Button1Click(Sender: TObject);
y: integer;
x: array of integer;
y := 23;
SetLength(x, 2);
FillChar(x, 8, 0);

ShowMessage(Format('addr1 is %x, addr2 is %x', [Integer(addr(x)), Integer(addr(y))]));
Notice that the value of y has changed from 23 to 0! This is because the FillChar is doing too much (going over x, which is a pointer, for 8 bytes -- i.e. 4 bytes for x, which is essentially a pointer, and 4 bytes for y). The wanted change there would be to use x[0] with the FillChar to get correct results. Be careful of similar problems with pointers.

Avatar: ggs is talking about two different approaches to multitasking by cooperative vs pre-emptive. The first one relies on each task to say "I've had enough", which the second one yanks control away from a task as required. As a result, the second (pre-emptive) is much preferred as it's more reliable. I believe that Windows 3.1 had co-operative multitasking, which meant that a poorly written app could hog the system at the expense of other tasks. In later Windows, the task should be forced to take a back seat as required.

08-08-2003, 04:38 AM
Sorry for the question but, what do you call "Cooperative multitasking". Are you talking of some sort of multi-threading ? If it is, then I agree with the fact that it's Evil lol ^^

Say you set up a scripting engine to run a batch of scripts each frame. Exactly which scripts get executed in what order isnt an issue here (That the scheduler's job).

With a Cooperative multitasking scripting engine, the script have to play nice and stop executing when they are done. Basicly the script runs to completion or when ever the script yields.

Thus if you only have a budget of a few milliseconds per frame for the scripts, having a script take 1 minute is going to make a serious difference to the game. And if the script gets stuck in an infinite loop...

With a Cooperative multitasking scripting engine, it doesnt matter how long the scripts take to execute. As with a cooperative multitasking scripting engine it executes a batch of scripts. But if a script doesnt run to completion, it timesout and the scripting engine kicks it out of the hotseat and lets some other script have a slice of time.

Also writing scripts for pre-emptive multitasking scriptign engines means you done have to care about biulding in logic to cope with doing the multitasking. To a script running in a preemptive enviroment, as far as it is consered, it is the one and only script running.

08-08-2003, 06:44 AM
Thanks a lot for the explaination !

Now I understand :)