Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Some things I wish Decker did

A topic by Screwtapello created 4 days ago Views: 124 Replies: 9
Viewing posts 1 to 5
(+2)

Just for the heck of it, I’m expanding my UXN fonts deck into one that can import various font formats into Decker. As I’ve been working on it, I’ve bumped into a few things that annoy me.

I can’t find an easy way to edit the Deck script

I can edit the card’s script with ^e. I can edit a widget’s script by selecting it and hitting ^r (and the shortcut for switching widgets with ^r in the editor and control-clicking the ghost of a widget is very cool). But I don’t know how to quickly get to the deck script, and I occasionally have to flip back and forth between them when I have a card script that calls handlers defined in the deck script.

For some reason, my fingers have decided that ^e should toggle back and forth between the Deck and Card scripts. It doesn’t work, but I keep trying it and being disappointed.

read[] doesn’t filter by extension

If you read["image"] or read["sound"], the file-picker restricts you to selecting filetypes Decker can read, which makes sense. If you write[array[] ".dat"] then Decker writes array data and automatically sets the file-extension to .dat. However, if you read["array" ".dat"], the file-picker doesn’t restrict you to reading .dat files - you get to pick any file on the system, whether you understand it or not.

Some font file formats have a magic number I can check to see whether it’s a format I recognise, but some are just straight binary data and I have to try it and see. It would be more friendly if I could say “this button only imports .ch8 files”.

read[] can’t tell me the filename it opened

Very simple font formats also often don’t have a font name embedded in them; the font name is effectively the filename. But read[] doesn’t tell me the name of the file it opened, I just get Array interface, so I have to import the font as “New Font”, then let the user rename it. That’s not impossible, but it is annoying.

In addition, if the user clicks Cancel in the file-picker, I’d expect it to return nil or some other indicator that things didn’t work out. Instead, it returns a zero-sized array, just like I’d tried to open an empty file. Again, not a deal-breaker, but “You cancelled, or chose an empty file” is not the most helpful error message.

Developer(+2)

Thanks for the suggestions.

  • The script editor has "Go to Deck" / "Go to Card" menu items which don't presently have a keyboard shortcut; adding shortcuts would be very simple and at least get you a two-keystroke path to what you want. Any preferences?
  • I'll give a file-filtering hint for read[] some thought, but it might be tricky to make portable; Browsers (notionally) want filters based on MIME types- which often don't exist or aren't well-recognized for binary formats, and at best this information is a vague suggestion that they may ignore entirely. I've observed very inconsistent behavior for both MIME and extension-based filters, especially on mobile browsers.
  • I don't see a way of supplying filenames as a result from read[] without breaking its contract, and in turn many existing decks. It also poses some potential portability issues; on mobile browsers, for example, importing an image may allow a user to take a photo from their phone's camera instead of choosing an image from the local filesystem. I can see how this could be useful, but I'm hesitant to make the breaking change.
  • Returning an empty array on canceling a read[] of a binary file is consistent with returning an empty image on canceling a read[] of an image. This design hasn't been re-examined since the introduction of nil as a new option for in-band signaling, though. I'll give this some thought, too.
(+1)

As far as I can see, ^d is not being used for anything, so if that could be “Go to Deck” (and especially if ^e could be “Go to Card” even in the script editor), that would be very handy.

I figured there’d be a Good Reason (probably browser-based) why read[] works the way it does, I just couldn’t guess what it might be. Apparently file extensions also count as Unique File Type Specifiers, but I do not doubt it’s a mess on mobile browsers. I guess this is just a nice-to-have, since even filename extensions can lie.

As for returning a name, I guess the hacky thing would be to give the Array interface a .name property that’s normally nil but can be assigned any string value, and have the read[] builtin try to set it before returning the result. A binary-data array isn’t necessarily a file, though, and it doesn’t make a whole lot of sense for it to have a .name property otherwise.

Developer(+1)

Added those shortcuts: https://github.com/JohnEarnest/Decker/commit/c9d1b8076db54b857c57860e3440a08221b291c1

(+1)

Thanks!

(2 edits) (+1)

For your first one, as a stop gap, my editor card can be modified to read & write the deck script:

https://codeberg.org/woodring/decker.whiteboard/src/branch/main/whiteboard.deck

search and replace:

deck.modules[w.module_name.text].script

to

deck.script

lines 71, 84, 96, 108

After editing the whiteboard deck, load it and cut and paste the editor card into your deck. Then, I’d have an offscreen button with a hotkey that takes you to the card that has the editor or last card. (though, you can’t have control+key hotkeys for buttons)

or alternatively

Modify the card to add four new buttons and copy the scripts editor.1 through 4. Attach them to the 4 new buttons that read and write the deck.script, instead, which retains the module editor functionality, too.


Totally stop gap, but the editor card is how I do live module edits. I flip between the cards with arrow keys and move it where I need it. That’s just my workflow, though.

(2 edits)

By the way, a question a bit related to this is, is there a Decker shortcut cheatsheet someplace?

I know the documentation describes some of them, with inline text, but it’d be nice to have a table. I haven’t found it, if there is.

(+2)

I don’t know of one off the top of my head. Digging around in Decker’s source-code, I managed to get this list of shortcuts from the code that sets up menus:

Cards...           C
Copy               c
Copy Image         c
Copy Rich Text     r
Copy Sound         c
Copy Table         c
Copy Widgets       c
Cut Image          x
Cut Sound          x
Cut Widgets        x
Cut                x
Darken Image       k
Fullscreen         f
Invert             i
Keycaps...         k
Lighten Image      j
Listener           l
Open...            o
Order...           O
Paste Card         v
Paste Image        v
Paste Inline Image v
Paste Rich Text    v
Paste Sound        v
Paste Table        v
Paste              v
Paste Widgets      v
Prototypes...      T
Query...           u
Quit               q
Redo               Z
Rotate Left        ,
Rotate Right       .
Script...          e
Script...          r
Select All         a
Snap to Grid       p
Sounds...          S
Tight Selection    g
Toggle Comment     /
Undo               z
X-Ray Specs        r

Most of those shortcuts are only available at certain times (for example, ^/ to toggle comments only works in the script editor) and there’s shortcuts that aren’t in that list (like m to toggle the menu while in drawing mode).

It might be a fun graphic-design challenge to make a Decker keyboard shortcut zine with Millie’s zine template.

Developer(+1)

I highly encourage anyone with an idea for new documentation, references, learning materials, or tutorials to take a stab at making them and share them with the community.

I can't suit every need myself, and presenting information with more voices and for more learning styles is always better!

Developer(+1)

I have revised the behavior of read[] in Decker to return nil if a user cancels the open file dialog instead of a hint-appropriate empty value. This makes it possible to distinguish explicit cancels from selecting and reading empty files, and makes it easier to use 'unless' to substitute in a default if needed:

https://github.com/JohnEarnest/Decker/commit/182398aed65b6ce900592137ebcba22a4c304b5e

In practice, I don't expect this to be a significant breaking change, since most of the examples in the wild that I have reviewed either explicitly check the size of the result (e.g. 'if count read[] ...'), gracefully tolerate a nil as an acceptable empty value (coercing it to a string, dict, etc), or make no attempt whatsoever to handle even an empty result.

Note that this change does not alter the existing behavior of 'danger.read[path hint]' or lilt's 'read[path hint]', which produce empty values upon a read failure, such as lacking filesystem permissions.