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
Preview mode for quickfort #2018
Comments
|
After tinkering with the preview screen for a bit, I've come to a realization: this screen should not be an interstitial. it should be the main quickfort UI. we don't need a e.g. what I envisioned as if a blueprint is already specified on the commandline, a preview for that blueprint is loaded. otherwise the blueprint list dialog (the current "UI") is shown. we can move command selection to the "preview" ui. Oh, this opens up a world of possibilities! |
|
add notice to sidebar describing what the blueprints do (e.g. "This blueprint will designate buildings and send keystrokes to the DF UI to configure individual tiles" or "this blueprint will send keystrokes to the DF UI to change options, but will not affect any tiles directly") add messagebox showing which orders will be enqueued if the user hits the "Generate manager orders" hotkey add "Undo" hotkey |
|
TODO: don't display an invalid tile when the blueprint designates a tile for tree chopping and there is no tree there |
|
TODO: show how many orders will be enqueued next to the 'o' hotkey label. Don't show popup if no orders were enqueued (though still show the empty pop-up if the orders preview was selected with 'O'). |
|
Change 'o' to a toggle that automatically enqueues orders on run. Add an "enqueue now" hotkey to the orders preview pop-up |
The more I thought about this feature, the more I realized that it needs a design doc, or at least somewhere to gather my thoughts. So here it is.
The vision:
After a blueprint is selected in the quickfort ui (or if --preview is passed on the commandline), a sidebar overlay viewscreen is shown and the cursor becomes active. Flashing X's appear where the blueprint will make changes to the map. The user can move the cursor (and use other hotkeys to apply euclidean transformations) and the blueprint shadow will change accordingly. The user can also "lock" the blueprint so the cursor can be used to shift the viewport and examine parts of the blueprint shadow that were originally offscreen (or on different z-levels). Enter applies the blueprint to the map, Esc cancels.
A technical challenge we need to address is that the ui needs to remain responsive to cursor movement, but the calculations for generating the blueprint "shadow" can be slow. This implies usage of lua coroutines and requires a design for explicit yielding to the graphical rendering stack.
Well, actually, let me think about the assumption that shadow calculation will be slow. My concern comes from observing the execution of large query blueprints, which can take multiple seconds. However, query blueprints won't be executed when generating previews. Just the tile locations where the query commands will be run are required. Perhaps I should approach this more iteratively.
First, I'll implement the preview UI and logic without coroutines and measure the responsiveness. What's the threshold? It should be low enough that the user doesn't feel that the cursor is frustratingly "laggy". Let's say 5ms max latency for calculating and rendering a shadow across all of Dreamfort's blueprints. Dreamfort has a good mix of simple and complicated blueprints that should provide good coverage of likely use cases.
Some thoughts on how to generate the previews:
If a preview is required, set preview={unclipped={}, clipped={}, bounds={}, invalid_tiles=0} in the ctx. As we run through the blueprint(s), set preview.unclipped[z][y][x] to true if something is on the blueprint at that tile position, and set the clipped coordinate to true or false according to whether the map would actually be changed at that position (i.e. it's a valid tile for the proposed change). When assigning false, increment the invalid_tiles counter. Only record clipped for the first blueprint that covers that tile. We don't want to mark a tile as bad if a later blueprint in a meta blueprint depends on an earlier one (e.g. meta plays a place then a query. The query blueprint depends on the stockpiles being there). Track min and max x, y, and z in the bounds table so we know what ranges to scan while rendering.
Note: this could potentially subsume the implementation of --pretend. Is there ever a case where we want the preview but pretend is false?
When rendering the overlay in the viewscreen, clip the preview bitmap to the viewport and render green Xs for coordinates that are true in clipped and red Xs for coordinates that are false in clipped but true in unclipped.
If I end up having to make the preview generation process interruptable, here are some thoughts about how I'd do it:
Use script.start() to process the blueprints when generating previews. Add to ctx a cancel flag and a function that will:
In the blueprint processors, we'll call the function and abort processing if the cancel flag is set. We'll have to add calls and checks in any loop that can take more than 5ms to execute.
If we do implement interruptibility, it will also enable quickfort to show progress when running blueprints instead of just showing a black screen until the blueprint is completely applied.
UI design:
Blueprint "shadow" appears on the map on the tiles where modifications would occur if the blueprint were applied at the current cursor location. Tiles where the blueprint would successfully be applied flash with green X characters. Tiles where the blueprint would attempt to make a change but fail (invalid tile, out of bounds, etc.) flash with red X characters.
Total invalid tile count (including tiles offscreen) is displayed in the menu overlay area.
Movement keys: move cursor and viewport. If blueprint is not locked, also move blueprint start location
l: lock blueprint start location, allowing user to see blueprint preview outside of the original viewport and other z-levels. If blueprint is locked, this unlocks the blueprint and jumps the cursor to the tile that it was on when the blueprint was locked.
L: (only appears when locked) unlock and jump the blueprint start position to the current cursor position
r: repeat. cycles through "None", "Up", and "Down"
R: (only appears when repeat is not "None". edit box for inputting how many times to repeat
Ctrl Up: apply vflip transformation
Ctrl Down: apply hflip transformation
Ctrl Left: apply rotccw transformation
Ctrl Right: apply rotcw transformation
x: clear all transformations
X: remove last transformation
As transformations are applied, they are listed on the menu overlay panel.
Enter applies the blueprint, Escape exits the viewscreen without applying
The text was updated successfully, but these errors were encountered: