Opened 6 years ago

Last modified 5 years ago

#4955 new defect

ObstructionConstraint to ensure placing only reachable entities in rmgen

Reported by: elexis Owned by:
Priority: Should Have Milestone: Backlog
Component: Maps Keywords:
Cc: Patch:

Description

Problem: Since the introduction of the random map generation code, we mark regions that are impassable due to entities (like forests, mines, players, animals) being placed there with tileclasses. When placing further entities, we hardcode the obstruction size of the new entity in avoidClasses constraints. For instance avoidClasses(clMetal, 4, clForest, 1) because that happens to be our obstruction sizes.

Often we forget a tileclass or chose a too small number and then we have units trying to gather resources they can never reach. FeXoR has complained about this often.

Solution: But tileclasses and constraints are still a genious approach per se. Just the way they were used was insufficient in this case.

For every entity placed on the map, the rmgen code can look up the obstruction size and mark the affected terrain as obstructed.

It has to be taken into account that the the entity can be moved after the first placement (rare but possible, see Map constructor in maps.js holding the two kinds of entities).

A new Constraint prototype could just check against all entities that are already placed on the map.

So the new constraints could be [avoidClasses(clMetal, 20), preventCollisions(templateName)] where preventCollisions() returns a new ObstructionConstraint(templateName) and templateName is the name of the template of the entity to be placed.

This way one can't forget anything and can't chose too small numbers and it would still be possible to place entities inside of each other if desired.

(One could still forget the preventCollisions() call however, but that is inevitable if we want to keep it versatile.)

Change History (5)

in reply to:  description comment:2 by FeXoR, 5 years ago

I guess this is mainly about collision?

  • Entities are placed within the obstruction of larger entities

Because IMO there are several other cases of "cannot be reached":

  • Trees in the middle of forests (no problem)
  • Mines or other non-wood resource entities in the middle of forests (should IMO be allowed since the trees can be cut down and the other entity reached at some point of the game. The pathfinder should return "unreachable" and the player notified of this. Still, this should be in general avoided until the pathfinder and unitAI can handle this well.)
  • Resource entities surrounded by or placed on unwalkable terrain (while the pathfinder should tell the player this should be in general be avoided for those entities add no gameplay value - as long as there are no flying units/transports in a mod.)

Collision detection and avoiding tile classes will not help in any of the later cases because it's about connectivity rather than overlapping.

Replying to elexis:

[...] It has to be taken into account that the the entity can be moved after the first placement (rare but possible, see Map constructor in maps.js holding the two kinds of entities).

Oh. In this case the collision maps has to be either updated on shifts, too (not implemented), or be newly generated for every check (expensive). Can we get rid of the shifts?

EDIT: I can't find the "entity moved after placement" part of the code. Could you give me a hint?

Last edited 5 years ago by FeXoR (previous) (diff)

comment:3 by elexis, 5 years ago

EDIT: I can't find the "entity moved after placement" part of the code. Could you give me a hint?

I think there is no map doing it currently, but it's a possibility that it can occur. Code may not rely on assumptions that can be invalidated by someone changing the position of the Entity instance. The position should be deepfreezed if we want that assumption. There are at least some historic cases where an entity is placed and then conditionally deleted again. I think the library functions dealing with positions already do not rely on global states (unless someone has introduced new globals in the meantime).

comment:4 by FeXoR, 5 years ago

Well, I guess expensive it is then ;/

That will likely also mean we want collision checks in as-small-as-possible-regions.

And that also will lead to the need of reading all (or all used but that would be an assumption again) template data and check for the maximum distance from an entities anchor to any points obstructed by it..

in reply to:  description comment:5 by FeXoR, 5 years ago

Replying to elexis:

For every entity placed on the map, the rmgen code can look up the obstruction size and mark the affected terrain as obstructed.

This would be the fast approach BTW.

So please make up your mind and let me know so I can implement it. (Though I guess these are basically 2 issues and obstructed Areas is not the same as "colliding")

Still, we should have a consensus what this specific ticket should solve (and maybe open others fo other issues).

Note: See TracTickets for help on using tickets.