Usage of `find_closest` and `set_loose_grouping` in Map Scripts

:arrow_forward: GAME INFORMATION

:point_down: These details are CRITICAL; DO NOT skip them or your issue may not be reviewed.

  • GAME BUILD #: 73855
  • GAME PLATFORM: Steam
  • OPERATING SYSTEM: Windows 10

:arrow_forward: ISSUE EXPERIENCED

:point_down: DESCRIBE THE ISSUE IN DETAIL (below). LIMIT TO ONE BUG PER THREAD.

DE added the find_closest instruction for create_object commands in the OBJECTS_GENERATION section of random map scripts. This command is used extensively throughout the GeneratingObjects.inc file that is included in many of DE’s standard random map scripts. However, this file relies upon unspecified behavior of find_closest, with the effect that some subtle bugs may occur in map generation.

The find_closest instruction is documented on the Forgotten Empires website here: https://www.forgottenempires.net/age-of-empires-ii-definitive-edition/rms-features
To summarize how it is used: there are many ways to restrict the placement of objects. They can have min/max distances to players, be placed on specific terrain types, avoid forest and cliff zones, be made to avoid actor areas or other object groups, and many more. The find_closest instruction finds the map tile that is closest in Euclidean distance to the center of the object’s land (usually this is the center of a player’s TC) and places the object on that tile. It is used to ensure that objects always spawn and avoid bugs where, for example, a player’s Gold mine runs out of room and doesn’t appear. Most commonly it allows for a create_object command to specify a min distance without a max distance, and place the object as close to the min distance as possible.

Note, however, that the documentation specifies the behavior of find_closest only when number_of_objects is 1. But in the GenerationObjects.inc file, find_closest is used in commands for spawning more objects. A good example is spawning the extra player herdables (the 2 groups of 2 Sheep). The herdables use find_closest in combination with set_loose_grouping to find a spot for each group of Sheep. However, find_closest in this circumstance only finds enough room for 1 of the Sheep to spawn. It may find a tile that is surrounded entirely by other tiles that are restricted from spawning the Sheep. The result is that only 1 Sheep spawns instead of 2, since find_closest doesn’t take the entire group into account when searching for a tile.

This behavior seems to be the root cause of an issue I reported here, where the entire group of Goats, placed using find_closest and set_loose_grouping, does not spawn on the official Migration map: https://forums.ageofempires.com/t/migration-may-fail-to-spawn-all-player-sheep/219058
The Goats are sandwitched between the water and the minimum distance to the player, and only 3 of them have room to spawn. Even though there is room elsewhere on the island for the entire group to spawn, find_closest still picks this tile because there’s room for 1 Goat.

I’ve attached a map script that serves as a minimal working example to demonstrate the issue. A create_object command is supposed to spawn 15 Sheep with loose grouping. There are two patches of Dirt: a small one close to the TC and a large one far away. The 15 Sheep do not fit on the close Dirt patch, so find_closest, following its intended usage from GeneratingObjects.inc, should place the 15 Sheep on the far patch. However, the Sheep are placed on the close Dirt patch, and only 9 are created.

Ideally I think the find_closest instruction should behave like GeneratingObjects.inc uses it: that it finds space for the entire group, even with loose grouping. But if that’s not changed, then the game’s map scripts should be updated to ensure they don’t rely upon this behavior incorrectly.

:arrow_forward: FREQUENCY OF ISSUE

:point_down: How often does the issue occur? CHOSE ONE; DELETE THE REST!

  • Less than 25% of the time / matches I play (RARELY)
  • 100% of the time / matches I play (ALWAYS)

Well, the map scripts themselves include the issue 100% of the time, but the result manifests in a missing Sheep or other objects less than 25% of the time.

:arrow_forward: ############ STEPS

:point_down: List CLEAR and DETAILED STEPS we can take to reproduce the issue ourselves… Be descriptive!

Here’s the steps to reproduce the issue:

  1. Download the attached map script and change the extension from .txt to .rms (the forums don’t allow rms files to be uploaded, that itself should be fixed too).
  2. Place the map script file in your rms folder.
  3. Open the scenario editor and set the number of players to 1.
  4. Generate the map on tiny size.

:arrow_forward: EXPECTED RESULT

:point_down: What was SUPPOSED to happen if the bug you encountered were not present?

The map script, following the usage pattern in GeneratingObjects.inc, “should” place 15 Sheep on the far away dirt patch. But instead 9 Sheep are placed on the close dirt patch.

:arrow_forward: IMAGE

:point_down: ALWAYS attach a PICTURE (.jpg, .png, .gif) or VIDEO (.mp4, YouTube link) that highlights the problem.

:arrow_forward: GAME FILES (SAVE / RECORDING)

:point_down: Attach a SAVE GAME (.aoe2spgame) or GAME RECORDING (.aoe2record) of the match where you encountered the issue. Link it below if using an external file service.

3 Likes