"The only way to access the class’ data is through access (getter/setter) functions."
So only methods are accessible, and you may do any checks in accessors.
If you pass managed reference (smart pointer instance) to python side you just couldn’t delete the object until reference will be GCed at python side. But if you f.e. delete object from adv. map it will be in fact dead pointer though object will not be freed. Notification mechanism will be needed anyway, smart pointers will not help in this case.
I wonder why do you ever want to access object directly. All game actions are handled by long path of Callback mechanism, so all object functions / properties are useless from scripter’s perspective. Therefore we need script functions that call engine functions.
In my understanding, object wrappers are only references that are guaranted to point at some object and define it precisely, but don’t allow any direct actions on the object itself. They still need to be passed to function.
I can see one use of direct access, however. It is when objects are created by mod and before they are actually added to engine. Or, even worse, modding by inheritance - is that ever possible?
And we don’t care what type the wrapper actually is.
EDIT: An solution to above issue.
As long as object is script-local, scripter (or even player) is free to access every field and method in it by wrapper, just for convenience. However, when the object is added to game engine (becomes potentially effective), the wrapper is locked and the objects pointed by it becomes inaccessible. I think it’s conceptually simple and possible to achieve.
I had a nice and long post explaining that great misunderstanding that arose here, but it got deleted by accident. So shortly:
We can make template Wrapper that wraps all game objects, providing:
smart pointer-like GC
constrained access to fields/methods using pointers to fields, pointers to members, variadic templates and r-val refs
setters/getters for boost::python class properties that are not just setting/getting, but checking constraints and forming appropriate netPacks/callback calls.
Is there any problem with this solution? It provides elegant script syntax and maximal safety.
I see no need in another template, to use boost::python we anyway have to define wrapper templates for every exported class and setters/getters should be defined in engine classes itself.
Cheatproof multiplayer, if not scripts. Anyway, I don’t see why you insist on procedural style API for scripts when OO-style API is relatively easily achievable.
Not necessarily. Non-cheatproof mode can offer full access to engine for client side scripts (ensuring higher responsiveness of complicated GUI/game mechanics scripts).
There should be a preferred style and your last example was procedural – if you have nothing against OO style API being preferred then it’s ok.
It will encourage singleplayer-only mods even if they don’t have any mechanics that require SP mode. (modder does not needs to care about server-client interaction)
Lag on localhost is almost zero so delay for SP games won’t be notable. Biggest “lag” will be player - human can’t react as fast as program.
And in some cases (like hero movement) lag can be eliminated completely if client won’t wait for reply from server.
This is how most of online games work: client starts action immediately but in rare case of negative reply from server client should cancel that action.
Yes, it will. Tournament players are usually very conservative, so it doesn’t matter IMO.
Yes, but you can’t transfer mouse position in real time to support whole ERM. Full access to game mechanics is not designed to reduce lag (which they don’t, as game state is still synced by server) – it is meant to support ERM scripts using mouse positions.
I wish we have them before mod support. Microsoft, give me variadic templates and initializer lists, and I’ll be a happy man! Shamefully VC11 brings support for neither.
They are conservative for the reason. ERM doesn’t play well with MP mode, because it mixes GUI-dependant and gamestate-dependant stuff. We should not repeat that mistake. I believe that if high quality client-side-only script were available, tournament players would use them. Everyone wants “Recruit All” button.
If a script doesn’t need privileged access to the game data, it shouldn’t have that access at all. That way:
a) script is accessible in cheat-proof mode
b) script will be as reactive as the hard-coded GUI (no additional need to communicate with server)
c) it’ll be difficult for the script to make sth wrong and damage the game.
I don’t say that we can’t have privileged client-side scripts, however they should be avoided if possible.
Well, we once did predicting artifact movement results because there was a visible lag between click and updating hero parameters (#155). Hero was modified locally, without awaiting response from server. It resulted in endless avalanche of bugs and despite numerous fixes there were still issues. And there is no telling to what would’ve happened if the artifact transfer went wrong and client were to reverse its effects. Eventually I had to rewrite the whole thing, so things are now in sync (bonus system is used to display hypothetical “hero bonuses without this artifact”).
After that experience I strongly believe that we should just accept the lag. It’s a turn based strategy, so delays in MP are not a disaster. Besides, when having server-side scripts, predicting the action result would become more and more difficult.
I’m not sure but it may be enough just to report clicks with their coordinates and some info on GUI. (!!CM can be used only after !?CM trigger).
However handling clicks on the server side would cause very unpleasant lags, since ERM can decide whether to handle that particular click or let the GUI do this. So client would have to wait after every time for server to tell, whether it should be handled.
Nah, I don’t see how ERM can be reasonably supported and work smoothly in MP mode.
Only by splitting script to client and server parts, and this will not support all existing ERM scripts in MP mode. This has been already discussed some time ago.
Mouse position is definitely client-only info. For example position (x=700, y=300) can be both town\hero lists (800x600 res) or some tile on adventure map (any higher resolution)
Join the dark side - we have cookies gcc!
In some places this can be quite notable: lag in hero movement can be noticed even now - there is small delay after hero moves to one tile and before he starts moving to next one.
This breaks nice & smooth hero movement from H3.
Maybe split events into client events and server events?
If the step event weren’t “the same event” but a pair of asynchromous client event and server event - it would be fixed - but this approach needs desync guardian (So while it works properly the lag is reduced so non noticeable - but if disaster detected - there would be single bigger lag on mentioned tile (eg. !?HM fired or local event) - which is mostly not noticeable because mostly such event show blocking dialog)
10.2 For event FOO initiated by player or client side script not related to UI:
OnBeforeFoo executed on client side (event may be canceled at this point).
Script may alter client request
Client sends request to server.
OnBeforeFoo executed on server side (event may be canceled at this point).
Script may alter client request.
server prepares data structures for response packet
request become read-only, response data is writable.
If OnFoo is subscribed server executed it passing a flag of standard processing
server side script can alter behavior in any way and also executes engine`s standard processing callback (only first callback will be executed).
Server processes predefined mechanics if no trigger subscribed or callback was not executed and flag was not cleared.
server alters GameState and sends response to client.
response become read only.
OnAfterFoo trigger executes on server side
additional packet sends to client. informing that serverside processing ends.
OnAfterFoo trigger executes on client side.
If event was canceled at server side 4) & 5) will be skipped. On After triggers executed with canceled flag in response data but may react on changing request in “before” triggers.
10.2 For event FOO initiated by player related to UI:
OnBeforeFoo executed on client side (event may be canceled at this point).
OnAfterFoo trigger executes on client side
10.3 For event FOO initiated by engine or server side script:
OnBeforeFoo executed on server side (event may be canceled at this point).
server prepares data structures for response packet (if applicable)
If OnFoo is subscribed server executed it passing a flag of standard processing
server side script can alter behavior in any way and also executes engine`s standard processing callback (only first callback will be executed).
Server processes predefined mechanics if no trigger subscribed or callback was not executed and flag was not cleared.
server alters GameState and sends response to client.
OnAfterFoo trigger executes on server side
10.4 Some remarks
Nor serverside nor clientside scripts have direct write access to GameState.
The only way of changing smth is triggering events
F.e. altering monster stats is an event too, such receivers initiates event in fact.
MA event should probably have only OnAfterXXX triggers allowing other scripts and UI to react on change. (Scripts might have private structures with data dependent on stats and UI might have opened window with smth related)
Client side script in cheat-proof mode can initiate only player-accessible action and any action in non cheat-proof mode (only ERM scripts). Server side scripts can initiate any event.
I think this page can be fairly useful in Lua vs Python debate.
About the compression, how about lz4? It’s extremely fast with small memory footprint and compresses OK.
Abstracting away from mod implementation, I would like to discuss a more specific problem.
Imagine we have a bunch of mods that add multiple creatures to the game. These mods can be turned on and off. Where should be the data loaded or stored?
We can load all the data at application launch, but then it may take up a ton of RAM. It’s not unlikely that eventually people will create gigabytes of mods. Of course not all of these mods will be used at once. So maybe another solution would be to load resources only for mods actually used at game start?
But then again. If we, for example, try to check 3 different autosaves, reloading lots of graphics every time may be a waste of time.
What does new filesystem API offer here?
Another problem is functionality which allows to load and change the list of objects avaliable in game.
Currently, CreatureHandler stores all the info about creatures. Craeture animation is handled by new APi, which is good. But what with creature sound, for example? Creature portraits, small icons, any other related media. What happens when we decide, let’s say, to remove creature with id = 100 from the game?
My proposal for now is to design (and write) a mechanism which could allow freely add or remove game objects to handlers, possibly keeping related media linked properly. This is a task independent of actual implementation of how the creatures will be possible to add or remove. And I’m willing to do the task
Third issue, which is reported over and over, is dependency VCMI of WoG. I see that VCMI uses WoG config and media files, but sooner or later these should be split. Ie. VCMI will need only Sod / complete install, while WoG will become separate package. Since WoG is dead, we could repack and redistribute these files, but then there is an issue of handling separate resources and loading / parsing their files.
Unlikely. Start game and check amount of memory used by server - it is just 10 Mb. Everything else (size of client -> 100 Mb) is graphics. And graphics must be only loaded on request. Currently only pregame\adventure map load too much data. And I’m going to fix this at some point.
I’ve been thinking about this. Easiest solution about this is to cache some amount of data during game so closing and opening windows (e.g. town screen) won’t cause a lot of reloading. For map restart we may need to increase cache limit or stop unloading for some time.
Yeah. I still don’t know where to place this data - our handlers as well as classes in ObjectHandler should not store any of these - they are only for mechanics-related info.
Best solution I found so far is to store URI’s to all these data in class like current Graphics. And then load it like this:
graphics->getImage(“creature-portait”, creatureID);
Internal storage can be for example map<string, map<int, URI>>
This may be generalized to store any type of data and return only URI’s instead of images instead of separate handler per type
And I’m willing to do any client-related parts of this task
Haven’t we decided that types can’t be removed? Anyway replacing entry to deleted creature with null is probably easiest solution - shifting all creatures with ID’s 100+ will be quite complex. Or at least mark them as deleted to avoid crashes.
It looks that you’re faster than me, Warmonger
My plan was something like this:
Improve H3 configuration system: instead of parsing files with loadToIt create parser that will create 2d array of strings that will be used further.
Improve VCMI configuration system: instead of separating data by destination handler store all creature-related data in one file, all town-related data in another single file, etc. To do this we’ll have to merge creatures.json with cr_sounds, replace 5-10 parts of town configuration with 1 per faction (will be too big for one file I think)
Maybe even write hota.json
Write code that will use H3 2d string array + vcmi json as input and will register all available objects.
This will make registering object atomic. For example if somebody will add entry in H3 texts without tweaking our files this most likely will kill VCMI. Checking if all data is valid before inserting it into creatures\heroes\etc handlers should be more reliable.
I agree. Not a huge supporter of WoG myself. But this will have to wait until data loading issue is solved.
Or we can just use Era as base - it already has nicely repacked WoG included
I already use such configuration but it still has several issues. (like music\sounds\video loading). But all texts and graphics already works perfectly for me. And mire important - vcmi is still compatible with classic H3 + WoG install
I’m glad we agree on most topic, some steps towards modding system need to be made
I even considered rewritting all H3 config files (including data?) in our json format.
Certainly there’s an issue with hardcoded size of config files, for example in generalTextHandler. The properties of every object should be read independent of others, especilaly if object number is likely to change (adventure objects, artifacts etc).
I’m going to post a schematic of simple modding system once I’m done with bugfixing and other minor stuff.