Latest Posts

Topic: How can I replace immovables?

tothxa
Avatar
Topic Opener
Joined: 2021-03-24, 12:44
Posts: 434
OS: antix / Debian
Version: some new PR I'm testing
Ranking
Tribe Member
Posted at: 2021-11-23, 01:52

I'm trying to learn how to create addons by implementing https://www.widelands.org/forum/topic/5458/ but I ran into some problems when I tried to test it. I attached my code for Empire coal mine.

Problem 1: How to replace a unit?

When I try to start a game with this addon, it fails with this error:

[00:00:31.063 real] ERROR:   FATAL EXCEPTION: Error while loading tribe 'amazons':
DescriptionManager::register_description: Attempt to register description
[00:00:31.063 real] ERROR:    name: 'empire_resi_coal_1'
[00:00:31.063 real] ERROR:    script: 'tribes/immovables/resi/empire/init.lua'
[00:00:31.063 real] ERROR: but the object has already been registered to
[00:00:31.063 real] ERROR:    script: 'addons/perma-resi.wad/resi/empire/coal_1/init.lua'

What am I doing wrong? Or may this be a bug in the unit replacement code? Unfortunately I couldn't find an example for replacing units, only for adding new ones. I'm not even sure if I need modify_unit at all, because I get the same error even if I remove it from postload.lua.

Problem 2: Multiple units in the official resource indicator definitions

Before the above error message, the following warnings are logged:

[00:00:31.063 real] WARNING: Unused key "empire_resi_coal_2" in LuaTable. Please report as a bug.
[00:00:31.063 real] WARNING: Unused key "empire_resi_gold_1" in LuaTable. Please report as a bug.
[00:00:31.063 real] WARNING: Unused key "empire_resi_gold_2" in LuaTable. Please report as a bug.
[00:00:31.063 real] WARNING: Unused key "empire_resi_iron_1" in LuaTable. Please report as a bug.
[00:00:31.063 real] WARNING: Unused key "empire_resi_iron_2" in LuaTable. Please report as a bug.
[00:00:31.063 real] WARNING: Unused key "empire_resi_none" in LuaTable. Please report as a bug.
[00:00:31.063 real] WARNING: Unused key "empire_resi_stones_1" in LuaTable. Please report as a bug.
[00:00:31.063 real] WARNING: Unused key "empire_resi_stones_2" in LuaTable. Please report as a bug.
[00:00:31.063 real] WARNING: Unused key "empire_resi_water" in LuaTable. Please report as a bug.

These warnings go away if I edit the main definitions in data/tribes/immovables/resi and move the redefined units to separate directories, but the error remains. It looks as if when coal_1 is replaced, all others registered at the same time are removed as well. I figure it may prevent redefining these units, and so I think it is a bug in these data files, because when I first copied the data/tribes/immovables/resi directory to the addon, and edited the register.lua-s and init.lua-s for all tribes, adding __replace_if_exists to all registrations gave me the following warnings:

[00:00:00.610 real] WARNING: The registry file addons/perma-resi.wad/resi/atlanteans/register.lua
[00:00:00.610 real] WARNING:     defines multiple (10) units: atlanteans_resi_coal_1 atlanteans_resi_coal_2
atlanteans_resi_gold_1 atlanteans_resi_gold_2 atlanteans_resi_iron_1 atlanteans_resi_iron_2 atlanteans_resi_none
atlanteans_resi_stones_1 atlanteans_resi_stones_2 atlanteans_resi_water
[00:00:00.610 real] WARNING:     Defining multiple units in one file is error-prone. Every unit should be defined in a
registry directory of its own.
[00:00:00.610 real] WARNING: The registry file addons/perma-resi.wad/resi/barbarians/register.lua
[00:00:00.610 real] WARNING:     defines multiple (10) units: barbarians_resi_coal_1 barbarians_resi_coal_2
barbarians_resi_gold_1 barbarians_resi_gold_2 barbarians_resi_iron_1 barbarians_resi_iron_2 barbarians_resi_none
barbarians_resi_stones_1 barbarians_resi_stones_2 barbarians_resi_water
[00:00:00.610 real] WARNING:     Defining multiple units in one file is error-prone. Every unit should be defined in a
registry directory of its own.
[00:00:00.611 real] WARNING: The registry file addons/perma-resi.wad/resi/empire/register.lua
[00:00:00.611 real] WARNING:     defines multiple (10) units: empire_resi_coal_1 empire_resi_coal_2 empire_resi_gold_1
empire_resi_gold_2 empire_resi_iron_1 empire_resi_iron_2 empire_resi_none empire_resi_stones_1 empire_resi_stones_2
empire_resi_water
[00:00:00.611 real] WARNING:     Defining multiple units in one file is error-prone. Every unit should be defined in a
registry directory of its own.
[00:00:00.611 real] WARNING: The registry file addons/perma-resi.wad/resi/frisians/register.lua
[00:00:00.611 real] WARNING:     defines multiple (10) units: frisians_resi_coal_1 frisians_resi_coal_2
frisians_resi_gold_1 frisians_resi_gold_2 frisians_resi_iron_1 frisians_resi_iron_2 frisians_resi_none
frisians_resi_stones_1 frisians_resi_stones_2 frisians_resi_water
[00:00:00.611 real] WARNING:     Defining multiple units in one file is error-prone. Every unit should be defined in a
registry directory of its own.

In this case the unused key warnings were for the Amazon resis, and the error was with the Amazon gold_1 resi.


Attachment:
perma-resi.zip (3.5 KB)

Top Quote
Nordfriese
Avatar
Joined: 2017-01-17, 18:07
Posts: 1927
OS: Debian Testing
Version: Latest master
Ranking
One Elder of Players
Location: 0x55555d3a34c0
Posted at: 2021-11-23, 08:49

I had a quick look at the attached file – what you are doing is to create some new immovables, but you're not adding a link between these items and the immovables placed by the geologist.

There are three ways to achieve what you want:

  1. The "brute-force"-way is to register a new description in your add-on with the exact same name as the original item and the "__replace_if_exists" directive.

  2. The more elegant way is to instead alter the original unit's properties using modify_unit. Unfortunately this is not supported for plain immovables yet.

  3. Or you can instead use modify_unit to change the tribe's resource indicators mapping, so that the tribe uses your immovables instead of the default units.

Let me know if you want me to add modify_unit support in C++ for any or all of these properties.

The "multiple units in one file" errors happen because the official resi definitions themselves have not yet been converted to the new format. As long as this has not been done, you'll need to batch-replace all resource indicators of a tribe at the same time or there will be bugs.


Top Quote
tothxa
Avatar
Topic Opener
Joined: 2021-03-24, 12:44
Posts: 434
OS: antix / Debian
Version: some new PR I'm testing
Ranking
Tribe Member
Posted at: 2021-11-23, 10:18

Nordfriese wrote:

I had a quick look at the attached file

Thank you.

– what you are doing is to create some new immovables, but you're not adding a link between these items and the immovables placed by the geologist.

Is that possible with modify_unit("tribe", ...)? I was able to find (eventually face-smile.png ) that this is done in the tribe's units.lua in the resource_indicators table, and also that the geologist's program is all done in C++ (though that doesn't matter for this addon). I think the relevant C++ function is do_modify_tribe() in scripting/lua_root.cc, but that only implements add_ware, add_worker, add_building and add_immovable.

There are three ways to achieve what you want:

  1. The "brute-force"-way is to register a new description in your add-on with the exact same name as the original item and the "__replace_if_exists" directive.

As far as I was able to figure it out this is the only way that may (should?) be possible with the current code, because modify_unit("immovable", ...) has no implemented property. But as you can see, I failed, and I'm not even sure if it's my fault or a bug in the C++ code. Actually, as the item definition in my addon is copied from the official one, and it is found by Widelands, I think it is more probable that it's a bug. Could you please check it? (It's the same with v1.0 and a fairly current development version)

  1. The more elegant way is to instead alter the original unit's properties using modify_unit. Unfortunately this is not supported for plain immovables yet.

Yes, I saw that. It is far from ideal to copy the whole item definition just to change 5% of it. However it's not just the main program I'm trying to modify, but I'd also like to add an attribute, because currently resis only have the resi attribute, but not the resource.

  1. Or you can instead use modify_unit to change the tribe's resource indicators mapping, so that the tribe uses your immovables instead of the default units.

That would be quite a big change to modify_unit, wouldn't it? And it would still need copying the unmodified parts of the resi definition.

Let me know if you want me to add modify_unit support in C++ for any or all of these properties.

Well, I hoped it would be possible to do it with the current code. But modifying immovable programs (2.) is clearly something that will be needed by some addon sooner or later. I may try to do it though, based on #4866.

But how should I handle the attribute issue? I think it would make sense to add the indicated resource as attribute to resis in the official definition. Is that OK? If not, it seems quite a big change to modify_unit... as far as I was able to make it out, changing attributes isn't implemented at all even in C++. Though it also may be useful for other addons as well.

BTW, is it possible to use multiple attributes in findobject? I wasn't able to follow the code all the way through, but I don't think it is. If that's correct, then I'd go with "resi", "resi_coal" instead of "resi", "coal" which would otherwise be more elegant.

The "multiple units in one file" errors happen because the official resi definitions themselves have not yet been converted to the new format. As long as this has not been done, you'll need to batch-replace all resource indicators of a tribe at the same time or there will be bugs.

I tried it, but it doesn't work. (see the original post)

Edited: 2021-11-23, 14:36

Top Quote