Per wrote:aubergine wrote:... Both these only run when game is first started, and neither is run when it is loaded.
Oh, in that case yes - we do need that extra event otherwise we can't do stuff on savegame load.
Per wrote:aubergine wrote:Maybe I don't understand the "snapshot" nature of game objects - I would have assumed that there would be properties of the JS object that "behind the scenes" call getters/setters in WZ whenever they are called?
No, they don't.
[/quote]
So, if I've got this straight, something like this is happening...
In C++ land:
- Code: Select all
create an array
loop through each matching droid {
create an object
for each property of a droid {
object[property] = droid[property] // this will be calling getter func on each property, in addition to making a copy of the value!
}
}
expose array to javascript
So you're basically doubling the RAM usage of the entire list as you've just made a clone of it for maybe a single function in JS to use. And because people are in the habit of using enum<Whatever>() each time they need a list (because old list will likely be out of date = people won't bother caching it in JS), you're going to be doing that over and over and over again?
Look, would it be better to take a different approach like this:
- Code: Select all
create an array
loop through each matching droid {
push droid.id on to array
}
expose array to javascript via a wrapper/helper function
In C++ land you'd have two functions (or maybe several) that would facilitate getting/setting of properties as applicable. The wrapper/helper in JS land would then interface with the C++ getter/setter functions as applicable. Using inheritance and proper properties (eg. defined using Object.setProperty) you'd get a beautiful environment JS side. Examples:
* console(typeof someDroidObj) // DroidObject
* (someDroidObj instanceof BaseObject) // true
* someDroidObj.isVTOL() // calls isVTOL(someDroidObj)
Thanks to inheritance the instantiation of objects has practically zero overhead, regardless of number of properties due to prototype chain inheritance. And, because property values are only accessed on an as-needed basis, that gives performance and RAM-consumption benefits too. Furthermore, because the JS properties will be calling the exposed C++ getter/setter functions directly, there's practically zero extra overhead in the overall chain from requesting a property value to returning it compared to the current approach being used (and the current approach is doing all that work for every property of every item regardless of whether it will be used or not).
And, finally, and this is the big one IMHO, the object properties in JS will always get the latest values when accessed - so all this stuff can be cached in JS land. Obviously a simple check would need to be made to ensure the droid/struct/feature still exists, but that is fairly trivial to implement on the JS side (or simply catch exceptions in JS if an error is thrown in C++).
This could go even further, the lists (of ids) themselves could be made fully dynamic too! So when you iterate through a list, it already knows what "filters" the list should have, the JS list wrapper asks C++ for a new list with those filters and as far as the JS developer is concerned the list is always up-to-date and the objects in it are also always up-to-date! I can write a custom Array class (that for all intents and purposes is *identical* to a normal JS Array) which would transparently handle the calls to C++ functions, etc.
With my OOP inheritance stuff, I could then easily create subsequent classes which are more specialised (eg. droidList, structureList, featureList, etc).
Oh, and dare I mention that all these things could then be much more easily persisted - for example, uneval(someList), someList.toSource() or someList.valueOf() (which is what I assume your persistence layer does on global vars during savegame) would be returning a simple array of primitive numbers = nothing breaks in save/load cycle!
I really think there's a massive opportunity here to radically improve the scripting engine from script-developer perspective, and such a radical change would be better to do sooner rather than later. What's more, the existing JS API can be retained - we'd simply be adding some new global functions to it to allow the next-generation approach. I'm more than willing (in fact, practically begging!) to write the JS wrapper/helpers. Please give it consideration - it would be astonishing API with this sort of stuff.
Per wrote:aubergine wrote:surely I could just add a property to the game object, eg. someDroid.foo = {...}?
You can, and I've used that to some effect already, but the moment your copy of the game object goes out of scope, then that property is gone.
My wrapper/helper function idea above would completely solve that issue IMHO.
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO