Polls

Best Build 21 Screenshot

Log in to vote!

Currently Online

Latest Posts

Topic: Making wild animals reproducible

Solstice_s_Return
Avatar
Joined: 2020-01-28, 13:24
Posts: 57
Ranking
Likes to be here
Location: Finland
Posted at: 2020-02-22, 21:34

Nordfriese wrote:

We should have a look that we don't make to little changes we wont see later or recognize in game but have high programming work

Good point.

In my opinion, we should keep the effect on the game small. This means no fancy things which are hard to implement. But the following should be pretty easy to code:

  • give each critter a tag "herbivore"/"carnivore"

  • when a critter with carnivore tag enters a field with one or more herbivores on it, one herbivore is eaten with say 25% chance

  • when a critter with herbivore tag enters an immovable with the new "herbivore_food" tag (given to Tiny, Small and Medium fields only), the immovable's currently running program step runtime is increased by say 5s

  • critters remember their creation gametime and die when they reach a critter-specific lifetime defined in their init.lua

  • when a critter enters a field, and there is another critter of the same type on it, and both critters are at least say 20 minutes old, and there is also an immovable tagged "tree_any_growth_stage" on it, another critter of the same type is spawned on the field with say 25% chance

Those should be pretty easy to implement and are worth the effort even if the impact on the game is small. More complex models are not really worth their effort IMHO.

+1 I think it would be nice thing to have it as described above even after considering the arguments posted after Nordfriese's suggestions. It adds to the game world and is a nice detail to discover as was the natural tree growth cycle for me when I recognized it the first time and I still think it is very nice. This thing won't have such a high impact to gameplay even if it makes critter population grow or shrink. I still think it would be the most great if the effect can be slowly visible if a player maintains big enough forest/chops most of all trees down as usually happens, but If not, even then it would be a nice detail to discover and adds to the game that way.


Top Quote
king_of_nowhere
Avatar
Joined: 2014-09-15, 18:35
Posts: 1646
Ranking
One Elder of Players
Posted at: 2020-02-22, 22:53

Nordfriese wrote:

In my opinion, we should keep the effect on the game small. This means no fancy things which are hard to implement. But the following should be pretty easy to code:

  • give each critter a tag "herbivore"/"carnivore"

  • when a critter with carnivore tag enters a field with one or more herbivores on it, one herbivore is eaten with say 25% chance

  • when a critter with herbivore tag enters an immovable with the new "herbivore_food" tag (given to Tiny, Small and Medium fields only), the immovable's currently running program step runtime is increased by say 5s

  • critters remember their creation gametime and die when they reach a critter-specific lifetime defined in their init.lua

  • when a critter enters a field, and there is another critter of the same type on it, and both critters are at least say 20 minutes old, and there is also an immovable tagged "tree_any_growth_stage" on it, another critter of the same type is spawned on the field with say 25% chance

i worry that this would make it too hard for an herbivore population to recover when reduced in number. it makes reproduction much more difficult. in ecosystems, reproductive rate of existing members is not impacted too much by depleting population. I would therefore remove the need for another animal to reproduce and just have herbivores spawn spontaneously.

also, to avoid predators going extinct and then prey going wild, i'd add a clause that the animal won't spawn if there is another similar one nearby. so, i'd make the condition like that

prey: "every 10 minutes spawn with a 25% probability unless there is another similar animal within 5 corners" predator: "if comes in contact with prey, kill prey with 50% chance. if it killes 2 prey in less than 10 minutes, 25% chance of spawn. if it does not eat for 30 minutes, 25% chance of death. 50% chance of death every other 10 minutes until it eats again".


Top Quote
JanO
Avatar
Joined: 2015-08-02, 11:56
Posts: 147
Ranking
At home in WL-forums
Posted at: 2020-02-23, 08:40

Nordfriese wrote:

Good point.

In my opinion, we should keep the effect on the game small. This means no fancy things which are hard to implement. But the following should be pretty easy to code:

  • give each critter a tag "herbivore"/"carnivore"

  • when a critter with carnivore tag enters a field with one or more herbivores on it, one herbivore is eaten with say 25% chance

  • when a critter with herbivore tag enters an immovable with the new "herbivore_food" tag (given to Tiny, Small and Medium fields only), the immovable's currently running program step runtime is increased by say 5s

  • critters remember their creation gametime and die when they reach a critter-specific lifetime defined in their init.lua

  • when a critter enters a field, and there is another critter of the same type on it, and both critters are at least say 20 minutes old, and there is also an immovable tagged "tree_any_growth_stage" on it, another critter of the same type is spawned on the field with say 25% chance

Those should be pretty easy to implement and are worth the effort even if the impact on the game is small. More complex models are not really worth their effort IMHO.

Would it make sense (to the game, not for realism) to not have static probabilities here but instead calculate them based on the number of individuals of the involved species in the area around? Like this:

  • probability = 2/(1+[individuals in within radius 2])+4/(2+[individuals within radius 5])

At least we need something to prevent herbivores which stay a while on one field together to start into mass-reproduction


Top Quote
Nordfriese
Avatar
Joined: 2017-01-17, 18:07
Posts: 956
Ranking
One Elder of Players
Location: 0x55555d3a34c0
Posted at: 2020-02-23, 11:15
  • probability = 2/(1+[individuals in within radius 2])+4/(2+[individuals within radius 5])

+1
should also be easy to code


Top Quote
hessenfarmer
Avatar
Joined: 2014-12-11, 23:16
Posts: 1439
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2020-02-24, 12:51

I am still not convinced whether this would not produce a very high CPU load. As far as I know we still officially support Netbooks (from a resolution point of view and therefore from a processor load as well).
To calculate this we have to check either all critters or all nodes every second to calculate this this would be very CPU intensive as far as I remember from calculating valuable fields for territorial and woodgnome win condition.


Top Quote
Nordfriese
Avatar
Joined: 2017-01-17, 18:07
Posts: 956
Ranking
One Elder of Players
Location: 0x55555d3a34c0
Posted at: 2020-02-24, 13:55

To calculate this we have to check either all critters or all nodes every second to calculate

No. It would be enough that every critter checks this autonomously whenever it enters a node and goes into idle mode.


Top Quote
hessenfarmer
Avatar
Joined: 2014-12-11, 23:16
Posts: 1439
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2020-02-24, 14:41

Nordfriese wrote:

To calculate this we have to check either all critters or all nodes every second to calculate

No. It would be enough that every critter checks this autonomously whenever it enters a node and goes into idle mode.

Hm, from the discussion I was not aware that this should only happen in idle mode.
Assuming this should happen whenever 2 critters arrive at the same field I simply assumed a wlaking time of 0.8 secs between fields. together with an idle time of probably 1 sec (couldn't identify the correct value in the code) I assumed a mean time of 1 sec for calcualtion which seems not to far away. Furthermore the whole thing would runaway with herbivores as barbarian gamekeepers only produce herbivores. Furthermore this would need to consider size of the critter as it would not make sense if a fox could eat a wisent for example. So this in total is more complicated that it seems.
Still not convinced of effects on computing I could live with a simplified mechanism that gives critters let's say a 5% chance of replicating themselves, if a total number dependant on map size is not reached.


Top Quote
Nordfriese
Avatar
Joined: 2017-01-17, 18:07
Posts: 956
Ranking
One Elder of Players
Location: 0x55555d3a34c0
Posted at: 2020-02-24, 14:57

The current behaviour of all animals is that they pick a destination within a radius of 2 fields, go there, idle for a random time between 1000 and 3000 milliseconds, then pick the next destination and so on. This is defined in Critter::roam_update.

Implementing reproduction, carnivory, herbivory, and animal death would all go into this function, where their effect on CPU load is negligible. Querying the map for bobs and immovables on a certain field or within a modest radius is a very CPU-efficient task that is done all the time by workers/buildings with work areas.
(compare this nice, small function e.g. with the huge code blocks in workers' …_update() functions.)

Edited: 2020-02-24, 14:58

Top Quote
hessenfarmer
Avatar
Joined: 2014-12-11, 23:16
Posts: 1439
Ranking
One Elder of Players
Location: Bavaria
Posted at: 2020-02-24, 16:03

Nordfriese wrote:

The current behaviour of all animals is that they pick a destination within a radius of 2 fields, go there, idle for a random time between 1000 and 3000 milliseconds, then pick the next destination and so on. This is defined in Critter::roam_update.

Implementing reproduction, carnivory, herbivory, and animal death would all go into this function, where their effect on CPU load is negligible.

Maybe this would be doable. However currently I beleive the critter does not know where he is, so while moving he would need in every step if there is another critter on its current field so we would need to implement this in in the Bob's program to move around.

Querying the map for bobs and immovables on a certain field or within a modest radius is a very CPU-efficient task that is done all the time by workers/buildings with work areas.

Difference is that this is only called once or twice in a working program of around 50 to 100 seconds. Furthermore in large maps critters might get very numerous until a hunter arrives. We have maps where already a lot of critters are placed from map designers. So this may get bigger then you think, but we could try this and do some measurements.

Still we need to implement size of critter to make this work properly. Alternatively we could define the critters to be hunted by carnivores.


Top Quote
Nordfriese
Avatar
Joined: 2017-01-17, 18:07
Posts: 956
Ranking
One Elder of Players
Location: 0x55555d3a34c0
Posted at: 2020-02-24, 16:18

However currently I beleive the critter does not know where he is

Yes he does: Bob::get_position()

And he has simple access to all other bobs on his field with this standard iteration loop:

for (Bob* bob = get_position().field->get_first_bob(); bob; bob = bob->get_next_bob()) {
    if (bob != this) {
        if (upcast(Critter, critter, bob) {
            log("Other critter found :)");
        }
    }
}

And such checks are very efficient, C++ is really fast.

Alternatively we could define the critters to be hunted by carnivores

I think this would be best. Critters would get an array of names of critters they can eat in the init.lua. An empty array would indicate herbivores (who eat fields), no value given means no interactions at all (like ducks).

EDIT: How about I just make a branch with this (expected effort: <<1h) and then we can test it face-wink.png

Edited: 2020-02-24, 16:26

Top Quote