Bay 12 Games Forum

Please login or register.

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

Author Topic: DFHack: quickfort | buildingplan | blueprint | blueprints/library  (Read 92312 times)

myk

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #15 on: July 31, 2020, 05:19:41 pm »

I'm halfway (I think) through implementing build mode, and boy is it a complicated one! The parsing and boundary detection logic is actually very similar to place, and I was able to generalize and reuse those algorithms. The difficulty comes from mapping all the different key sequences to buildings and then ensuring those buildings get configured correctly. After playing this game for years, I had no idea how many different kinds of buildings there are!

The operations map is currently 400 lines of dense configuration code, and still growing as I correct the bad assumptions I made in the first draft.

In general, I'm coding it to enforce the same rules as the in-game UI for allowed placement of buildings (e.g. beds have to be inside, doors have to be adjacent to a wall, etc.). A notable exception is that I'm allowing constructions and machine components to be designated regardless of whether they are reachable or currently supported. This allows the player to designate an entire floor of an above-ground
building or an entire power train without micromanagement. I'm also not enforcing that materials are accessible from the designation location. That is something that the player can manage.

I did some basic testing to make sure machine components wouldn't just immediately deconstruct when the were built in the "wrong" order, but I haven't verified yet that complex machines work as expected. If it needs more work, I might be able to control automatic suspension of the construction jobs to ensure things get built "correctly".
« Last Edit: July 31, 2020, 06:29:54 pm by myk »
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #16 on: August 02, 2020, 01:53:44 pm »

build mode is done, except for a few caveats. I haven't implemented material preferences yet, of course -- that's planned for later, but a few of the buildings are just very complex in their potential configurations. Weapon and upright spike traps, for example, can be built with a variable number of weapons attached. And pressure plates.. there's not even a deterministic ordering of keys that will result in a particular configuration! I'm going to return to those three later.

In other news, query mode is also mostly done! I though query mode would be the most complex since it can read an arbitrary sequence of keys and expand arbitrary aliases, but it turned out to be the easiest mode of all to implement!

There are still a few improvements to be made, especially around error detection (bad key sequences that don't return to the main screen, attempts to configure tiles that don't contain buildings, etc.), but once this gets merged, the quickfort script will be ready for some actual play testing!
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #17 on: August 04, 2020, 12:37:14 am »

Well, that about wraps up the basics! Dig, build, place, and query are now usable. I'm doing some play testing and writing documentation before I go any further so the current code is release-ready. While writing the docs, though, I realized that since DFHack quickfort is compatible with Python Quickfort, much of the previous tool's user manual is still very much applicable. I reached out to Joel Thornton, the author, to see if I could get his permission for reuse. His manual has lots of great examples and his writing is excellent. Anything I write would pale in comparison!

The next big coding tasks are .xlsx support. I should also spend some time putting together a library of useful example blueprints. If anyone has blueprints to share, I'd love to see them!
Logged

Zalthor

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #18 on: August 05, 2020, 01:31:51 pm »

I should also spend some time putting together a library of useful example blueprints. If anyone has blueprints to share, I'd love to see them!
I know that the Starter Pack has its own library of blueprints. Perhaps you could port those?
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #19 on: August 05, 2020, 02:52:10 pm »

Good idea -- I'll also look at the ones linked from the user guide for the original python Quickfort. By the way, Joel gave us permission to use his user guide, so I'll be copying lots of good info from there into the new DFHack quickfort user guide. Thanks Joel!!

I've been playtesting the quickfort script and things have been going well. Fixing bugs as I find them. I'm significantly expanding the library of query mode aliases, too, so complex query blueprints should be much easier to write now. I even wrote a set of aliases that sets up everything you need for a quantum stockpile : )
« Last Edit: August 05, 2020, 02:56:21 pm by myk »
Logged

Starver

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #20 on: August 05, 2020, 04:28:34 pm »

Currently, just orthogonally, but there's no reason why I can't make it also connect diagonally if that's what map makers want. What would be "expected" by a novice mapmaker? should this be one stockpile or two?:
Code: [Select]
#place
a,a, ,a
a, ,a,a
Slightly late to this[1], but I tend to chequerboard some pairs of stockpiles (say in preparation for alloy-making, copper-storing tiles alternating with tin ones, or whatever) for no good reason other than aesthetics and a rather specific kind of at-a-glance level checking.

I'd usually do this by painting a major square of one type (bars/copper, e.g.), deselecting alternates and then repainting the same major square of the next type (bars/tin...). Other useful mixes and ratios-of-mix get implemented, too, with additional work.

It looks like you've got got #place notation capable of doing this with the "a:onepile"-type definitions, but I thought I'd mention it as a further testable situation that others might benefit from.


Not that it's important to cater for, but might be an edge-condition worthwhile considering, especially when there are non-adjacent (orthagonal or diagonal) disconnects and exclaving/enclaving. Or don't, if you just think I'm being awkward. ;)


[1] Would say "long time listener, first time caller", except that the thread isn't old enough, and I probably only saw it first on an idle-pass over the threads after a week or so.
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #21 on: August 05, 2020, 06:01:41 pm »

I've actually been leaning towards including diagonals since I discovered, while implementing build mode, that roads and farm plots and other "extent"-based structures are unhappy when they are fully disconnected, but are perfectly happy if they are connected only by a diagonal. This makes it "canon" enough for me to support diagonally-connected stockpiles without hrmming and hawing about it (is that how you spell it?).

I also discovered that although you can't place disconnected farm plots and roads via the UI, they work just fine if you place them via directly on the game map using the API. For most structures I enforce the same rules as the UI (for example, you can't build in hidden tiles, even if they're really an empty cavern floor), but there is no reason *not* to support disconnected farm plots and roads, so I went ahead an relaxed the rules. This will save you from some frustration when a center tile of a planned farm plot is taken up with a piece of stone.

edit: done with diagonal stockpiles. isn't Lua scripting easy?
« Last Edit: August 05, 2020, 06:13:22 pm by myk »
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #22 on: August 06, 2020, 02:16:55 am »

I've been going through the user guide for python Quickfort and adapting it for this implementation. One of the first sections is the list of features. Here's what I have so far:

* Manages complete blueprints to handle the four main phases of DF construction
* Supports .csv and multi-worksheet .xlsx blueprint files
* Near-instant application, even for very large and complex blueprints
* Multi-z-level blueprints
* Designates complete constructions at once, without having to wait for each tile to become supported before you can build it
* Supports stockpiles of all shapes, not just rectangular blocks
* Automatic splitting of stockpiles and buildings that exceed DF size limits
* Automatic cropping of blueprints that extend beyond the map boundaries
* Automatic blueprint validity checking so, for example, buildings that cannot be placed on a certain tile will simply not be placed instead of the blueprint failing to apply or the blueprint getting desynchronized and "going bonkers". Blueprints that are only partially applied for any reason can be safely reapplied to build the remaining buildings.
* Relaxed rules for farm plot and road placement, allowing disconnected tiles to be part of the same building.
* Handles arbitrarily complex minecart track designations
* Supports aliases to automate frequent keystroke combos
* Supports including aliases in other aliases, and repeating key sequences a specified number of times
* Includes a library of aliases to automate most common tasks, such as configuring stockpiles for important item types or creating hauling routes for quantum stockpiles.
* "Undo" functionality for dig, build, and place blueprints
* Generates and queues manager orders for everything required to apply build blueprints
* Assortment of read-to-use blueprints included
* Instant halting of blueprint application when keystroke errors are detected
* Verbose mode that logs detailed processing steps when debugging blueprints

Need to work on some of the wording, but I've got 2000 more lines of user guide to go through first...

I think the most important bit is that (non-query) blueprints are now idempotent -- that is, you can apply the blueprint multiple times and you get the same consistent result: any missing buildings will be placed, and any buildings that are already placed won't be changed, and, more importantly, won't make the blueprint go crazy because it can't place something that it's trying to place.
« Last Edit: August 06, 2020, 05:42:42 am by myk »
Logged

rmblr

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #23 on: August 06, 2020, 04:20:23 am »

Quite a project!

I think idempotency is very important, also undo functionality, nice to see that there.

I suppose included will be the option to designate the blueprints in marker mode?
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #24 on: August 06, 2020, 05:40:27 am »

I totally forgot to add that! Yes, already implemented. Also configurable settings for max numbers of bins, barrels, and wheelbarrows for blueprint stockpiles.
Logged

rmblr

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #25 on: August 06, 2020, 06:34:45 am »

Will it also support designating stockpile settings themselves (the items that can be placed in the stockpile)?

That would be seriously amazing. I wrote the savestock/loadstock plugin for dfhack just because I make extensive use of fine grained stockpiles in every fort, and defining them is a very tedious process. Being able to have blue prints that designate my rooms, workshops AND stockpiles would be killer!
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #26 on: August 06, 2020, 11:52:21 am »

Yes, setting stockpile settings is supported via actual keystroke playback, abstracted behind a library of aliases (and aliases that combine aliases) that handle the common key sequences.

For example, a series of blueprints that I've been testing with that creates a quantum stockpile system for non-economic stone and gems looks like this:

Code: [Select]
#build
 ,`
 ,trackstopN
`,`,`
`,`,`
`,`,`

#place
 ,s
 ,
s,s,s
s,s,s
s,s,s

#query
 ,quantum
 ,quantumstopfromsouth
`,`,otherstone
`,`,enablegems
`,`,`

which will create stone stockpiles and the trackstop (dumping North), configure them like we want, and create a hauling route so dwarves will load and dump the minecart onto the quantum stockpile above. each of the strings in the query blueprint is defined in an aliases list that is distributed with dfhack or in a player-defined alias that builds on the common aliases.

As an example, "quantum" is defined like this:
Code: [Select]
quantum: {linksonly}{nocontainers}{enableanimals}{enablefood}{enablefurniture}{enablestone}{enableammo}{enablecoins}{enablebars}{enablegems}{enablefinishedgoods}{enableleather}{enablecloth}{enablewood}}{enableweapons}{enablearmor}{enablesheet}where each of those elements are aliases themselves, for example:
Code: [Select]
foodprefix:  s{Down}
enablefood:  {foodprefix}e^
The caret ("^") is shorthand for {ESC}, required to exit the stockpile settings screen. query blueprints have to make sure to return to the same screen they started on whenever they apply a configuration so we can move the cursor to the next cell to configure.

Another simpler example is a food stockpile that is configured to just hold booze:
Code: [Select]
booze: {foodprefix}b{Right}{Down 5}p{Down}p^
« Last Edit: August 06, 2020, 01:50:48 pm by myk »
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #27 on: August 10, 2020, 03:38:22 am »

After an intense battle with the build system, the quickfort script now supports reading from .xlsx files. That was a lot tougher than I thought it would be! Cross-platform support is difficult when building libraries you don't control on operating systems you don't have! Huge thanks to lethosor for getting me unstuck when I ran into linker symbol resolution issues, and for giving me an excellent walkthough for how to make C pointers type safe when sending them through the Lua layer!

I've also adapted the Python Quickfort's user guide into the DFHack quickfort user guide, which, when merged, will be available here (as of this posting, that file just contains a few lines; after the merge, it'll have about 1000).
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack script: quickfort
« Reply #28 on: August 12, 2020, 01:54:42 am »

Two new features for today:

1) ability to filter quickfort list output by mode and/or by substring. As I run through my test blueprints when I make a change, it was getting more and more difficult to find the blueprint I wanted. This helps a lot : )

2) you can now generate manager orders to produce everything you need for a build-mode blueprint! For now, I hard-coded it to produce rock where possible, then wood if we can't use rock, then iron if we need a metal. We'll see how much more configurable it needs to be once people start using it.

The next big thing I'll be working on is support for buildingplan. Currently, quickfort places all requested buildings, even if you don't actually have the materials to build them. That's fine, but if you don't have the materials, they disappear with a "can't build building" message as soon as the job is scheduled. Integration with buildingplan will keep the buildings suspended until materials are available.  The big difficulty here is that buildingplan only supports a few item types. I'm looking into extending its functionality to cover *all* item types.
Logged

Warmist

  • Bay Watcher
  • Master of unfinished jobs
    • View Profile
Re: DFHack script: quickfort
« Reply #29 on: August 12, 2020, 02:36:12 am »

After an intense battle with the build system, the quickfort script now supports reading from .xlsx files. That was a lot tougher than I thought it would be! Cross-platform support is difficult when building libraries you don't control on operating systems you don't have! Huge thanks to lethosor for getting me unstuck when I ran into linker symbol resolution issues, and for giving me an excellent walkthough for how to make C pointers type safe when sending them through the Lua layer!
<...>
I'm still scarred from some library integration - build time is 200 times longer.The library itself builds for half a day. Never again...

Now everything i build small and more c-like and single header.
Pages: 1 [2] 3 4 ... 29