bvschaik / julius

An open source re-implementation of Caesar III
GNU Affero General Public License v3.0
2.79k stars 311 forks source link

Adding some pseudo-random noise into roaming. #715

Closed serg-bloim closed 7 months ago

serg-bloim commented 8 months ago

The issue: It is VERY easy to create situations where roaming figures will always choose the same turns and never visit other areas. But the code and all the forums tell it should be done randomly. But it is deterministic.

Every turn is determined by three things: location of the building, location of the figure and distance it made so far. As you may see, all these things are constant for every figure at every point in time. It may look that figure does change decisions, but in fact there's just 4 patterns that every figure repeats again and again. They are like Neo from matrix that is given a choice, not knowing the answer is predetermined. Moreover, you may have a really lucky seed and all your roamers cover the city pretty well, but after a reload it will change and things may fall apart.

My proposal doesn't use real randoms, it is still a deterministic approach. But in this case the number of factors increase dramatically. Basically every other figure in the game contributes to turn decision. It's like a butterfly effect and should be a great boost for roamers' free will.

P.S. I'm not a C programmer, and assume my code may be wrong, especially I'm not sure about two things:

QuakeIV commented 8 months ago

Integer overflow is OK in C.

QuakeIV commented 8 months ago

I'm not actually an admin, just commenting anyways because why not.

IMO this actually seems like a pretty slick way to do this, I suppose the only real question is whether the mechanic is appropriate or not. I'd say maybe. In the past it was sortof a weird minigame where you try to engineer the walk paths, hence the determinism, but I never cared for it. Regarding it being undocumented, I could swear I remember mention of it in the manual somewhere back when I was a kid (long gone so cant check it).

bvschaik commented 8 months ago

Thanks for the suggestion.

However, the goal of this project is to recreate the original behaviour from Caesar 3 as-is. You can also see that from the failing tests which check Julius behaviour against Caesar 3 behaviour. So, therefore I will not merge your change. You can try whether Augustus will accept your change though.

But the code and all the forums tell it should be done randomly.

On the HeavenGames forums, it's been known for a long time that the "roaming walkers" (which is the proper term, according to the original game developers themselves!) have a deterministic algorithm behind them. To the untrained eye, they might appear random, hence why most people call them "random walkers".

Regarding the code: I'm curious where you see "random" related to walkers, as far as I know I used "roaming" where needed.

Regarding your questions:

is declaring a global variable ok?

In this project, yes. In general it's frowned upon since it makes functions not thread-safe and/or not re-entrant.

I rely on integer overflow. I assume there's no error/exception if overflowing an integer in C?

Nope. Like QuakeIV says, it's fine in C. It just wraps around. In your case with a short, it will wrap from +32767 to -32768.

serg-bloim commented 8 months ago

Regarding the code: I'm curious where you see "random" related to walkers, as far as I know I used "roaming" where needed.

You're right, there's none. I missed the fact it saves/loads the random.items into a save file. So it must keep the routes even after a reload.

bvschaik commented 7 months ago

Closing due to the reasons listed in my previous comment.