BVM Questions
Blitz3D Forums/Blitz3D Programming/BVM Questions
| ||
Okay, I want to add BVM into the engine, properly. If this works, the author gets another license sale. I am using one script per entity. I want to load a script with an UpdateEntity() function, and pass the function the four-byte entity data structure to update that entity. file$="monster.script" module=BVM_LoadModule(file) If module=BVM_INVALID_MODULE RuntimeError "Error loading script "+Quote(file)+"." context=BVM_CreateContext() functionpointer=BVM_FindEntryPoint(context,module,"UpdateEntity") BVM_SelectContext(context) BVM_SelectEntryPoint(functionpointer) BVM_Invoke_Blitz3D() Questions: -How do I pass a variable to the UpdateEntity() function? (The entity!) -Can I have more than one function called "UpdateEntity" in the same context, or do I have to call each entity's update routine a different name? -Is there any inherit overhead in calling a function? Should I call one UpdateMonsters() function, or is it okay to call each UpdateMonster() function individually? |
| ||
I'm only (very recently) familiar enough with BVM (though I like it) to mention that you'll need to pop the stack to prevent possible stack overflow, since every Invoke returns a value (this isn't really clear in the docs): http://koriolis.free.fr/forum/viewtopic.php?t=57 As for multiple UpdateEntities per context, you might find http://koriolis.free.fr/forum/viewtopic.php?t=55 helpful. Man, I feel that I've only yet scratched the surface ( http://koriolis.free.fr/forum/viewtopic.php?t=49 ), but I love what the potential of BVM seems to be! |
| ||
WendellM says it: you have to "pop". Yes, BVM is cool and therefore I implemented it in Wobbles. |
| ||
FunctionPoint would be the entrypoint(like main() in a standard C program). You would "Push" the entity that UpdateEntity() needs, then call it(if I recall correctly). I never used BVM like that, I coded all the actual game entities and structure in script itself. I was using it on top of alot of systems, like physics, effects, and general management. So all game code went in scripts, the more processor intensive code went in hardcode. |
| ||
How do I pass a variable to the UpdateEntity() function? (The entity!) I have to admit this explanation really lacks in the "basics" part of the docs (it's explained in the tutorial though). The recent questions I was asked gave me good hints about what needs improvments in the docs, and it *will* be improved.Passing parameters is done by pushing them on the context stack. For that use BVM_PushInt,BVM_PushFloat and BVM_PushString. By example say your function is: Function SomeFunc$(param1%, param2#) ... End Function All you have to do in your main program is to push the parameters, invoke the function, then pop the return value. BVM_PushInt(20) ; the value for param1 (it's an integer, so use BVM_PushInt) BVM_PushFloat(1.23) ; the value for param2 (it's a float, so use BVM_PushFloat) BVM_SelectEntryPoint(hEP_SomeFunc) BVM_Invoke_MYCOMMANDSET() returnValue$ = BVM_PopString() ; the return value (it's a string, so use BVM_PopString). ; If we don't need the return value than we just do "BVM_PopString()" and don't ; store the result anywhere (but popping it would *still* be required). Can I have more than one function called "UpdateEntity" in the same context, or do I have to call each entity's update routine a different name? Each script is a separate program, and thus the names you use in one script doesn't interfer in the other ones. Using the same function name in different scripts is actually a common and good usage, if you're planning to use one script per entity.So you can have each script have its very own "UpdateEntity" function, no problem at all. Is there any inherit overhead in calling a function? Should I call one UpdateMonsters() function, or is it okay to call each UpdateMonster() function individually? I don't think you can find any significant speed difference between both solutions, so choose the one that best fits your needs. |
| ||
If I have a script function that does not return a value, do I need to pop anything? Can I just do this: BVM_PushInt(entity); entity structure to update BVM_SelectEntryPoint(pointer): update function pointer BVM_Invoke_Blitz3D();update the entity It seems that the stack might be getting screwed up. After about 30 seconds, it says the entity does not exist when I try to position it, yet the debugline I added in the script, just before that command, lists the same entity it has been running the whole time. |
| ||
No, as stated in the thread WendellM pointed you at, you *always* have to pop something. To restate what I've said in this thread: There must always be a pop after BVM_Invoke_<CMDSET> Most important, a function for which you declared no return value actually returns an int (like in plain blitz), so in this case you have to put BVM_PopInt() after the invokation. Note: this also stands for the main program, which is nothing else than a function taking no parameters and returning an integer). The fact that any function actually returns a value is really a blitz thing, it's not a specificity of BVM: In blitz you can do If you fail to pop the return value you will eventually face a stack overflow. Because the default return type is integer, you have to do a BVM_PopInt() after the invokation. And as you really don't need any return value, just pop it and don't store the value anywhere.: Function Func1() ; I have not declared the return type, but it's an integer by default ; Here's the proof: I return the string "7 little dwarfs", ; it will get automatically converted to an integer (-> 7) Return "7 little dwarfs" End Function Function Func2() ; I have not declared the return type, but it's an integer by default ; In addition I'm returning nothing (will return the default value, 0 End Function Print Func1() Print Func2() Try this in Blitz, this will print 7 and 0. As you see Func1 and Func2 *do* return a value. Simply put, add BVM_PopInt()and that's all. In BVM 2 the stack overflow error will get properly reported rather than causing a bug. |
| ||
Sick, it works! |
| ||
That's great. Days worth of conversation and Halo gets it all within a few hours. =] |
| ||
BVM is the bomb! |
| ||
BVM is the best scripting engine I have seen in ages :) |
| ||
Okay, I almost have it all tested, but I am running into a bad problem. I call an entity update function every loop for several minutes, and it works fine. Then it just stops being able to select the entry pointer. What causes this? How can I bug test it? |
| ||
For starters I would count the nr of updates that is made before it stops to see if it's always the same or if it's random. |
| ||
Are you sure you're calling BVM_PopInt() or whichever data type the function at your selected entry point is returning? I've found the only way to test it is to use large quantities of debuglogs in my scripts. updatePoint=BVM_FindEntryPoint(script_context,module_handle,"updateworld") debuglog "updateWorld entry point: "+updatePoint |
| ||
Generally I create one global context at the beginning of my game, then map all my loaded modules to that. I'm therefore never calling selectContext ever again. |
| ||
Me too. I said SelectEntryPoint. I have verified that the entrypointer is the same value that is initially loaded, and that it is succesffully called for about five minutes, and then it just keeps failing after a certain point. I only use one context for all scripts. |
| ||
I tested to see when it failed, by incrementing a variable each time the script is called. I ran it three times, and it failed on the 17,582th, 16,904th, and 17,868th loops. :| |
| ||
I call an entity update function every loop for several minutes, and it works fine. Then it just stops being able to select the entry pointer. What causes this Most probably the 10 minutes timeout of the trial version. This time limit is the only limitation of the trial version, everything else being exactly as in the full version, so that you can properly test all you that want.After that limit is reached some key functions of BVM are locked. So if it works all fine for 10 minutes and suddenly stops, then it's all normal. I should certainly have put a messagebox or something to make it obvious. |
| ||
ARGHHHHH!!! I suspected this, but no one said that there was a time limit, and I didn't see anything in the docs about it. Oh well, problem solved. Now that I know the system works, I am off to get my credit card. Thanks for the help with this. You might check out PayPal for orders. They take the same fee, but you can withdraw your money instantly. ShareIt would not accept my hotmail address, and it failed the first time I tried my gamecreators address, then worked thr 2nd time. :| |
| ||
and I didn't see anything in the docs about it True. It's said in the little readme at the end of the installation though. But I now believe noone actually reads these readmes, so a message box after the timeout is probably a good idea. |
| ||
If it's any concellation, I read it, K =] But I bought it before I actually used it so it didn't matter =] BTW, that patched dll you sent me, would that be likely to have been a patched demo or patched proper dll? Maybe I should revert back to the old one and test it... |
| ||
would that be likely to have been a patched demo Shouldn't be, I compiled it with the options set up for the full version. I'll check that anyway, and let you know otherwise.[EDIT]Checked, it's ok[/EDIT] |
| ||
Then, shoot. I have no idea what's going wrong now... |