Anonymous Login
2019-12-08 07:40 UTC

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0001384OpenClonkEnginepublic2019-03-31 14:23
ReporterSven2 
Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
StatusnewResolutionopen 
PlatformVisual C++ 2008OSWindowsOS Version 
Product Version 
Target VersionFixed in Version 
Summary0001384: Make cross-check script-accessible
DescriptionThe engine cross-check was once used for object collection, object tumbling, incineration and fight-check (for CR-style clonk2clonk melee fights). These days, most of them have been replaced by FindObjects happening in one of the interaction objects.

This is actually a very inefficient method because it runs though the script engine, has to construct the whole FindObject-context, etc. It's OK for many cases, but when you get to many objects (like Mosquitos stinging clonks), there's always trade-off of performance vs accuracy when you need to decide how often to repeat the check.

I propose to replace the current CrossCheck method by one for which you can register properties to be added to the check. E.g. for a monster, on definition initialization:

AddCrossCheck("Monster", "Prey", "OnHitPrey")

The engine would do this:
1. Reserve a bit for the "Monster" and the "Prey" properties.
2. Set these bit for all objects that have the properties set
3. Add a listener to the object property change function to update the bits when the respective properties change
4. Run the cross check using the bit mask check
5. If it finds a hit, do the callback function on the first object

That method would be resitrcted to e.g. 32 bits at first, but can easily be extended to a bitset or multiple 32 bit masks if we run out of bits for cross checks.

Multiple calls to AddCrossCheck could just update/ignore the call, so you can do it in Initialize of the monster.

Objects can use two bitmasks: One for its own collision bits (first property in AddCrossCheck) and one for its target collision bits (I.e. link second property in AddCrossCheck to first and set all these bits). Then the cross check becomes even simpler because it only needs to do one bit mask comparison (if (obj->bit1 & obj2->bit) ...). It would also mean only one bit is required to be registered per cross-check (i.e.: Only the first bit). The second property can be looked up when a collision has actually happened.

We could also remove OCF and replace it with these custom bits. In fact the features could be separated and work like this:

static OCF_Prey = RegisterOCF("Prey");
static OCF_Monster = RegisterOCF("Monster");
RegisterCrossCheck(OCF_Monster, OCF_Prey, "OnHitPrey");

It could even be made downwards compatible with some of old OCFs like OCF_Alive, and also work in FindObject(Find_OCF(...)).

Of course, instead of bit masks, we can also just use properties and check them on every collision. That would be slightly less efficient but easier to implement.
TagsNo tags attached.
Attached Files

-Relationships
related to 0002054new Feature request: Register custom OCFs 
+Relationships

-Notes

~0003822

Maikel (developer)

Then the cross check should be improved, as for example currently when shooting a shield at a line of clonks with a cannon does not kill them all. So the cross check is missing some them.

~0006213

Marky (developer)

If we expose this to script, then the default behavior for hitting objects needs to be in a library that materials, etc. include?

Some of this is hardcoded, such as how much damage the object takes from a projectile hitting it. Ideally this behavior would be part of a library then, but it adds complexity when creating new objects. That is, if construction materials should still be able to damage living beings, etc., and not only weapons.

~0006214

Marky (developer)

Regarding Maikel's comment: Yes, the cross check missing objects is very likely, if the object has a high velocity.

The cross check iterates over hitable objects and looks if a suitable projectile is on its shape, then the object gets hit by that projectile.
This is very likely done for performance reasons, because there are usually fewer hitable objects (objects with collection, or alive objects) than there are projectile objects (anything that is C4D_Object with enough speed or C4D_Object that is collectible).

If we want a "correct" cross check, then we'd have to go another route: Go from old position to new position and check all objects at that point.
At the moment, the cross check makes objects move through the other objects and/or fling them. When this becomes script-accessible and customizable, then objects might slow down or bounce off of other objects (as with the lorry collection, etc.) as they hit those objects. In that case it might make more sense to have that in the movement code, or do that callback at every movement step. This makes also sense, because sometimes objects are teleported between two frames/checks, so hitting everything between old position and new position is NOT a good solution.

Regarding the performance: It might become more expensive, but should still be better than before? After all, those objects that emulate the cross-check functionality do all of the above things in script, IN ADDITION to the normal cross check.
+Notes

-Issue History
Date Modified Username Field Change
2015-09-05 21:51 Sven2 New Issue
2015-09-05 21:55 Sven2 Note Added: 0003777
2015-09-05 21:57 Sven2 Note Edited: 0003777 View Revisions
2015-09-05 21:57 Sven2 Note Deleted: 0003777
2015-09-05 21:57 Sven2 Description Updated View Revisions
2015-09-05 21:58 Sven2 Description Updated View Revisions
2015-09-05 22:03 Sven2 Description Updated View Revisions
2015-09-19 06:04 Maikel File Added: Screenshot from 2015-09-19 08:03:11.png
2015-09-19 06:05 Maikel Note Added: 0003822
2019-03-31 08:02 Marky Relationship added related to 0002054
2019-03-31 08:21 Marky Note Added: 0006213
2019-03-31 14:23 Marky Note Added: 0006214
+Issue History