Not logged inOpenClonk Forum
Up Topic Development / Developer's Corner / Layers (Planes?)
1 2 Previous Next
Parent - - By Günther [de] Date 2010-10-15 01:34

> Here is a compromise between yours and Günthers argumentation. What do you two think of this.:


Sorry, that's not a compromise at all. We are all agreed that stuff like does-grow or the shape of the fire effect shouldn't depend on the object's position. How the engine derives a default position for object definitions that don't specify one isn't very important as one can always simply add that should the engine choose poorly.

> (Trees in front of animals & objects and trees behind structures should probably have the same behaviour.)


No, they shouldn't. Well, it doesn't matter for the two examples of position-based behavior (blastwaves and solidmasks) for trees, so let's take a car as an example. Cars are transported by solidmasks, at least by those attached to lifts. (No reason all solidmasks need to behave the same.) Buildings are not. I think it would look extremely weird if cars behind buildings were lifted by these solidmasks. There's a building in the way! A lift shouldn't be able to reach through the solid building and mess with the background objects!

I tried to think of other examples of position-based behavior in the engine, and remembered the hittest (Clonks vs. rocks). Again it would be just as weird to have a rock behind a building hit a Clonk in front of it as it would be for a rock ten Clonks away to hit the Clonk. Essentially, the engine would test (a.x, a.wdt) overlaps (b.x, b.wdt) and (a.y, a.hgt) overlaps (b.y, b.hgt) and (a.z, a.depth) overlaps (b.z, b.depth). The fact that the z test doesn't work properly at the moment doesn't mean that it shouldn't be there at all, it means that it should be made to work properly.
Reply
Parent - By Zapper [de] Date 2010-10-15 05:52

>Sorry, that's not a compromise at all. We are all agreed that stuff like does-grow or the shape of the fire effect shouldn't depend on the object's position.


Yes (actually Newton didn't say anything else?), and everyone but you agreed that actually no internal behavior should be tied to the order the objects are drawn on the screen, duh.

>No, they shouldn't. Well, it doesn't matter for the two examples of position-based behavior (blastwaves and solidmasks) for trees


I don't see how having a list of which things affect which layers and have the scripters look at that list and think about in which layer they should put their object ("Oh, but if I put it in that layer it is behind Y - but I need it to be affected by X!!!") makes anything easier.
Parent - - By Newton [de] Date 2010-10-15 11:03

>Sorry, that's not a compromise at all.


Uhm. I was was trying to help you guys to get to a common solution.
Parent - - By Günther [de] Date 2010-10-15 12:17
And you did it by repeating Zappers position. Well, thanks for trying :-)

Anyway, we've probably exhausted the available arguments now. I'll implement my design. If it turns out to be a bad idea after all, we can just modify the three or four algorithms using the z-position, which is trivial compared to the other necessary changes. We don't have to make a final decision now and live with the consequences for years.
Reply
Parent - - By Newton [de] Date 2010-10-15 13:41
When you implement it, can you write down on what behaviours you put into (what) properties and what you leave to be linked with the object order? I'd like to see what all is currently linked with categories.
Parent - By Günther [de] Date 2010-10-15 16:33
I'll document what I link with the position, but I can't promise a thorough list of category behavior. Looking at that stuff makes me sad :-(
Reply
Parent - - By Günther [de] Date 2010-12-23 02:23
The freeze is over and various other projects are more or less done. It's time to wrap this up.

As usual, the most difficult thing is the script API. I've tentatively called the thing "Z", since that's what it is. One small problem is that we already have a Z position: Parallaxity. The new Z position would be a mere stacking order in the infinitely thin plane given by the parallaxity. Or, well, the layer in the plane, but using that word would require renaming that other "layer" feature. Anyway, I'd like to design a coherent API for both. Ideally including the feature request of the X/Y position of parallax objects being useful instead of the projected position on the landscape plane when the camera is at 0/0. That'd require dealing with infinitely far away objects (like the HUD...) separately, which is probably a good idea anyway. So, further feature requests? API suggestions?
Reply
Parent - By Zapper [de] Date 2010-12-23 06:19

>So, further feature requests?


Yes, but I guess we argued enough about that. :)
Parent - - By Clonk-Karl [de] Date 2010-12-26 13:21
How about calling it "sort order" or "drawing order"? Since that's what it really is. :)

Just some further brainstorming about the topic Z order/parallaxity: What if we change the meaning of X/Y of parallax objects to really mean the position within the world (and, while we are at it, remove the feature of different values of parallaxity for X and Y). Then change the camera position so that it is in the viewport center instead of the left viewport edge. The drawing order could then be determined first by parallaxity (that is, "real" Z), and, if it's equal, by the newly introduced sort order. As you already pointed out this would require special handling for GUI/HUD objects (since, even if they are infinitely far away, they should be drawn on top of everything else, and since otherwise they could not be aligned to the viewport boundaries).

You do not plan to use the depth buffer for this feature, right?
Reply
Parent - - By Zapper [de] Date 2010-12-26 13:44

>As you already pointed out this would require special handling for GUI/HUD objects (since, even if they are infinitely far away, they should be drawn on top of everything else, and since otherwise they could not be aligned to the viewport boundaries)


I don't want to rant again, but wasn't the idea in the first place to have a ordering system that works equally fine for both GUI and ingame objects without special treatment for special stuff? :)
Parent - By Günther [de] Date 2010-12-26 17:37
Well, feel free to suggest such a thing. As far as I know, the requirements for game objects and GUI objects are incompatible: You really want that objects do not change their apparent x/y position if they are in the center of the screen and their z-position changes. And you want GUI objects to be positioned in screen coordinates, not landscape coordinates. That you can sort-of-do that at the moment by pretending to position them with landscape coordinates and infinitely far away from the viewer doesn't mean that that is a good idea.

Also, I do not know of any usecases for objects that have inconsistent positions, that is, appear to be behind/before some other objects while the camera doesn't move, but appear to be farther/less far away when the camera moves. Apart from GUI objects, of course. If nobody can come up with any objects "in the landscape" that should behave in such a strange way, it's best to remove that feature from the engine to save everyone's time.
Reply
- - By Günther [de] Date 2010-12-27 21:49 Edited 2010-12-27 22:26
There's a first patch on bitbucket. The category-replacing thingie is called "Plane" for now. Suggestions for better numbers for the inferred-from-category-planes are welcome. Here's a list of the remaining usages of "SortLimit" categories:
- C4Command::Build:
  // Worker ist structure or static back: internal target build only (old stuff)
  // Activate internal vehicles
- C4GameObjects::Load: // staticback must not have speed
- StaticBack have different behaviour with regards to "layer bounds"
- StaticBack don't move
- StaticBack can't be grabbed
- Only StaticBack can be chopped
- Only StaticBack and Alive Living can grow
- // Material check (if rule set or any other than structure or castle-part)
  bool fNeedMaterial = (Game.Rules & C4RULE_ConstructionNeedsMaterial) || !(Category & (C4D_Structure|C4D_StaticBack));
- StaticBack don't do gravity
- "// Woa, structures can build without target"
- bool IsMoveableBySolidMask()
  {
    C4PropList* pActionDef = GetAction();
    return (Status == C4OS_NORMAL)
           && !(Category & (C4D_StaticBack | C4D_Structure))
           && !Contained
           && ((~Category & C4D_Vehicle) || (OCF & OCF_Grab))
           && (!pActionDef || pActionDef->GetPropertyP(P_Procedure) != DFA_FLOAT)
           ;
  }
- StaticBack are not sorted by their definition
-   // Regular objects: Try to find a new, suitable owner from the same team
    // Ignore StaticBack, because this would not be backwards compatible with many internal objects such as team account
    // Do not ignore flags which might be StaticBack if being attached to castle parts
- Structure is created using CreateConstruction instead of CreateObject on drag'n'drop into a editor viewport
- // Structures dig free snow
- C4Object::DoCon:
  // even rotated buildings need to be moved upwards
  // but by con difference, because with keep-bottom-method, they might still be sinking
  // besides, moving the building up may often stabilize it
-   // set default fire modes
  DWORD dwCat = pObj->Category;
  if (dwCat & (C4D_Living | C4D_StaticBack)) // Tiere, Bäume
    iFireMode = C4Fx_FireMode_LivingVeg;
  else if (dwCat & (C4D_Structure | C4D_Vehicle)) // Gebäude und Fahrzeuge sind unten meist kantig
    iFireMode = C4Fx_FireMode_StructVeh;
  else
    iFireMode = C4Fx_FireMode_Object;
- // Shock wave hit (if in level range, living, object and vehicle only. No structures/StatickBack, as this would mess up castles, elevators, etc.!)
  if (cObj->Category & (C4D_Living | C4D_Object | C4D_Vehicle))
  // vehicles and floating objects only if grab+pushable (no throne, no tower entrances...)
    // living takes additional dmg from blasts
    cObj->Fling( itofix(Sign(cObj->GetX()-tx+Rnd3())*(level-Abs(tx-cObj->GetX()))) / BoundBy<int32_t>(cObj->Mass/10, 4, (cObj->Category & C4D_Living) ? 8 : 20), itofix(-level+Abs(ty-cObj->GetY())) / BoundBy<int32_t>(cObj->Mass/10, 4, (cObj->Category & C4D_Living) ? 8 : 20), true );
    if (cObj->Category & C4D_Object)
      // tracing indirect killers
      cObj->Controller = iCausedBy;
- C4Game::ShakeObjects only affects Living
- C4Object::Init: if (Category & C4D_Living) Alive=1;
-   // OCF_Inflammable: Is not burning and is inflammable
    // Is not a dead living
-  if (Category & C4D_Living)
  {
    OCF|=OCF_Living;
    if (Alive) OCF|=OCF_Alive;
  }
- C4Object::AssignDeath:
  // ensure objects that won't be affected by dead-plrview-decay are handled properly
  if (!pPlr || !(Category & C4D_Living) || !pPlr->FoWViewObjs.IsContained(this))
    SetPlrViewRange(0);
-  // Dead living don't burn
-  // Assume that the new container controls this object, if it cannot control itself (i.e.: Alive)
  // So it can be traced back who caused the damage, if a projectile hits its target
  if (!(Alive && (Category & C4D_Living)))
    Controller = pTarget->Controller;
- // Script context functions of target
  // No dead livings
- // Context functions of the menu clonk itself (if not same as target)
  // No dead livings
- // decay of dead viewtargets
- // Only hit if target is alive and projectile is an object
Reply
Parent - - By Günther [de] Date 2010-12-28 23:40 Edited 2010-12-28 23:43
And here's a first categorization for what to do about them.

Can be replaced by making other functionality dynamic


- StaticBack can't be grabbed
- Only StaticBack and Alive Living can grow
-   // OCF_Inflammable: Is not burning and is inflammable
    // Is not a dead living
-  // Dead living don't burn

Probably has to be replaced with a new separate property


- StaticBack don't move
- StaticBack don't do gravity
- C4Object::Init: if (Category & C4D_Living) Alive=1;

Can be replaced by script already or does not need a replacement


- C4Command::Build:
  // Worker ist structure or static back: internal target build only (old stuff)
  // Activate internal vehicles
- StaticBack have different behaviour with regards to "layer bounds"
- Only StaticBack can be chopped
- // Material check (if rule set or any other than structure or castle-part)
  bool fNeedMaterial = (Game.Rules & C4RULE_ConstructionNeedsMaterial) || !(Category & (C4D_Structure|C4D_StaticBack));
- "// Woa, structures can build without target"
- StaticBack are not sorted by their definition
-   // Regular objects: Try to find a new, suitable owner from the same team
    // Ignore StaticBack, because this would not be backwards compatible with many internal objects such as team account
    // Do not ignore flags which might be StaticBack if being attached to castle parts
- Structure is created using CreateConstruction instead of CreateObject on drag'n'drop into a editor viewport
- // Structures dig free snow
- C4Object::DoCon:
  // even rotated buildings need to be moved upwards
  // but by con difference, because with keep-bottom-method, they might still be sinking
  // besides, moving the building up may often stabilize it
- C4Game::ShakeObjects only affects Living
-  if (Category & C4D_Living)
  {
    OCF|=OCF_Living;
    if (Alive) OCF|=OCF_Alive;
  }
- C4Object::AssignDeath:
  // ensure objects that won't be affected by dead-plrview-decay are handled properly
  if (!pPlr || !(Category & C4D_Living) || !pPlr->FoWViewObjs.IsContained(this))
    SetPlrViewRange(0);
- // decay of dead viewtargets
- // Script context functions of target
  // No dead livings
- // Context functions of the menu clonk itself (if not same as target)
  // No dead livings
- C4GameObjects::Load: // staticback must not have speed

Bla


- bool IsMoveableBySolidMask()
  {
    C4PropList* pActionDef = GetAction();
    return (Status == C4OS_NORMAL)
           && !(Category & (C4D_StaticBack | C4D_Structure))
           && !Contained
           && ((~Category & C4D_Vehicle) || (OCF & OCF_Grab))
           && (!pActionDef || pActionDef->GetPropertyP(P_Procedure) != DFA_FLOAT)
           ;
  }
-   // set default fire modes
  DWORD dwCat = pObj->Category;
  if (dwCat & (C4D_Living | C4D_StaticBack)) // Tiere, Bäume
    iFireMode = C4Fx_FireMode_LivingVeg;
  else if (dwCat & (C4D_Structure | C4D_Vehicle)) // Gebäude und Fahrzeuge sind unten meist kantig
    iFireMode = C4Fx_FireMode_StructVeh;
  else
    iFireMode = C4Fx_FireMode_Object;
- // Shock wave hit (if in level range, living, object and vehicle only. No structures/StatickBack, as this would mess up castles, elevators, etc.!)
  if (cObj->Category & (C4D_Living | C4D_Object | C4D_Vehicle))
  // vehicles and floating objects only if grab+pushable (no throne, no tower entrances...)
    // living takes additional dmg from blasts
    cObj->Fling( itofix(Sign(cObj->GetX()-tx+Rnd3())*(level-Abs(tx-cObj->GetX()))) / BoundBy<int32_t>(cObj->Mass/10, 4, (cObj->Category & C4D_Living) ? 8 : 20), itofix(-level+Abs(ty-cObj->GetY())) / BoundBy<int32_t>(cObj->Mass/10, 4, (cObj->Category & C4D_Living) ? 8 : 20), true );
    if (cObj->Category & C4D_Object)
      // tracing indirect killers
      cObj->Controller = iCausedBy;
-  // Assume that the new container controls this object, if it cannot control itself (i.e.: Alive)
  // So it can be traced back who caused the damage, if a projectile hits its target
  if (!(Alive && (Category & C4D_Living)))
    Controller = pTarget->Controller;
- // Only hit if target is alive and projectile is an object
Reply
Parent - - By Günther [de] Date 2011-01-01 15:57

> StaticBack can't be grabbed


Make Grab a property. Or perhaps just remove it from the engine?

> Only StaticBack and Alive Living can grow


Make Growth a property. Or perhaps just remove it?

> OCF_Inflammable


Make ContactIncinerate a property. Though perhaps we could also just allow corpses to burn. It never made much sense that they couldn't.

> StaticBack don't move
> StaticBack don't do gravity


Any suggestions for names for these? The latter already has Procedure=Float, so maybe we don't need anything new. We could use a procedure for the former also, but that will result in a lot of boilerplate for the simple background decorations this is used for.
Reply
Parent - - By Newton [de] Date 2011-01-01 18:38

>> StaticBack can't be grabbed
>Make Grab a property. Or perhaps just remove it from the engine?


IIRC an object that can be grabbed needs to have a certain value in defcore set anyway. So I don't see a reason why this should stay in the engine.

>> Only StaticBack and Alive Living can grow
>Make Growth a property. Or perhaps just remove it?


Yeah, property or defcore property, I'd say. By the way, why is there still a difference between defcore property and (definition) property?

>Any suggestions for names for these?


StaticBack=1?
Parent - By Günther [de] Date 2011-01-01 21:53

>> Make Grab a property.
> IIRC an object that can be grabbed needs to have a certain value in defcore set anyway.


Yes, "Grab". I think the only critical usage in the engine is in IsMoveableBySolidMask, everything else could be done by script already.

> By the way, why is there still a difference between defcore property and (definition) property?


They are implemented in a totally different way and while it'd would be easy now that norefs was merged to pretend they were the same, I don't want any properties on definitions that cannot be overwritten by objects. Setting obj.Grab=0 should make the object untouchable if local Grab=1; was the way it was made grabable. But that requires changing every line in the engine dealing with Grab, and nobody had the inclination to do a mindless mass conversion yet. Since a lot of defcore values are of the same dubious value as Grab, I don't think that will change. But if somebody could go through the defcore values and make a list of those that will stay around for longer in the engine and roughly sort that list by how often it'd be nice to change the value dynamically, we could start with the conversion.
Reply
Parent - - By MrBeast [de] Date 2011-01-01 18:46 Edited 2011-01-01 18:51

>Any suggestions for names for these?


GravityAcc=0 as for the particles? That could be also useful for Objects with different air drag.
Reply
Parent - By Günther [de] Date 2011-01-01 22:00
I'd rather introduce real air drag. While there's also a usecase for buoyancy, the few objects where it would be noticeable are served well enough by Procedure=DFA_FLOAT.
Reply
Parent - By Clonkonaut [de] Date 2011-01-03 13:54

> Though perhaps we could also just allow corpses to burn. It never made much sense that they couldn't.


Oh, the cruelness!
Reply
Parent - - By Günther [de] Date 2011-01-02 04:43

> // Regular objects: Try to find a new, suitable owner from the same team
> // Ignore StaticBack, because this would not be backwards compatible with many internal objects such as team account
> // Do not ignore flags which might be StaticBack if being attached to castle parts


Does OC already have staticback objects which have owners and that rely on not being reassigned to a team member when the owner is removed from the game?

> C4Game::ShakeObjects only affects Living


ShakeObjects uses Shape.AttachMat and Action.t_attach. The latter could be replaced by hardcoding procedure attach behavior in script (or just removing procedure attach behavior in favor of ActMap.*.Attach), but the former is somewhat of a mystery. It's only used for AdjustWalkRotation and ShakeObjects. I think everything else just assumes that objects that wanted to be attached (=nonzero Action.t_attach) but couldn't because there was no landscape were forced to jump and thus no longer have Action.t_attach. It's probably save for ShakeObjects to also do that.

> Can be replaced by script already or does not need a replacement


I've deleted the other things under this heading. Some still need a script replacement, and I've not tested anything yet.

> bool IsMoveableBySolidMask()


> Shock wave hit (if in level range, living, object and vehicle only. No structures/StatickBack, as this would mess up castles, elevators, etc.!)


> Only hit if target is alive and projectile is an object


The plan is still to use layers/planes for these.

> set default fire modes


Still no idea. Perhaps the object's size could be used?
Reply
Parent - - By Zapper [de] Date 2011-01-02 09:47

>Still no idea. Perhaps the object's size could be used?


I am going to reimplement the whole fire stuff via script anyway (just as a sidenote)
Parent - By Günther [de] Date 2011-01-02 16:37
So? Script doesn't have any magical sources of information the engine doesn't have, so reimplementing that stuff in script again doesn't solve the problem.
Reply
Parent - - By Maikel Date 2011-01-02 11:29 Edited 2011-01-02 16:41

>Does OC already have staticback objects which have owners and that rely on not being reassigned to a team member when the owner is removed from the game?


I don't know of any, but if they do C4Script FnOnOwnerRemoved isn't called if they have the OnOwnerRemoved() callback specified, right?

Edit: The whole hud is owned and StaticBack.
Parent - - By Günther [de] Date 2011-01-02 16:34
Probably. OnOwnerRemoved is a weird callback. FnOnOwnerRemoved should be removed from the engine entirely.
Reply
Parent - - By Zapper [de] Date 2011-01-02 18:33
Why? I guess it can be important in some games. For example if you want to make sure that certain objects (super mighty staff of super might) do not stay in the game after the player to whom it belonged died

PS: I think I actually used that callback once back in CR..
Parent - By Günther [de] Date 2011-01-02 19:00
I used FnOnOwnerRemoved to refer to the engine function called OnOwnerRemoved, which is implemented just like CreateObject and others are. Having the engine call itself via script indirection might be a nice way to do callbacks, but the majority of callbacks do the default engine implementation when the callback is not implemented or returns 0, not when it is not implemented or calls inherited. While the latter does have some small advantages, they aren't compelling enough to make someone spend the effort to switch all callbacks over. I think making all callbacks consistent is more important than using a little bit nicer method for one callback. The category thing is just a nice opportunity to do the change now.
Reply
Parent - - By Günther [de] Date 2011-01-03 03:10
The current state can be found on bitbucket, as usual.

I'm actually considering not to remove all the remaining usages, but to leave these in:
- StaticBacks don't move
- Livings start as Alive
- Objects hit Alive
With the other baggage related to categories removed, the remains do not look that bad anymore. Sure, it could be better, but there are lower-hanging fruit elsewhere.

The next big missing thing (apart from some testing) now are the default Plane numbers the engine derives from the category of definitions that don't have a Plane number. At the moment, I've put these placeholder values in:
C4D_StaticBack: Plane = 5
C4D_Structure: Plane = 10
C4D_Vehicle: Plane = 20
C4D_Living: Plane = 30
C4D_Object: Plane = 40
C4D_StaticBack | C4D_Background: Plane = -10
C4D_Structure | C4D_Background: Plane = -8
C4D_Vehicle | C4D_Background: Plane = -6
C4D_Living | C4D_Background: Plane = -4
C4D_Object | C4D_Background: Plane = -2
C4D_StaticBack | C4D_Foreground: Plane = 51
C4D_Structure | C4D_Foreground: Plane = 53
C4D_Vehicle | C4D_Foreground: Plane = 55
C4D_Living | C4D_Foreground: Plane = 57
C4D_Object | C4D_Foreground: Plane = 59
Reply
Parent - By Günther [de] Date 2011-01-04 01:50
Next update. I fixed the obvious brokenness Maikel kindly pointed out. I think it's time to stop changing things and get the series ready to be pushed to hg.openclonk.org. There's still some category things in the engine I want to remove, but there are a lot more in scripts, and others could help there, especially after the engine stops requiring every object to have one of the five "sort" categories.
Reply
- By Günther [de] Date 2011-01-08 18:03
I've pushed to hg.openclonk.org. With that, I'm probably done with large-scale refactoring of the engine code for this release. Now it is time for bugfixes and game content.
Reply
Up Topic Development / Developer's Corner / Layers (Planes?)
1 2 Previous Next

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill