-
-
Notifications
You must be signed in to change notification settings - Fork 379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Space.GetBodiesNear(), ProximityQuery module #5637
Conversation
I was as planning to include this in my next PR, but if you want, you can add this changes too, since you're modifying
|
@Max5377 If you have a commit, @Web-eWorks could cherry pick it into this PR, if he wants to. |
I note this creates a data/modules/common folder. What's the philosophy between putting things there vs. data/libs?
Sounds like something that's worth pointing out in the Lua-API documentation, as it is intended to be used by beginners. |
@impaktor Do I just fork this branch and do PR, or I can commit directly without PR? |
The idea is for common functionality used in mission modules to live there (e.g. the mission time/reward calculator utility, ship generation/outfitting utilities, etc.) - it's not fundamental to the execution and design of the game, but is a useful tool for creating modular content. The way I see it, I've put the ProximityTest file in As a side note, individual equipment definitions should most likely live in a |
I really like this concept, it was something I've been thinking about, whilst playing with pirates logic - for example, I see each mission spawns and equips enemy ships in their own places and in slightly different ways, whereas ideally you'd have some centralized logic to help with that. Actually, I'd like to have centralized logic to help with that as then one can have difficulty settings that would then globally effect all the missions (as appropriate). |
OK @Web-eWorks , I had another look at this and realized some usage semantics that I think will make sense for using the ProximityTest.lua, as-is. I think the general rule of thumb with this API is only create tests for a body of which your script 'owns'. E.g. if you are creating a Pirate ship module, then write the tests for the pirate ships, not the player ship, nor planets/spaceports or other things. The reason for this would be that otherwise there is the possibility of two different pieces of code requesting the same parameters and overwriting each other's listeners. One way around this would be for The other thing that end up being problematic is that the way of scheduling these tests is essentially random and so we hope that the RNG is kind and we don't end up with them clustered together. I've been burned by this in the past, with either really odd, hard to reproduce bugs or frame rate instability. I personally wonder if the timer field matters too much at all. It might be better to have no guaranteed time for these to happen and process each context, n a frame, continually (where n could vary depending on time acceleration and be one a frame if there was no acceleration on). This may well mean that we're actually doing these a lot more than we would with the current time based logic but it is more likely to give us more consistent frame rate and better worst-case frame time. Either way, neither of these are showstoppers I don't think, I'm really grateful for this and intend to have a go at re-building the (unpublished) pirates changes I've been working on top of this, exclusively in Lua. |
While I do agree with you, the current LuaTimer implementation serves two separate semantic purposes - a (relatively) high-precision interval-based callback implementation for game mechanics which require precise timing, and a way to request functionality to be called at some imprecise time later in the future when it's convenient. If trying to limit the performance impact of simultaneous timers, it would be better to split the two uses into separate APIs. In the context of the ProximityTest module itself, it'd definitely be possible to limit the total number of proximity queries performed per frame as well; I've not implemented that in the current version simply because I don't expect there to be enough performance cost coming from the module in the near future to necessitate implementing a priority queue in Lua when the current timer implementation does a very good job of stochastic amortization. I can definitely bolt it on afterwards with little difficulty if it becomes needed.
Regarding the API for proximity test modules, the hash of body/distance/interval was just intended to make a unique key to store the proximity test object for iteration and the design of the module diverged from one in which that key is useful. If there's not an immediate need for multiple mission modules to share the same ProximityTest instance with the same parameters, I can remove the hash key and vastly simplify that aspect of the API. |
I've simplified and updated the I've also dropped the |
Will be merging this PR soon if no objections / further review is forthcoming. |
No objection from me, I've been using it a while and all seemed good :-) |
- Add helper to push/pull ObjectType enum values from Lua - BodyNearFinder functionality exposed to LuaAPI
- Avoids pushing all bodies in Space to Lua every time we want to perform a very simple type filter operation - Also avoids a Lua -> C -> Lua -> C call chain for each body - Replace with lua-side filtering on a reduced set of bodies where class filter isn't granular enough - Convert all classnames into ObjectType enum values for filtering
- All proximity queries are transient and should not be serialized - Proximity queries should generally be created by code that "owns" the entities being queried. - Queries are not reused/shared based on parameters due to large parameter space making useful sharing unlikely.
32cea10
to
1a97ea2
Compare
Stemming from discussion on IRC, this PR exposes the BodyNearFinder functionality as
Space.GetBodiesNear()
, refactorsSpace.GetBodies()
to be significantly more efficient with all current callsites, and provides an initial prototype of a ProximityTest module for the use of mission modules.All GetBodies* function callsites now pass a classname (the same as would be used with
:isa()
) instead of a filter function. This moves the ObjectType filtering inside of C++ where it can be significantly more efficient than calling a Lua filter function for every object iteration (which internally called back into a C++ accessor function... sigh).On the topic of efficiency, there is an unimplemented further optimization where we can potentially convert ObjectType into a bitfield to enable O(1) body type evaluation, given that we have a strict single-inheritance model for Bodies.
The new ProximityTest module provides a way for mission modules to request nearby bodies to be evaluated for a given reference body and to receive events when a body of the given type enters or leaves the given relevancy range of the reference body. This is mostly intended to enable @JonBooth78's WIP pirate ambush mission module, but could also be used in many different places in the codebase due to the pattern of deferring nearby body checks on an interval.
Note that ProximityTest cannot be serialized and individual tests will have to be recreated by downstream module code after loading a saved game.
This PR also provides partial type information about the LuaSpace API - I've not had time to finish providing type information about all functions in LuaSpace.