Talk:04ED
Principles of streaming in SCM
Hi,
I just want to leave some words in here, because many SCM opcodes, like this one are named a bit confusing. I already recognized this some time ago and now I just wanted to note this somewhere :p. This also includes opcodes for models and sounds (0247, 03CF, ...). The names of those opcodes in Sanny Builder just as in Mission Builder (sascm.ini) are something like "load_...", but in general this leads us to the assumption that the opcodes do load something, but this is wrong! Also why do we need an opcode like 038B, if the data already is loaded (I will come to 038B later)? So in general every modern engine is based on parallel algorithms and streaming. The reason for this is simple: more high quality data gets bigger and bigger, of course! But if we would not load data parallel (in multiple threads) we would load let's say 1 file per frame to get stable framerates. But now take a 3 Mb file and you may calculate that even there loading may take some time. This is the reason why loading and rendering are seperated from each other. The renderer just asks the game (the streamer, to be correct) if an object has been loaded, if not it tells the streamer to load the object and continues, until it reaches the object again (usually with the next frame). But we do not want to know how the renderer works - I just told you this to make clear how the streamer get's his information. The streamer itself is nothing special. It consists out of 2 queues: the loader and the unloader queue. An object (or sound, or animation, or texture or whatever) get's added to this streamer, by telling him "load this data for me!". Now the data we want to have loaded is getting added to the loader queue. This is what the opcodes 0247, 03CF and 038F, just as some others - like the opcode for special actors and so on - do. So correctly they should be named "stream_object" or "stream_sound as". Now the game empties the queue from the beginning to the end. But if there are, let's say 200 objects in the queue this may take some time. Remember that this process runs parallel to our script! So for performance reasons it is recommend to use opcodes like 0248 to check if the object has been loaded then use it (by the way - 0248 is called "is_object available", which also is confusing - but in my eyes correct! - because most other opcodes checking the same for animations or textures are called "is_... loaded"). Now to prevent a checking rutine you may use 038B. It simply emptys the loader queue of the streamer by loading all it's data with one step and first returning, if it has finished. If you add 10 objects to the queue (0247) and then call 038B you may recognize a short jerk. This is because the game is waiting for the SCM thread to be synchronized, but it cannot be synchronized, if the thread is busy (btw this is the reason why we need to place 0001: wait 0 ms in loops). So to come back to the point: 038B should be called "stream_all_data" or "empty_loader_queue" or "stream_everything" (or something in this way - because you can also use this opcode for any streamable data like animations and textures). I haven't yet said anything against the name convention for the unloader opcodes, because it does not realy matter what they do. You do not need to check if an object has been unloaded (I cannot imagine any situation where I needed this). Of course they are only adding the object to the unloader queue - the opposite of the loader queue but usually this one is not as filled as the loader queue and the objects get unloaded pretty fast.
So anyway. I hope you may understand things better now. For me it would be better if the opcodes would be named this way by default - but this is not my decision. I do not want to criticize anyone. I just wanted to write somewhere "what's behind the scenes" and perhaps it helps some people to understand some basics of game design.