Memory management in AGS

Started by darkseed, Sun 27/05/2007 06:42:44

Previous topic - Next topic

darkseed

I'd like to know how game entities (rooms, objects, hotspots, regions, characters, sprites) are handled inside AGS. There is a array of each of size AGS_MAX_ENTITY (eg AGS_MAX_CHARACTERS) with the structures or pointers to the structures that are alloc'ed when needed? If that's the case, the engine uses some a simple garbage collector?

For me, room stuff (background, hotspots, regions) is a perfect candidate to be only alloc'ed when needed. Is that how it works?

If they aren't, is there anything that is alloc'ed in execution time besides DynamicSprite?

Regards

Pumaman

All data for global stuff (characters, views, etc) is loaded into memory at startup and kept in memory permanently.

All data for room stuff (objects, hotspots, etc) is loaded when the player enters that room, and discarded when the room changes.

Sprites are handled by a sprite cache which dynamically loads and unloads them as required, maintaining the most commonly used ones in memory. The size of this memory cache is configurable under the Advanced options in the game setup program.

Any items created dynamically in the script (eg. DynamicSprites, Strings, etc) are handled by a simple garbage collector system, that works in a similar way to the way that COM and VB6 handle object creation and destruction.

I'm interested to know the reason for your question?

darkseed

#2
I'm thinking in porting a adventure game project half-done in another engine to AGS. Right now, I'm evaluating how AGS would support the game and efficient memory management is one of the requisites. If we conclude AGS isn't a good platform for the game, probably we'll have to develop a custom adventure engine and your guidelines would be very useful anyway.

How are your scripting languages (dialog/game scripts) implemented, if I may ask? I suppose you compile the script to bytecodes and then interpret it in runtime. You built the entire compiler (lexer, parser and bytecode generator) or used some tool such as Bison (parser creator)?

The interpreter is a VM with a virtual stack that call the proper opcode handler through a table of function pointers? How does the multi-threaded scripting environment (global/room/no-block threads) work? You have 3 virtual stacks and the interpreter manages them or the code really is multi-threaded?

The binding between interpreter and C++ was hand-made or some tool was used for it?

Thanks for the info, CJ.

Pumaman

The scripting language is something I wrote from scratch; I looked at the available tools but none of them seemed to work the way I wanted (in particular I needed something that would enable me to handle the save/load game process automatically, without the user having to write any code to deal with saving and restoring variables).

Yes, the AGS editor compiles the script into bytecode, which the engine then interprets.

In terms of the interpreter it's quite simple really, yes each "thread" has its own seperate stack, registers, etc. But it's not actually multi-threaded, since only one script is actually running at a time (the others are either not running at all, or blocked waiting for a function call to return).
At the moment it's not re-entrant on the same thread which is the reason for a couple of limitations in AGS and the reason why there are three "threads". (ie. if the script calls into a native code function in the engine, that function can't then call back into the script. It must return before the script can continue).

QuoteThe binding between interpreter and C++ was hand-made or some tool was used for it?

When the script calls into the engine, the compiler writes a special "callext" opcode, which the interpreter then uses to know that it has to map the address to a native code function pointer and call it. There's nothing particularly complicated involved.

If you look at the AGS Plugin API you can see how the interface between the script and the code works.

SMF spam blocked by CleanTalk