-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rare specials accidentally became too frequent #73618
Comments
Oh no... @kevingranade already went into a strange mood over this once |
Should we also ping the one who reviewed and merged the pull request - @Maleclypse ? |
So, the difference between UNIQUE and GLOBALLY_UNIQUE would be that the former would continually roll chances to place and add new entries to the "to be placed" pool, while the globally unique would have a fixed count to place, and once that number has been rolled, it's a matter of placing the remaining ones as soon as possible? It might be suitable to issue a debug warning if the "to be placed" count starts to climb, as that would indicate the thing is too picky (or too many are requested). I might have missed it, but there needs to be something to ensure the complete backlog isn't dumped onto the same overmap (say you've got something that needs to be away from cities, but the first 10 overmaps generated are all cluttered with cities, and then you generate a plains one, and suddenly dump 11 overmaps' worth of the thing onto it). |
As far as I understand a special with the GLOBALLY_UNIQUE flag is supposed to spawn only once per world. It would indeed try to draw it from the deck once per overmap until it succeeds. Once successfully drawn the GLOBALLY_UNIQUE special would be placed as soon as possible. I.e the "fixed count" of a globally unique special is (to the best of my knowledge) always 1. |
Already taken care of (emphasis mine):
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. Please do not bump or comment on this issue unless you are actively working on it. Stale issues, and stale issues that are closed are still considered. |
Oh crap missed this with the flood of other issues, and not particularly watching for mentions. Having said that I did finally see it because I checked my mentions. Thanks for this, I very much missed that we were only placing one unique per overmap, that explains a lot of things that were frustrating me. I can try and tackle implementing your proposal, algorithm and data wise it's not all that different from what I already attempted. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. Please do not bump or comment on this issue unless you are actively working on it. Stale issues, and stale issues that are closed are still considered. |
Is your feature request related to a problem? Please describe.
Specials with
UNIQUE
orGLOBALLY_UNIQUE
flag define how frequently they should spawn. For example"occurrences": [ 2, 100 ]
means the special should spawn in about 2 put of 100 overmaps. This allows some specials to be relatively rare and others to be relatively common.overmap::place_specials()
used to simply rollx_in_y(...)
(e.g. 2 in 100) for each UNIQUE or GLOBALLY_UNIQUE special to decide whether to attempt to place it on the current overmap or not. This attempt is not guaranteed to be successful and the success chance depends on how picky the special is - some specials find valid places to spawn easier than others.There were two issues with this implementation:
The overmap_terrain_coverage test only generates 300 overmaps. By my calculations there is about 2% chance that at least one spacial will fail all 300 x_in_y rolls (an outlier, but more common than we would like):
Because some specials are harder to place, their real frequency was lower than the intended frequency from their defenition.
#73339 attempted to improve this:
Here is the formula we are now using:
x_in_y(X/special_count, Y/overmap_count)
(i.e.rng_float( 0.0, 1.0 ) <= (X/special_count) / (Y/overmap_count)
), where the intended frequency is X in Y (e.g. X=2, Y=100), special_count is the number of times the special was successfully placed (or 1 if the number is zero to avoid div by zero), overmap_count is the number of overmaps generated so far (or 1 if the number is zero).A bit of algebra:
I see two issues in the current implementation:
Despite 73339 claiming that the chance of occurrence is dialed down for specials that happen to spawn more frequently than intended, it never dials the chance of occurrence below X in Y. Proof:
This change had accidentally rebalanced rare specials to be much more common than intended:
@kevingranade
Solution you would like.
overmap::place_specials()
will rollx_in_y(x_remains, y_remains)
On success both x_remains and y_remains are decremented by one and to_place is incremented by one. On fail y_remains is decremented by one. This is equivalent to drawing without replacement from a deck of Y cards out of with X contain the special and the rest are emptyDescribe alternatives you have considered.
Another approach I have considered was to adjust the current formula to have the correct equilibrium:
This should have:
The downsides:
The success of the overmap_terrain_coverage test is not guaranteed
This approach reduces, but does not eliminate the effect that the probability of successful placement has on the real distribution of the specials making it harder for content creators to correctly balance the specials:
Additional context
No response
The text was updated successfully, but these errors were encountered: