Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 2 [3] 4 5 ... 24

Author Topic: DFHack plugin embark-assistant  (Read 94243 times)

PatrikLundell

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #30 on: August 03, 2018, 05:15:01 am »

Thanks for the kind words, clinodev. The whole purpose of this kind of tools is to allow people to get to the game bit by reducing the trial-and-error bit, and philosophically I'm more into handing people fishing rods so they can fish for themselves than giving them fish.
Logged

taleden

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #31 on: August 03, 2018, 09:15:24 am »

I don't think it would be easy to get those alternatives in.

Fair enough, maybe not worth the effort. Just thought I'd pitch the idea in case it was feasible, since I imagine folks could put it to a number of uses, not just my weapons metal and fuel examples.

The Matching World Tiles should be that, i.e. the number of world tiles that have at least one match in them. The number starts high as the first pass counts all tiles that are not incapable of having a match (e.g. requiring clay, and there's no clay in any of the mid level tiles). The detailed pass then removes the ones that do not have any match in them.
Unless there's a bug, each matching world tile should be marked on the middle map (the one labeled "Region" by DF), first with a yellow "X" after the tentative pass, and then a green one when the final check has been made (assuming there was a match: otherwise the marker is removed, of course). If those markers are missing, there's a bug somewhere.
I think my confusion comes from the mismatching terminology. You're using "world tile" to refer to a tile on the middle map, and yes, that's the one where I see initial yellow Xs and final green Xs, and the number of those Xs does indeed match what's reported by the plugin on the right. The thing is, DF itself labels the middle map "Region" and the right map "World", while your plugin refers to the middle map as "World". So just changing the text to be "Region Tiles" would avoid the confusion. (I get that in the DF mod dev world there are various conventions for referring to world/region/local/fortmode tile zoom levels, but from the user perspective all they know is what labels are shown on-screen, so it's weird when those don't agree with eachother.)

The reason there are no indications on the World map (the rightmost one) is that I haven't been able to replicate the logic DF uses to squash multiple tiles into one for display: I've come fairly close, but that's not good enough.
From my very limited experimentation it seemed to me that it just depends on world size. In a "small" world there seem to be 2 region tiles per world tile; "medium" has 3, "large" has 5. I think. But I guess maybe they're not evenly divisible? I guess that'd be easy enough to test by just counting the dimensions of each map for each world size. Anyway, yeah, it's that right-hand world map that would be great to get Xs on; right now in a medium or large world if your search turns up just a few results, it takes awhile to hunt around and find them on the region map.

EDIT: Okay, did some testing, of course it's not so simple. The world map displayed size appears to depend on the window size, so for example for me a "small" world in a maximized window has a 32x32 world map, but if I shrink the window down DF will eventually switch to a 22x22 world map to leave more room for the region map. However, the mapping of region tiles to world tiles seems to be consistently simple: if the dimensions don't divide evenly, any extra region tiles are folded into the east-most column and south-most row of the world map. For example, here are the dimensions I checked at my maximized resolution:

Code: [Select]
size    region  world  ratio  distribution
------  ------  -----  -----  ------------
Pocket    17      17    1     1,1,...,1
Smaller   33      33    1     1,1,...,1
Small     65      32    2.03  2,2,...,3
Medium 129      43    3     3,3,...,3
Large 257      51    5.04  5,5,...,7

The Pocket, Smaller and Medium dimensions all divide equally so each world map tile represents the same number of region map tiles, but in the Small and Large worlds the mapping was 2:1 and 5:1 respectively for all but the last row/column, where it was 3:1 and 7:1 to round out the leftovers.

So I think if you're able to detect the displayed world map dimensions at any given time, you can convert a region coordinate to a world coordinate like so (using integer division with implicit FLOOR):

Code: [Select]
worldX = MIN(regionX / (regionW / worldW), worldW - 1)
« Last Edit: August 03, 2018, 09:52:12 am by taleden »
Logged

PatrikLundell

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #32 on: August 03, 2018, 11:00:01 am »

I'm trying to move away from using the term "Region" because of terminology confusion. However, a World Tile is a fairly established terminology for the actual top level tiles in the world: those are the tiles you actually move between on the world level. The fact that DF's World display squashes those into a smaller number based on display size doesn't change the underlying technical entity. Calling those Region Tiles would definitely confuse things as that term is usually used to refer to Mid Level Tiles (the ones on the Local map), but not always, and not by everyone.

I tried a number of different matches for the squashing, including leaving the "remainder" at the end, and almost, but not quite, managed to get it to match as I resized the game window with different sized maps. The logic has to cover any size world (ideally including non standard ones) combined with any window size (at least down to the default one). I failed to predict when DF would switch resolution, for instance: being correct to within 1 isn't good enough.
Logged

taleden

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #33 on: August 03, 2018, 01:39:28 pm »

I understand where you're coming from and I don't want to keep arguing the same point, but let me just state the case this way and leave it at that: the broader user base doesn't know (and, I think, shouldn't have to know) what the game's world data structures look like or that the right-hand map tiles aren't actually "real" but are just sampled on the fly from a varying area of "real" top-level tiles from the center map. What the broader user base knows is that the center map is labeled "Region", the right-hand map is labeled "World", and the wiki agrees with that terminology by i.e. referring to world sizes by their "region tile" dimensions. So I get that using the label "Matching Region Tiles" maybe feels icky to an internals developer who knows why that's kind of a misnomer, but to the general user base it would be far more sensible and intuitive than the current situation where the label "Matching World Tiles" actually refers to what's under the "Region" header and not what's under the "World" header. And I think power users will still grok what the label means, especially if you're ever able to crack the scaling so you can put up a second tally of "Matching World Tiles" referring to the right-hand map.

On that topic, is it necessary to predict when DF will switch world map resolution, or could it be measured empirically? For example does dfhack let you read the current contents of the screen in order to find the "World" header, go down to the top left glyph of the map, and then go right and down looking for blank spaces to measure its size? Or, does your mechanism for rendering the Xs on the region map and the hotkey prompts in the right-edge text area let you know the screen coordinates of those things, in order to calculate the gap between them where the world map must be?

Just brainstorming ideas. I'll do some more testing to see if I can find a formula that holds up to resizes.
Logged

taleden

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #34 on: August 03, 2018, 03:28:33 pm »

Okay, I think I understand now how the world map dimensions are chosen and how region tile coordinates are mapped to world tile coordinates based on the region map's displayed dimensions (which in turn of course depends on the console/screen dimensions). So to state it as a formula I just need to know what information you have easy access to from the dfhack API on your end, and what kind of coordinates (screen col/row? worldmap X/Y? something else?) you need to draw the Xs.

Can you read the current displayed dimensions of the (center) region map, or only the total console size? And can you write X markers to the (right) world map using an offset from the top-left corner of that map, or do you need to offset from the top-left of the region map, or of the whole console?

Also, I did my testing using the available default world sizes (17-33-65-129-257 region tiles), but you mentioned custom worlds. I went into the "design a world with advanced parameters" but could not find any way to specify alternate sizes (i.e. 256), I could only select the width and height (separately) from among those 5 presets. Is there some hack to force world gen with an arbitrary size?
Logged

PatrikLundell

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #35 on: August 03, 2018, 05:30:08 pm »

I understand what you're saying, and I agree that something should be done about the terminology so it's both understandable for "casual" users and doesn't clash with what's "known" by power users. I'll need to think about that.
Hm, "World Map (right) Tiles", "Region Map (middle) Tiles" might work, if there's enough screen real estate for the text (always in short supply).

In order to merge the info to the correct place on the "World" map I need to be able to determine exactly which (technical) World Tiles go onto exactly which "World map" merged tiles. It's preferable to use world X/Y dimensions and screen dimensions (which are readily available) to do that, although it should be possible to read the contents of a "screen tile" for empirical measurement (I know it can be done from Lua scripts, so the same underlying function should be usable from High Level Assembly (a.k.a. C(++)).

I don't need to read the dimensions of the center map, as I've got the logic for what it will be sorted out, so it is computed based on the basics, i.e. world and screen size. If I remember correctly, the logic for where the top left corner of the right map ends up is also in place.

There are two kinds of custom world sizes. The "simple" one is different dimensions for X and Y (I typically use 17 * 129, for instance), and the "complicated" one is whacko dimensions (e.g. 25*42, randomly selected). The first one can easily be generated with the standard advanced world gen interface (as you've seen), as well as using a saved template (with optional PSV data). I'm not quite sure if whacky sizes can be done by modifying the template file, or if you need to use DFHack to change them, but I think a template is enough. I don't think any special handling is needed for differing standard X/Y dimensions, though, as they ought to just follow the normal logic for the appropriate dimension.

Edit: I'm going to make a new attempt at matching World Tiles to the DF World Map. This is what I left behind when I gave up a year ago:
Spoiler (click to show/hide)

Edit 2: The other part from the code:
Spoiler (click to show/hide)

Edit 3:
I think I've found how DF decides to resize the map (haven't tried non standard dimensions, and mostly the Y dimension) (Lua script this time):
Spoiler (click to show/hide)
« Last Edit: August 04, 2018, 11:15:11 am by PatrikLundell »
Logged

taleden

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #36 on: August 04, 2018, 01:36:21 pm »

Yep, I think you found the same little quirk I did -- the ratio is based on (totalsize - 1) / (availsize) rather than totalsize / availsize as one might expect. The X and Y dimensions appear to be handled independently, so all these formulas are axis-agnostic:

Code: [Select]
realTiles = "number of real top-level tiles in the world in this dimension, i.e. 17, 33, 65, 129 or 257 for standard worlds"
regionTiles = "number of displayed (center) region map tiles in this dimension; dependent on window size"
normalWorldScale = "ratio of displayed (right) world map tiles to (center) region map tiles for all columns/rows except the last" = CEILING((realTiles - 1) / regionTiles
worldTiles = "number of displayed (right) world map tiles in this dimension" = MIN(regionTiles, CEILING(realTiles / normalWorldScale - 0.5))
finalWorldScale = "ratio of displayed (right) world map tiles to (center) region map tiles for only the last column/row" = realTiles - (worldTiles - 1) * normalWorldScale
regionCoord = "offset to a position in the (center) region map, from 0 to realTiles - 1"
worldCoord = "offset to a position in the (right) world map, from 0 to worldTiles - 1" = MIN(worldTiles - 1, FLOOR(regionCoord / normalWorldScale))

I gathered data on all five standard map dimensions and window sizes from 25 to 120ish and found the region map size breakpoints where the world map would resize, and these equations match what I observed for all cases. Some of the components look a little odd but may be the result of Toady writing the code using slightly different inputs or operators; for example "realTiles - 1" is also "maxRegionCoord" so maybe that's the value he had on hand and neglected to add 1 for the 0th position, and CEILING(X/Y - 0.5) is effectively ROUND_HALF_DOWN(X/Y) (i.e. round to nearest, but 0.5 toward 0 instead of away).

Anyway, let me know you find a case where those values come out wrong and I'm happy to tinker with it some more!
Logged

Bumber

  • Bay Watcher
  • REMOVE KOBOLD
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #37 on: August 04, 2018, 05:28:40 pm »

What does Toady call region tiles? It was something amusing, but I forget.
Logged
Reading his name would trigger it. Thinking of him would trigger it. No other circumstances would trigger it- it was strictly related to the concept of Bill Clinton entering the conscious mind.

THE xTROLL FUR SOCKx RUSE WAS A........... DISTACTION        the carp HAVE the wagon

A wizard has turned you into a wagon. This was inevitable (Y/y)?

PatrikLundell

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #38 on: August 05, 2018, 03:27:56 am »

What does Toady call region tiles? It was something amusing, but I forget.
Mid Level Tiles, if you use the most common interpretation of "region tile". That's the one I use since then, as it ought to be unambiguous. The most amusing term is probably "feature shell" though.

@taleden: I went through all cases vertically up to and including 129, predicting the 257 size map beforehand and verifying that the changes occurred where predicted. I'll make a few tests with weird map sizes to see what happens. Axis agnosticism is handy, and matches what I've seen.

Edit: Hmpf! When testing I found DF behaving weirdly with a 129 Y dimension world: it changed the scale factor at 19 and 22 available lines as expected, but weirdly it only uses 18/21, leaving the World map one tile shorter than the Region one (and a lot of World Tiles mapped onto the tiles of the last row). Thus, I need to test through each world size carefully for each dimension to see if there are other such cases. Also failed to generate weirdly shaped worlds, although I know I have done so a few years ago.
« Last Edit: August 05, 2018, 06:51:40 am by PatrikLundell »
Logged

taleden

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #39 on: August 05, 2018, 08:29:07 am »

Edit: Hmpf! When testing I found DF behaving weirdly with a 129 Y dimension world: it changed the scale factor at 19 and 22 available lines as expected, but weirdly it only uses 18/21, leaving the World map one tile shorter than the Region one (and a lot of World Tiles mapped onto the tiles of the last row).

Yes, I observed this as well, and at least the cases I saw are handled by the equations I posted. For example with world size 129 and (center) region map heights from 22-25, the (right) world map has height 21, leaving its bottom row blank. The mapping in that case is 20 rows of 6:1 and the final row 9:1. But the equations should handle that:

Code: [Select]
normalWorldScale = CEILING((realTiles - 1) / regionTiles = CEILING((129 - 1) / 22) = CEILING(5.82) = 6
worldTiles = MIN(regionTiles, CEILING(realTiles / normalWorldScale - 0.5)) = MIN(22, CEILING(129 / 6 - 0.5)) = MIN(22, CEILING(21.5 - 0.5)) = MIN(22, CEILING(21)) = 21

So I think in fact it's exactly the round-half-down behavior I mentioned that causes these odd results with unused space in the (right) world map.

edit: It would be nice to have integer-math versions of these equations to make sure to avoid any floating point oddities. If I have some time later I'll give that a try, but in the mean time since we know the size of the values we're working with is small we can probably get away with just adding some manual fuzz, i.e. "CEILING(X - 0.5001)".
« Last Edit: August 05, 2018, 08:33:57 am by taleden »
Logged

PatrikLundell

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #40 on: August 05, 2018, 09:55:14 am »

Assuming I've gotten it right, the following ugly (Lua version) logic should take care of it (and I'm giving up on odd sized worlds):
Spoiler (click to show/hide)

As expected, I don't have enough room for a good matching description, so I've ended up with:
Matching World Tiles: xxx
(Those on Region Map)

Not great, but might be a bit better. Curiously, counting the number of tile on the right map would require extra work, as the logic currently just writes an X in the right place when iterating over all World Tiles without checking if there is one already. It's easier to count the ones on top of the Region map, as that would just be a matter of summing up how many times an X is written, but I don't think that would add anything to what the Eyeball Mk 1 tells you.


Logged

Fleeting Frames

  • Bay Watcher
  • Spooky cart at distance
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #41 on: August 05, 2018, 10:18:14 am »

Footnote on odd sized worlds: I had to use dfhack's gui/gm-editor to make them, personally (also had to have a prompt popup i.e. with initial vanilla size change to initialize the values for it to work for some reason). But that was a while ago, much like you.

taleden

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #42 on: August 05, 2018, 12:36:00 pm »

I managed to massage the equations to work out with integer arithmetic (i.e. no more CEILING, no non-integer constants, implied FLOOR on all divisions):

Code: [Select]
normalWorldScale = (realTiles - 1 + regionTiles - 1) / regionTiles
worldTiles = MIN(regionTiles, ((realTiles + ((normalWorldScale - 1) / 2)) / normalWorldScale))

edit: So, no need for an iterative algorithm, or I think for any hard coded special cases for certain combinations of world sizes and scale factors; just plug the above equations in (using integer math) and they should get the right numbers. I think there's a good chance they'll work for non-standard world dimensions as well, since this new integer variant seems much more plausible to me as something Toady might well have written (again allowing for plausible quirks of the variables he had available at the time, i.e. maxCoord rather than numTiles-1 as I've written it above).
« Last Edit: August 05, 2018, 12:46:54 pm by taleden »
Logged

Bumber

  • Bay Watcher
  • REMOVE KOBOLD
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #43 on: August 05, 2018, 04:37:52 pm »

The most amusing term is probably "feature shell" though.
That was it! :P
Logged
Reading his name would trigger it. Thinking of him would trigger it. No other circumstances would trigger it- it was strictly related to the concept of Bill Clinton entering the conscious mind.

THE xTROLL FUR SOCKx RUSE WAS A........... DISTACTION        the carp HAVE the wagon

A wizard has turned you into a wagon. This was inevitable (Y/y)?

PatrikLundell

  • Bay Watcher
    • View Profile
Re: DFHack plugin embark-assistant
« Reply #44 on: August 06, 2018, 04:56:09 am »

I've adopted taleden's better "world map" size determination algorithm.
Logged
Pages: 1 2 [3] 4 5 ... 24