Open winex opened 8 months ago
reserved for code description
this is how i banned wheat-farms from spawning in sands and deserts, for ex:
RBGEN_CHUNKS=256/32
PARAMS_PRIMARY_INDUSTRIES = {
["tycoon-apple-farm"] = { prob = 1.0,
},
["tycoon-wheat-farm"] = { prob = 1.0, min = 0.75, max = 1.00,
tiles = {
"grass-1", "grass-2", "grass-3", "grass-4",
"dirt-1", "dirt-2", "dirt-3", "dirt-4", "dirt-5", "dirt-6", "dirt-7",
},
},
["tycoon-fishery"] = { prob = 1.0, min = 0.25, max = 0.90, radius = 1,
tiles = { "water", "deep-water" },
},
}
-- rbgen itself is called like this:
local function on_chunk_generated(event)
for _, name in pairs(Constants.PRIMARY_INDUSTRIES) do
region_based_generator(event, PARAMS_PRIMARY_INDUSTRIES[name], name)
end
end
adding new industries like potato and rice farms (wanna them :)) is just adding an entry into that table
tag placement is deferred for calls from on_chunk_charted()
(as in current release), by introducing global.tycoon_tags_queue
, which could be used for tagging cities as well or any other future type
repeatability of generation independent of explore direction even after save/load probably not going to happen as it should keep random seed for every region or seed it with coordinates XOR'd w/ something
I love that you started on this! Let me know if there's anything I can help with, or where some of my code/intentions may be unclear
switch Cities placement to use RBGen (in explore mode, future milestone?)
I'll try to get some more clarity on the path forward with cities. There has been some feedback on custom placement on cities, as well as multi-surface support. Will share more as ideas get clearer, and am happy to receive more input :)
4Kx4K map (with town generation enabled!) by rbgen
:
as game.forces.player.chart()
go spiral, placement seems too close when just checking random() < probability
.
checking if it hits into range of adjacent chunk positions inside this region should work better like: 0 <= rnd < 0.5 <= rnd < 1
, will see... otherwise, i'll just go for repeatability using region coordinates
as one may noticed - fishery probability is set to 4.0, which is kinda big - my tests shows that it just can't generate enough of them, because of very strict conditions (radius=1 makes 3x3 chunks search). this tweak helps
will try to compare this against rbgen
-disabled map
here it is! RED - old (A:54 W:54 F:56), WHITE - rbgen
(A:72 W:76 F:40, same as above):
This looks great! I can't wait to test it soon :)
Did you notice any positive/negative impact on map startup times or lag when discovering new chunks?
This looks great! I can't wait to test it soon :)
me too, better in multiplayer :)
it took more time, than i thought - lots of little creepy things! also, i've ran into some issues, which bothers me like hell - figured out the numbers and parameters for rbgen
(to be alike the old gen
), but the result just is not fine, yet (see https://github.com/bahrmichael/factorio-tycoon/issues/269#issuecomment-1976898462 )! still working on that...
Did you notice any positive/negative impact on map startup times or lag when discovering new chunks?
oooh, that's a hard question, actually! but as i always think about speed (50% optimization inplace) when writing anything, i think rbgen
is even faster, here is why:
on_chunk_charted()
was lagging - i put warning in the code - biters trigger that VERY frequently! and it was always/on each call searching for nearby entities of the same type trying to place another one(!) while it wasn't neededold gen
with "easy params" - i got lots of industries spawn nearby just by looking at the biters for a couple of minutes, not even exploring! that looked weird -- so i dug into that and we're here now! ;)rbgen
: doesn't do anything after chunk has been generated alreadyrbgen
: on_chunk_charted()
just places pending tags if there are any, nothing more!rbgen
: there are still tiles counting/searches, but it's done in actual generation step and only once per each chunk!@bahrmichael okay, if you can't wait anymore to play with it - i've just pushed WIP version winex:rbgen with lots of logging to track placement and errors, it's based off winex:pr-2
(#271)
Constants
tablerbgen
is very simple (except for number crunching there) and just called for every entry from param tablesregion_size^2
(but not recommended) - maybe try to place chests/inserters to prove it, haha? :)[water_lo_mult; water_hi_mult]
and prob
is multiplied then.water coverage needs some more testing, but my regens (from the same point) on 2Kx2K map did good for A, W, F respectively:
this corresponds to mult params. maybe we need to lower it to 1.5
~sqrt(2)
for the numbers to be close to what 100% shows (except for fisheries - they're already struggling hard with prob=4.0
)
btw, players with sand or desert maps could become sad, so it's probably going only into v0.5.0
:
"biomes" in Factorio were almost never used at all - i always thought map could be more useful (hate cliffs, though!)
looking forward to discuss your findings or even watch a stream (yeah, i've found your last one - it was cool :) )... have fun!
just for history, already fixed in https://github.com/winex/factorio-tycoon/commit/1e065bcfafe7a809d75f09e6a87ca3332a2f846c (make sure to use latest winex:rbgen
)
were testing moisture and sand-desert biases... found that players would definitely rage at me for:
by adding dirt
tiles (finally found them :)) as well as red-desert
for apples (it's like clay, so i'ts fine) - map shouldn't be so empty as above:
red-desert
is not for wheat though (future changelog: this should be stated)grass
, there should be dirt
tiles somewhere!it should be fine as wheat farms aren't starting tech (currently) - it just makes game more interesting, though i see future mod conflicts here, ex: alien-biomes
... i'd be happy to get some feedback for mod compatibility requests
we should inform players with a message of higher difficulty overall as it might be harder to find industries if map_gen_settings
has:
Water Coverage
set to 0%
=> disabledMoisture Bias
set to -0.5
=> desertTerrain type Bias
set to -0.5
=> sandok, i've got some great feedback (but it's misposted in #271), those are better to be discussed here:
rand()
exactly its bits-times (2^31
how many we got there?)0, 0, 0
0, 0, 0
of very low probability, but it is >0
params
table smash PRNG even more... ex: fisheries with insane 4.0 probability
- Fisheries very close to each other, and on an island. Maybe not ideal as it's hard to access. I'm fine with rare cases of similar industries nearby each other, but in general it should have a good distribution.
- [ ] TODO: tweak last-step placement checks. will revise this (not my code, though)
- generator itself doesn't know whether it is on island now or not - it's just too expensive to search for this
- it's PRNG - i'm trying to use all the bits of it, but there's almost nothing left we can do more about it
this is how rbgen
works (almost the same as oldgen
): 8x8 chunks = 64. chunk was generated, let it be number 42 in that region, check if random(0, 64) is inside [42; 42+prob
) range, check filtering with radius
and then try to place. placement itself (it's same 0.4.5
code) has some checks (last-step) and we should tweak that more for cliffs and other stuff
! i haven't pushed the latest WIP version, yet !
btw, i personally see such batches of industries as really nice feature (different + same, too). never aimed for that and even couldn't - there is no code for this!
ex: resource patches in Factorio are soooo evenly distributed -- they just used perlin/simplex noise of few levels (maybe only 1) and that looks very bad to me after almost 10 years of development... that's why we like rso-mod
, not to mention that it has same problem (for bigger maps), though :P
City placed on water; may prevent the city's early expansion if nearby water or cliffs or resource patches.
- [ ] TODO: didn't touch that, yet. callback needs
position
argument or some BoundingBox at least just usedCityPlanner:: addCity()
function as a proof-of-concept - it has no checks at all, lol :)This feels like there are a lot of factories close to each other in batches. Noticed this, but not sure if I'm for or against it. Just a different spawning behavior that we should think about.
- [x] see no.1 PRNG. in overall, you get a good distribution (see my large screenshots), but sometimes you'll be just out of luck
- ex: one lake might get no fisheries at all, but the one next to the right of the same size -- could get 3 fisheries around it
- i've been choosing params for
rbgen
to be statistically the same (for large maps, ofc) this takes so much time, omg! it sometimes 2x than before bywater_*_mult
, though -- should change that to about1.5
- you need to generate at least 1024x1024 (or 2048x2048) map to see much better overall picture
Industry spawned very close to resource patch, which made me wonder if they could now spawn ON resource patches. I don't like the latter, but spawning close to patches is okay.
- [x] TODO: tweak last-step placement: resources
Industry spawned next to cliff. That blocks access to the industry, until the player has cliff explosives.
- [x] TODO: tweak last-step placement: cliffs
(y%2 + x)%2
, iirc) segmentation instead of 2D (y*size + x
), but i don't think it will change anythingmap.seed
(reimplementing rand()
) MAY NOT help the overall picture of batches -- it is still just pseudo-random numbers!rand()
over bigger areas somehow, may only be possible with repeatabilitysht, this is looong
latest test with PRNG segmentation... as i thought before - it doesn't do much better :(, but a bit - yes natural exploring made this feel more interesting, though (but it takes more time)!
same as above https://github.com/bahrmichael/factorio-tycoon/issues/269#issuecomment-1979307705 4Kx4K map, A:101 W:69 F:40 T:6
starting area minimal, moisture/red-desert bias +0.5, +0.5
~0.7x
that of apples on this part of mapPARAMS
should be tweaked, but it should feel almost the same as beforerand()
without real cases feedback this is going to be pure research :P
generator itself doesn't know whether it is on island now or not - it's just too expensive to search for this
Right, I see that now, too. Let's drop that part of feedback. It was just a thought when looking at the map, but I'm happy to not add that restriction :)
just used CityPlanner:: addCity() function as a proof-of-concept - it has no checks at all, lol :)
Gotcha! I wasn't sure how much you already changed. Will look into this myself!
see no.1 PRNG. in overall, you get a good distribution (see my large screenshots), but sometimes you'll be just out of luck
Sounds good to me! Thanks for reviewing my feedback.
it feels more natural as no repetitive pattern is seen here, just bunch of: circles, lines, clusters, etc... even single ones are present in some places - this is good!
I agree!
i suppose this algo is about 95% complete in its internals, 5% goes to externals/last-step checks
Awesome!
maybe even productivity bonus curves should be lowered instead because of new industry generation possibilities
We can do that. If you want you can suggest a rebalance after/with the PR for this change.
Let me know when I should give it another try or when you want to schedule a multiplayer session :)
@bahrmichael you can try any time! :) i've pushed latest "WIP-9" version (see at the top) few days ago.
town-center-virtual
to 14x14 didn't help muchi must review all city placement functions and sync them to be alike industry placement
possible fix would be to add some delay, but ideally it should be async. otherwise, we need to ensure somehow that our on_chunk_generated()
is called only after resources are actually placed, but idk if that is possible.
resources check can fail in rare cases - when generating map really fast, an industry might be placed just before resources are
Rare cases are fine, don't worry about hardening this too much.
Some more feedback :) Love the work so far! I see that you have disabled town generation, so I didn't look at that, but just at the primary industries.
This is the map I got with some running around, default settings:
I noticed that tags show up outside of the range that I should have discovered. Maybe that's related to tag placement, which we may want to defer to the on_chunk_charted
handler?
I also noticed that the coloured backgrounds aren't always matching the selection area. It would be nice to have them matching, or at least be consistent around the icons.
Wanted to share some explanation on how I (try to) prevent cities on water:
When placing a city, we generate a bunch of locations, and check the tiles in the area.
Water (and other less desirable tiles) are counted and with the power of 2 added to the weight of all possible locations.
We then finally sort the options by weight, and pick the best result.
This can lead to towns on water, but it's unlikely. If you didn't touch this code, then don't worry about rare towns on water. Sorry for not pointing that out earlier!
Some more feedback :) Love the work so far! I see that you have disabled town generation, so I didn't look at that, but just at the primary industries.
?! no, i didn't disable town generation. should work still, it's just rbgen_stats_...
don't support multi-surface/surface_index
, yet
can you point what else you've spotted?
I noticed that tags show up outside of the range that I should have discovered. Maybe that's related to tag placement, which we may want to defer to the
on_chunk_charted
handler?
feature, same as in rso-mod
by forcing game.forces.player.chart()
(why it can't show code here?!):
https://github.com/winex/factorio-tycoon/blob/18d1ecd337bd25d3e7d5fbcf77dc7acac4166053/chunk-charted-handler.lua#L206-L208
i think it's nice that it pops out while you're exploring - you'll never miss what you're trying to find
I also noticed that the coloured backgrounds aren't always matching the selection area. It would be nice to have them matching, or at least be consistent around the icons.
feature - apples are red, wheat is yellowish, town halls are green (saturated) -- it helps to distinguish them in the map view zoomed out and when it's uncharted. it looks a bit strange with icons, but it's because entities are large ~14x14.
we can color treasury
entity so it's easier to find it on map, too :)
Wanted to share some explanation on how I (try to) prevent cities on water:
thanks for pointing this, i'll try to use this function with limited radius (to be inside region) somehow...
it's just rbgen
works the other way around - it checks each chunk if conditions are met to be filled w/ something - similar to autoplace
thing. towns are rare, though, so we can do more stuff
?! no, i didn't disable town generation. should work still, it's just rbgenstats... don't support multi-surface/surface_index, > yet can you point what else you've spotted?
This is what I meant: https://github.com/winex/factorio-tycoon/blob/rbgen/city-planner.lua#L491-L493
I commented this out and everything worked fine.
This is what I meant: https://github.com/winex/factorio-tycoon/blob/rbgen/city-planner.lua#L491-L493
I commented this out and everything worked fine.
this is build_initial_city()
as per Spawn Initial City
option.
town generation by rbgen
should work fine
multiple surfaces was not intended to be supported by my (should-be-) fast Util::chunkToHash()
function, so moving from number
to string
type was required. it is slower, but until FactorioLua provides integers or at least >32-bit bitwise operators (bit52
, lol), this will work in some way...
global.tycoon_rbgen_stats
on 2Kx2K map now looks like this, cool isn't it?:
4119.323 Script log(serpent.block(global.tycoon_rbgen_stats)):1: {
true,
["tycoon-apple-farm"] = {
["0001fffd0002"] = 1,
["0001fffefffd"] = 1,
["0001fffefffe"] = 1,
["0001ffff0000"] = 1,
["0001ffff0003"] = 2,
["0001ffff0004"] = 1,
["0001ffffffff"] = 1,
["00010000fffc"] = 2,
["00010001fffc"] = 1,
["00010002ffff"] = 2,
["00010003fffd"] = 2,
["00010003ffff"] = 1,
["000100000003"] = 1,
["000100010000"] = 1,
["000100010005"] = 1,
["000100020000"] = 1,
["000100020001"] = 2,
size = 8
},
["tycoon-fishery"] = {
["0001fffcfffc"] = 1,
["0001ffff0002"] = 2,
["0001ffff0006"] = 1,
["00010001fffc"] = 1,
["00010002fffe"] = 1,
["000100000001"] = 1,
["000100010004"] = 1,
["000100030003"] = 1,
size = 8
},
["tycoon-town-hall"] = {
["0001ffff0000"] = 1,
["0001ffffffff"] = 1,
["000100000001"] = 1,
size = 32
},
["tycoon-wheat-farm"] = {
["0001fffc0002"] = 2,
["0001fffcfffc"] = 1,
["0001fffcfffd"] = 1,
["0001fffd0000"] = 1,
["0001fffd0001"] = 1,
["0001ffff0002"] = 1,
["0001fffffffc"] = 1,
["00010000fffc"] = 1,
["00010000fffe"] = 1,
["00010000ffff"] = 1,
["00010001fffd"] = 1,
["00010001fffe"] = 1,
["00010001ffff"] = 1,
["00010003fffc"] = 1,
["00010003fffd"] = 1,
["00010003ffff"] = 1,
["000100000005"] = 1,
["000100010006"] = 2,
["000100020001"] = 1,
["000100020003"] = 1,
["000100020004"] = 1,
size = 8
}
}
iirc, this is count of named entities per region
first is global.tycoon_rbgen_stats[surface.index] = true
to allow rbgen
on this surface -- idk if it bugs any for ... in pairs()
loops, yet. maybe should move it deeper
region size
is in chunks, i thought we should remember it for future possibility of changing it, then a RBGen.rescan()
could be easily called just by comparing values
this stats table is also used to limit anything internally... 48-bit fit into 12 chars means:
i think we should use this for surface-modified TagsQueue
also, but it's not necessary
@winex Just wanted to check in with you about your plans for the rbgen. I'm thinking about releasing 0.5 within 2-3 weeks, shall we include rbgen there?
i'm currently working on "Region Based Generator" (aka
rbgen
) similar whatrso-mod
has (Resource Spawner Overhaul)WIP branch: winex:rbgen (might be force-pushed frequently) -- edit: WIP-12 is new
current progress:
on_chunk_generated()
and do less in very frequently calledon_chunk_charted()
repeatability of generation independent of explore direction even after save/loadprobably not going to happen (see in first comment)map_gen_settings
combinations: water 0%/disabled = unplayable, sand deserts bias, etc... (see reports in comments below)mod support:
space-exploration
, blacklist non-solid SE surface types -- preliminary support:planet
,moon
almost done, WIP, ?:
testing
params
(see reports in comments below)map_gen_settings
(see reports in comments below)chart()
) -- looks even better!gather feedback
params
(not for players, though)map_gen_settings
(might missed some combinations)description
it's actually very simple and look really universal, uses simple configuration and supports any (well, if fits into region) amount of entries that doesn't depend on each other's numbers
it even supports filters in a single table. for each
rbgen
there should be region size, then a table of entity probabilities, tile names, etc.@bahrmichael pls, label: enchancement, assign: winex
early alpha screenshot, looks very nice to me (notice close industries, but overall randomness):