Making adventure map objects more configurable

You are right. Somehow you are always right.

  1. Good case. Then the list of visits needs to be stored in hero instance.

  2. I take back what I said about armed instance. It is either a potential enemy or a source of army to exchange with.
    Every reward-giving object should be armed instance and it is not wrong. Creating a temporary object for exchange… would be much work with no significant gains.

  1. One case we’ll need to consider here is how reset visitors? This won’t be as trivial as erasing list of visited heroes/players.
    A - keep visit date & date of latest reset and determine if object is visited based on that.
    B - (probably better one) add “Reset object visitors” net pack. On applying gamestate will erase this flag from all HeroInstances/PlayerStates. We may need to optimize this somehow to avoid spamming of hundreds of such netpacks each week but other than that this approach should be OK.

  2. And that means that it won’t be possible to apply this system to town buildings as well. At least for now

As for temporary object - perhaps implement it one way as part of garrison exchange query? Another option would be to handle this particular case (granting creatures via town building) manually - by filling free slots as much as possible discarding everything else.
[yeah, I know - ugly solution for largely optional feature]

Right now I’ve started looking into integration with AI. Can somebody who knows more about AI show desired interface for AI interaction? I can do something as simple as set of methods like “bool givesArtifacts()” but AI may need more information than that (like chance to provide artifact, chance to give some specific artifact, etc).

Currently I’m planning to move “object configuration” to handler so it will be possible to query configuration of object type without access to actual object instance. But I’m not yet sure on how AI interface of this “object configuration” should look like.

Didn’t follow the project over last week, so some points may be outdated.

I believe it would be better for AI to receive full info about all available rewards in first place and only then prepare some plan. For example, try to find all objects that can give gold or reward artifacts.
In my vision AI will preprocess all this info at the beginning of game and not poll concrete adventure objects. For that purpose, general info needs to be available independent of object instances.

Another issue are visitable objects. For example check for weekly visits is performed in isWeeklyRevisitable function on AI side. It would be better to give such info on object side.

Ok, so this is short version of current state:

  1. Objects consist from one or more of “rewards”, described here:
    github.com/IvanSavenko/vcmi/blo … ward.h#L63
    This is post-randomization state so neither AI nor human player should have access to it.

  2. Before randomization this information must be stored in separate structure that describes how this object should be randomized. So for example given resources should be described as something like this:

class CObjectInfo
{
    struct ResourceInfo
    {
        ui32 minAmount;
        ui32 maxAmount;
        std::set<Res::ERes> allowedResources;
    };
    std::vector<ResourceInfo> grantedResources;
    ...
}

And each object may contain multiple such entries (e.g. to grant different resources under different conditions - like water mill giving twice more gold on day 7).

I can give AI direct access to such structure but I’m not sure if it is AI who should read it:

  1. Interface may be shared among different objects, and not only those that I’m trying to replace.
  2. From what I see right now simple interface to show “type” of granted resources (and their “value”) is more that enough for AI. Of course this may change in future but this it what I see currently. So direct access to such struct will mean more coding on AI side to properly read this structure (and guess what it will contain after randomization).

Checks like these are not a problem - information like this will be available to AI so this is just a matter of replacing that check.
(although instead of “weekly revisitable” objects I have “reset duration” property so objects are not necessarily reset each week, but this is not applicable to H3 objects)

Not sure if I’d need to create new topic or bumping this one is fine, but anyway. Currently I’m look via adventure map objects handling code and see there is few things that incomplete: cartographers need don’t work as non-unique objects, “visited” and “owned” not displayed for all objects where it’s needed. Though it’s possible to just fix those in code, but it’s result in code duplication that looks bad. So I decide to ask few things.

First of all is it important to stick to behaviour of vanilla H3? E.g cartographers for don’t have “visited” hover text in vanilla and some objects that can be owned don’t have “owned” hower text. Personally I think that what I see it’s would be useful to add “owned by” in status for all objects that can be owned.

Also at moment there is few separate handlers “onceVisitable”, “oncePerHero”, “oncePerWeek” used by rewardable objects. Still those handlers can’t be used by special objects like cartographers and keymasters and objects that use “onceVisitable” still shouldn’t share this information for other players.

Based on this I think what if each object in JSON would have few more properties like:

  • (bool) “isUnique”. Set to “false” for keymasters, cartographers and any other objects that once visited/paid you can no longer use any other objects of same type/subtype.
  • (bool) “canBeOwned”. Set to “true” for mines, dwellings, lighthouse, shipyards, border gates, etc (?). Possible this should also enable "Owned by " hower text for all such buildings.
  • (string) “visitLimit”: onceVisitable, oncePerPlayer, oncePerHero, oncePerWeek, etc. Those might be moved to option and in same time rewardable objects might get different “handler”.
  • (bool) “visitVisibility”. At moment all rewardable objects like Warrior’s Tomb are marked as visible for every player while they shouldn’t (there is note in code). So VCMI might not only fix this, but also implement an option that make certain object marked as visited on adventure map for every player. Shouldn’t be needed for vanilla objects, but might be useful for mods.
  • Also thinking there might be some property that allow to set guards to certain object…
    Of course it’s just my thoughts and properties, names and options might be different, but I think something like that would help to finish implementation of current objects and also add a bit more modability.

I think we first should reach working state for all objects from summer, as object rewrite is clearly not complete and includes a number of bugs or missing options.

Sounds reasonable. However specifically about cartographers this is a bit tricky - if another player has activated Shroud of Darkness (one-use version on map) should we un-mark cartographers as visited?

Yes as long as this works only for players that see interaction, not globally for everyone. H3 objects also may use this - e.g. Windmill or Skeleton (object that don’t have yes/no confirmation dialog).

Although as Warmonger said I’d suggest going through known bugs first. Specifically these:
bugs.vcmi.eu/view.php?id=1912
bugs.vcmi.eu/view.php?id=1940 (and similar bugs for some other objects)

Also, I think I had some unfinished (and unpushed) work on this, specifically - on loading some objects from config. I’ll check in what’s state this branch now and push it in repo before it gets lost competely.

In vanilla you can only buy each type of map once. Though it’s would be interesting if it’s will be possible to mod a different cartographer with different rules.

Will try to find out. Actually those objects without messages is likely most annoying problem in game at moment. Still there is many quite primitive things missing and at moment they do cause code duplication. Is this okay for now?

Unfortunately I’m not professional C++ programmer so only thing I worry about it’s not to craft tons of useless code if there is better solution possible. :blush:

Would be great to see it even if it’s will be in some separate branch.

Other idea that should make both modding of objects and reading of configuration easier. Why not just split current code into “visitLimit” (once, oncePerPlayer, oncePerHero) and “resetPeriodicity” (never, oncePerDay, oncePerWeek, oncePerMonth, eachFriday, etc) so they would be independent options?

Ivan, can you say me something?

Now for boat object we have

94 	"boat" : { 
95 		"index" :8, 
96 		"handler": "boat", 
97 		"base" : { 
98 			"base" : { 
99 				"visitableFrom" :  "+++", "+-+", "+++" ], 
100 				"mask" :  "VVV", "VAV" ] 
101 			} 
102 		}, 
103 		"types" : { 
104 			"evil" : { "index" : 0,	"rmg" : { "mapLimit" : 64 } }, 
105 			"good" : { "index" : 1, "rmg" : { "mapLimit" : 64 } }, 
106 			"neutral" : { "index" : 2, "rmg" : { "mapLimit" : 64 } }, 
107 		} 
108 	}, 

As I looked into sources, boats are handled still like they was (my commits for boats modding were rejected in summer, but still no movement in this theme).

Can I for future use mod boats already?
Like in section “objects” add json, where will have

94 	"boat" : { 
95  		"types" : { 
104 			"myNewCoolBoat" : { 	
"rmg" : { "mapLimit" : 64 },
 "templates":{"mynew":{"animation":"newcool.def","allowedTerrains":"sea"}} }, 

107 		} 
108 	}, 

and after boats modding is finished, that will work?

Together with previos question on boats, next question had arisen.

I wanted to add bridges to map objects.
I created sub-object of

	"core:canyon" : {
	"handler": "generic",
		"types" : {
			"bridges01" : {
				"name" : "Bridge",
"rmg":{
					"value"		: 100,
					"rarity"	: 50},
			"templates" : {
				
								"bridge01" : { "animation" : "decors/bridges/bridge01.def", 
					"visitableFrom" :  "+++", "+++", "+++" ], 
					"mask" : "BBBBB","VVVVV","BBBBB"],
					"zIndex":-1
					},

}
}

In WIKI there is field “zIndex” that affects overlay. I looked into source code, it loads on start.
By the way, json scheme writes “unknown entry found: zIndex”.
On map bridge still hides hero under him instead of be under hero (as it is like only decoration on earth).
Is there is no way to make def zIndex lesser than hero’s?

Not 100% sure about most recent git, but I feel like there was issues with that even with default H3 assets so it’s maybe just a bugs.

I think next big thing I’m going to do is more configuration options for map objects.

I’m currently tried to make list of incorrect visit sounds and clearly find out that they should not be set in code at all as it’s super hard to change them this way.

I’ll suggest new JSON options quite soon.

Seems you got no time for objects sound configuration:-)
Time comes to stage, when i think about adding battlefields filenames to objects JSON.
We got here need to input path to battlefield backgrounds, to think about adding obstactles confguration for each object configuration section, and (arbitrary) for sound files serving as music background for battlefields.

How about adding section to each object like:

"battlefieldProperties" : 
  {
     "battlefield" :  "coolmod/background1" , "coolmod/background2"  ],
     "obstacles":
      
       {
		"width" : 2,
		"height" : 1,
		"blockedTiles" :  [0, 1],
		"defname" : "ObDino1.def",
		"unknown" : 1
        },
     ]
     "absoluteObstacles" : 
      
        {
             	"width" : 300,
		"height" : 214,
		"blockedTiles" :  [59, 60, 74, 75, 76, 93, 94, 95, 111, 112],
		"defname" : "ObMCL00.pcx"
         },
      "music" :  "coolmod/battle1", "coolmod/battle2"  ]
     ]
}

Battlefield and music will be taken randomly (if there is more than one val in array).
Obstacles can be programmed in future, because now there are no obstacles in banks, on ship etc., and this difficult coding can be postponed.
So if object has set section “battlefieldProperties”, this section information will be used.
If object don’t have this section, than battlefields/obstacles will be taken depending on terrain.
Bonus of this approach:

  1. There is no need to set something for passive objects
  2. Each bank and creature dwelling will have possibility to have custom battle background/music.
  3. There is no need to enter new code for existing battlefields functioning (only to move special terrain patches battlefields to their JSON config. No need to add new mod.json sections (like “factions”, “heroClasses”, etc. Later this structure can be inputed directly to terrain config.

For example, boats will get possibility to have custom battlefields when fighting with neutrals or under attack from bank.
Terrain patches also will have custom battlefields.
For standard terrain specific battlefields only need for random choosing of current battlefield from array of terrain battlefields is welcome.

UPD About configurable battlefields.
Someone earlier said he want to see battlefield for forest, when battle is near trees.
I propose t allow user to assign battlefields properties also to decorative objects (like trees, rock, river deltas, etc).
I propose this algoritm.

  1. When battle is initiated, VCMI first will check, if hero is visiting object. If yes, then it checks if object have battlefield assigned. If yes, battlefield is taken from object.
  2. If there is terrain patch under attacked position, than special battlefields for patches will be used (taken from battlefield configuration from terrain patches).
  3. If object dont have battlefield properties, VCMI will in random direction check +1 squares around him (8 squares). If there is passive object like trees (without “A” entering square in “mask”) and it has battlefield configured, than it’s will be taken and used as background.
  4. If none is configured, that terrain battlefields will be taken (from array of terrain battlefields names, choosen randomly).

Not sure about #3 (having battlefields for landscape object is a new idea), but certainly for armed objects it’s a way to go.

First we need to have custom battlefields anywhere and then we can think of interesting mechanics and practical configuration.

Didn’t have time for anything for a while, but now I’m back. Though currently I’m decide to work on pathfinding and movement rework first because it’s what more important to make VCMI playable (proper implementation on fly / water walk require some redesign of current code) and it’s code I already familiar with. If I manage to do that then I’ll certainly go for objects because there is more flexibility needed for all kind of things; not just sound.

BTW I like suggestion about battlefields backgrounds, but main issue there is art as always.

There is a mod for ERA with additional battlefields present.
Also there are many resources with sprites from games (including battlefields), that easily can be converted to HMM3.
For example, some battlefields can be taken from RPG Maker graphs assets.
First possibility needs to be made, than content will arise :mrgreen:

That ERA mod with 50+ battlefields is well enough. It’s in fact one of core mods and it’s where this whole idea came from.