Skip to main content

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

General Decker Question and Answer Thread Sticky

A topic by ahmwma created 98 days ago Views: 1,553 Replies: 62
Viewing posts 1 to 17
(+4)

Some users have mentioned having a question or two that were small enough that they didn't feel like they wanted to make a new thread.

So here's a place to ask and answer general questions about Decker.

No question too small or silly! It's always good to ask if you're feeling confused about something

-----

If your question is about Lil (the scripting language) specifically you could check out the Lil Programming Questions thread instead.

Hey! I'm  trying to build decker on linux and I'm getting an error. Mind you that I have close to 0 coding knowledge and its a miracle I'm able to even use linux so the problem  might be obvious.


$ make

In file included from ./c/decker.c:3:

./c/dom.h: In function ‘deck_write’:

./c/dom.h:2882:37: error: ‘js_decker_html’ undeclared (first use in this function)

 2882 |                 str_addz(&r,lmiutf8(js_decker_html,js_decker_html_len));

      |                                     ^~~~~~~~~~~~~~

./c/dom.h:2882:37: note: each undeclared identifier is reported only once for each function it appears in

./c/dom.h:2882:52: error: ‘js_decker_html_len’ undeclared (first use in this function)

 2882 |                 str_addz(&r,lmiutf8(js_decker_html,js_decker_html_len));

      |                                                    ^~~~~~~~~~~~~~~~~~

./c/dom.h:2891:37: error: ‘js_lil_js’ undeclared (first use in this function)

 2891 |                 str_addz(&r,lmiutf8(js_lil_js,js_lil_js_len));

      |                                     ^~~~~~~~~

./c/dom.h:2891:47: error: ‘js_lil_js_len’ undeclared (first use in this function)

 2891 |                 str_addz(&r,lmiutf8(js_lil_js,js_lil_js_len));

      |                                               ^~~~~~~~~~~~~

./c/dom.h:2892:37: error: ‘js_danger_js’ undeclared (first use in this function)

 2892 |                 str_addz(&r,lmiutf8(js_danger_js,js_danger_js_len));

      |                                     ^~~~~~~~~~~~

./c/dom.h:2892:50: error: ‘js_danger_js_len’ undeclared (first use in this function)

 2892 |                 str_addz(&r,lmiutf8(js_danger_js,js_danger_js_len));

      |                                                  ^~~~~~~~~~~~~~~~

./c/dom.h:2893:37: error: ‘js_decker_js’ undeclared (first use in this function)

 2893 |                 str_addz(&r,lmiutf8(js_decker_js,js_decker_js_len));

      |                                     ^~~~~~~~~~~~

./c/dom.h:2893:50: error: ‘js_decker_js_len’ undeclared (first use in this function)

 2893 |                 str_addz(&r,lmiutf8(js_decker_js,js_decker_js_len));

      |                                                  ^~~~~~~~~~~~~~~~

In file included from ./c/decker.c:9:

./c/io_sdl2.h: In function ‘base_path’:

./c/io_sdl2.h:75:87: warning: zero-length gnu_printf format string [-Wformat-zero-length]

   75 |         if(t){snprintf(path,PATH_MAX,"%s",t);SDL_free(t);}else{snprintf(path,PATH_MAX,"");}

      |                                                                                       ^~

./c/decker.c: In function ‘main’:

./c/decker.c:4314:57: error: ‘examples_decks_tour_deck’ undeclared (first use in this function)

 4314 |         if(!deck){str doc=str_new();str_add(&doc,(char*)examples_decks_tour_deck,examples_decks_tour_deck_len);load_deck(deck_get(lmstr(doc)));}

      |                                                         ^~~~~~~~~~~~~~~~~~~~~~~~

./c/decker.c:4314:82: error: ‘examples_decks_tour_deck_len’ undeclared (first use in this function)

 4314 |        if(!deck){str doc=str_new();str_add(&doc,(char*)examples_decks_tour_deck,examples_decks_tour_deck_len);load_deck(deck_get(lmstr(doc)));}

      |                                                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

make: *** [Makefile:66: c/build/decker] Error 1

(+1)

The js_decker_html variable should be defined in c/resources.h which should be automatically built when it needs to be.

If you rm c/resources.h and then make V=1 c/resources.h do you get any error message?

(1 edit) (+2)

Doing that solved the issue! Thanks!:-) You're getting a special thanks in my first decker project lol

I'm slightly surprised/confused by the behavior of the new pattern/color support in text fields.

It seems as if the pattern doesn't persist past whatever text you initially marked with that pattern. If I write out some text and make it green, if I continue to then write further text past that, it will revert back to the default black, and my new added text will be black. I also can't set the whole field to a specific pattern, so as to change that black default, at least not from what I can see from the GUI.

This is in contrast to the behavior when changing fonts, where the behavior is such that any text I write past the point where I changed the font will continue to be in that font. This does have some wrinkles that aren't always intuitive when mixing fonts, but it does mean I continue to write into a text field in that font as expected without any special interaction, and I can save myself even those headaches by just setting the font property of the field itself, thus insuring that it defaults back to that font.

I bring all this up because it sort of negatively effects my workflow to how I've been working with text fields for the current project. When I'm writing a long card of text, usually my method is just to make one large field on the card, set the default font of that, and then I take advantage of interact mode's ability to just write directly into the field. Makes it easier to write long texts rather than doing it in the field properties. 

But this kinda doesn't work with the color support, because I can't set the field to be all one color and just write away. Plus, on my current project, the text is over a mostly black background, so it's unreadable until I change the color. It's a minor detail, and I can work around it, it's just unexpected I guess.

(+3)

So this might help a bit, but basically there's two ways of setting the colour/pattern of text in a field. It sounds like what you're doing is using the "select a bunch of text and change it with the text menu" option, which yeah does seem to not affect newly added text. But you can also select the field in widget mode, go into the properties (double-click or widget -> properties) and then there's a "pattern" button. If you set the pattern or colour there, that becomes the default for that field, so when you're writing into it in interact mode it'll come up as the colour you want. Hopefully this helps / makes sense.

(+1)

oh! all those words and yet so there is a button for that. that should make this much easier but also begs the question how I missed it. 😜

I have some cards with a bunch of fields in them, and I want them to line up nicely, so I used the “snap to grid” function. Eventually I decided that the default 16x16px grid was a bit too chunky, and dropped down to an 8x8px grid so I could have spaces smaller than a field, as well as larger.

But now when I need to adjust a field, I have to go in and change the grid spacing back to 8x8px every time - it defaults to 16x16px every time I start Decker.

Is there a way to have the default grid size stored in the deck?

Developer(+2)

Currently grid settings aren't persisted anywhere, but I'll give it some thought; possibly it could be stored in deck files, or perhaps it might make sense to expose scripted control via the app interface.

How do I insert/drag and drop an image and have it be full width? I just starting using Decker and regardless of image size my images are being resized, even 512 × 342 GIFs are resized when dragged+dropped. What am I missing? Thanks!

Developer(+2)

With the selection still active, you can choose "Edit -> Resize to Original" or "Edit -> Resize to Card" from the menu to preserve the original dimensions of the image or snap it to the dimensions of the card, respectively.

(+1)

Amazing! Thank you and great project really. I am a Haskell and Lua novice and am enjoying Lil

Excuse me, I have a lot of questions. I hope you don't mind. Before asking, I want to say that English is not my native language. And I've tried to read the documentation on how to use this software. There's still a lot that confuses me, but behind the scenes of your animation The Riddle of The Temple has helped me quite a bit with some of the basics of Decker, especially the canvas. And I'm very grateful for the tutorial you created. My biggest problem, aside from language, is focus. Tutorials with a lot of text make me lose focus and my mind wanders. Actually, I wasn't like this before, until an incident happened to me that will remain personal. And I'm using a translator for this message.

So I have a total of 5 questions:

1. How can I make the dialogizer animate the dialogue with sound simultaneously with the puppeteer module or when the dialogue script comes from a field?

2. How can I make a card have background sound, whether it's a song or the sound of rain, that continues to play in the background? Can the sound continue to play even when moving between cards?

3. Since I see your animations are very cool, can you give me tips or perhaps your workflow in creating animations in Decker? I'm trying to create animations with the Zazz module. The difficulty I encounter is that I'm inconsistent with the size of each animation frame, so sometimes the animations look bad and overlap each other.

4. Is it possible for the zazz animation to remain active while the dialogue is running? Or there's some alternatives to do it?

5. I'm having trouble understanding how to use cardname.widgets[“widgetname”] in the tutorial you created. I tried to find it in your animation, but I still don't understand. I want to be able to create a game with a lock mechanism. What I mean is, there is a door whose key must be found elsewhere to open it. Like an escape room. And if I can make it, how can I reset it back to the beginning? Like, if you restart the game, the door is locked again and the key is hidden again?

Maybe I'm asking too many questions, sorry about that. I don't really have much experience in coding, except with Scratch, and that was years ago. I'm also looking for new activities. Besides making mini projects with Decker, I've also started learning HTML. I want to make a website. And I'm still learning. For me, starting to understand how to use Dialogizer and Zazz is a great achievement for someone with little experience like me.

I understand a little English, which is good news. I don't want to make you think too hard about how to answer my questions so that I understand. And if I still don't understand, I will ask in more specific way. And when my project is finished, is it okay if the language is not English? I want to show it to the public. Or maybe not.

and i'm from Indonesia 👋

(+3)

Hi! I'll do my best to answer your questions, but please let me know if anything doesn't make sense to you, and I will try to explain more clearly.

1:

When you're doing the style settings in Dialogizer, there's two key attributes to get it to animate with sound. The first is "tsound" which specifies a sound to play for each word, and the second is "speed" which specifies how fast or slow the text will appear.

For example, if you have a script in a field and a sound:

o:()
o.tsound:"sound1"
o.speed:3
dd.open[deck o]
dd.say[field1.value]
dd.close[]


2:

When you play a sound using the "play" command you can specify that you want it to loop. When you do this then it will loop continuously including over other cards, until a command is used to stop it.

To start a sound:

play["sound1" "loop"]

and to stop it:

play[0 "loop"]

3:

One way to make it easier to keep animation frames consistent and lined up is to use the grid functionality. When you're in drawing mode, in the View menu there is an option to "Show Grid Overlay" which will add a grid to the screen that you can use to line everything up. And if you click "Grid and Scale..." then you can change the size of the grid if you need to.

4:

Yes! As part of the setup for Puppeteer, you will have added an "on animate do" function - this is what Dialogizer uses to work at the same time as Puppeteer and other scripts. So if you add the zazz commands here then they will run as well.

For example, in a current project I have this in a card-level script to make the zazz animations work.

on view do
 zazzanimations[]
 go[card]
end
on zazzanimations do
 zazz.flipbook[coffee coffeeframes 0.0015]
end
on animate do
 zazzanimations[]
 pt.animate[deck]
end

I've put the zazz command in its own function so that I only have to change it in one place.


5:

So basically you will need to create a separate card with checkboxes on it, to store the values. E.g. make a card called "flags". Then you add a checkbox on this card named "gotkey"

You can in your code refer to the value of this card like so:

#to get the value
flags.widgets.gotkey.value
#or to set the value
flags.widgets.gotkey.value:1

You can reset it by having some code that runs at the start to reset the value to 0, or if you set the checkbox as "volatile" then it will automatically reset when the deck opens.


I hope this all makes sense. If you have more questions I'm sure people here would be happy to help out.

And I think it is absolutely OK to share projects that aren't in English. I know there have been a few Decker projects that are in languages other than English. People may not be able to understand it but you shouldn't let that stop you!

(+1)

Thank you, Millie, your answer helped me understand Decker better. I understood almost everything you taught me, even though there were a few errors here and there. But at least I'm starting to understand. Apparently, my biggest problem that made me doubt my ability to write script lines was that I often forgot to write some quotation marks or ‘strings’ and made typos. So, I actually lack confidence in my abilities because of this small flaw. If I had known earlier, maybe I wouldn't be so confused about Decker and feel so inferior. Maybe it would be a good idea for Decker to have a syntax highlighting feature in the future.

Hey! I've got 2 questions right now. One's more general, and one's a problem I've got with my code right now lol.

1. I wanted to make a canvas that does something on both the up and down click of a mouse  (Similar to how a button widget changes color when its clicked down on, but doesn't count as "clicked" until the mouse button unclicked over it.) and was wondering if there was any code to do something like that. Preferably, I want it so that the canvas counts as "Unclicked" when the mouse is also taken off of the canvas while clicked.

2.For some reason, the If Statement I'm using here isn't activating when I want it to, and I can't figure out why. My guesses is that either it's having trouble because it's reading from a text field, or because mult.text  routinely has 2 decimal points (Numbers like 1.35 and that kinda stuff) so the score.text also has 2 decimal points and that is messing it up somehow.  Either way, I kinda have no idea what I'm doing admittedly.

(Also, if someone has a better way to store number variables so they automatically round up/down from a decimal point, tell me and my life is yours.)

(1 edit) (+5)

For your first question, a canvas gets the click event on mouse-down, and the release event on mouse-up, so you can make the canvas change colour while the button is held down:

on click pos do
 me.pattern:colors.red
 me.rect[0,0 me.lsize]
end

on release pos do
 me.pattern:colors.white
 me.rect[0,0 me.lsize]
end

(obviously you can do fancier painting than that if you want)

The release event also gives you the position of the pointer at the time the button was released, relative to the top-left corner of the canvas. If the position is below and to the right of the top-left corner, and above and to the left of the bottom-right corner, then it’s within the canvas, and you can do whatever the canvas-button is supposed to do:

if min (pos>0,0),(pos<me.lsize)
 alert["whatever I'm supposed to do"]
end

For your second question, I can’t easily spot an error (though I’m pretty sure you don’t need set); in this situation I’d wrap show[] around different parts of the code to double-check that the values being calculated were the ones I expected. show[] takes a sequence of expressions, logs them to the Listener, and returns the first one, so you can wrap it around expressions without changing how your code runs. So, this code will run exactly the same as the example above:

if min show[(pos>0,0) "<-- to the bottom right"],show[(pos<me.lsize) "<-- to the top left"]
 alert["whatever I'm supposed to do"]
end

…but produces this output in the Listener:

(1,1) "<-- to the bottom right"
(0,1) "<-- to the top left"

For your third question, the floor operator drops the fractional part of a number:

 floor 1.0,1.4,1.5,1.6,2.0
(1,1,1,1,2)

If you want round-to-nearest rather than always-round-down, you can add 0.5 before hand:

 floor 0.5+(1.0,1.4,1.5,1.6,2.0)
(1,1,2,2,2)
(+1)

Alrighty, I'm back! I've started putting all of your of the advice you've given to work, but I still haven't been able to get the If Statement to work. 

I used the show code to make sure that that score.text is receiving numbers properly, and I also used the floor function to make sure that there were no decimal points in the score, but that didn't seem to work either. I also tried switching the field to both Plain Text and Code, but that didn't seem to fix anything either.

One thing I have come to realize is that when i make it so that the score.text is supposed to be Less Than the given number, it will always activate regardless of the number larger or smaller. And it seems to work the opposite with Greater Than, with it never activating instead. (I also tried to set the number it's compared to to a negative one,  and the results were the same) If anyone has any ideas as to what is going on, please tell me cuz I'm getting a little desperate.

Anyways, thank you Screwtapello for the help. Even if I can't get that one system working, seeing my scores finally not have a bunch of little decimal numbers hanging off of the end has eased a sense of peace upon my soul, one which I cannot describe accurately with words alone. Your help is appreciated.

Developer(+2)

The .text attribute of a field is a string. Comparing numbers to strings in Lil can have surprising results, because in this case Lil makes the comparison lexicographically:

3>"12"  # 1
3>12    # 0

To avoid this problem, you can use an arithmetic identity operation to coerce the string into a number before performing a comparison:

  myField.text  # "12"
0+myField.text  # 12

Alternatively, use the .data attribute of the field instead: this will ask Decker to interpret the contents of the field as LOVE (a superset of JSON):

myField.text     # "12"
myField.data     # 12
otherField.text  # "[11,22,33]"
otherField.data  # (11,22,33)

Yet another option would be to store numbers in Slider Widgets instead of fields; a slider's .value attribute is always a number. Does that help?

(+1)

I'll have to do some more research on what all this means, but I have gotten it working now. Thank you!I Like Your Funny Words, Magic Man - Meming Wiki

I HAD A QUESTION!
is it possible to have the widgets outside of Decker, like just chilling on my desktop or smthn or is that not possible?

(+2)

Unfortunately, No. Though that sounds fun. :) Decker Widgets share a name with phone Widgets but they do different things.

If you wanted to use Decker's Widgets for your own personal use on your computer you could definitely make a small nice looking deck that holds Widgets that do small helpful things that you'd like to have access to on your desktop... (I'm imagining things like a clock, a to-do list, a pomodoro timer, a place for writing notes, etc.) but the widgets would still have to be entirely inside Decker.

Quick question - with grids, is there any way to have a hidden column, aside from the few built-in always hidden columns?

Basically I'm trying to build a file list where I show the user "friendly" names but when they select one I then have the actual path to the file hidden behind the scenes and I can load that. Is there a way I can have that as a column in the same table, hidden but accessible through scripting, or would I need a separate invisible grid elsewhere with the "real" values?

Developer(+2)

You can set the .widths property of a grid widget to a list of column widths in pixels. Any columns thus set to 0px wide will be completely hidden from view and skipped over when navigating by cell. Grids will also automatically hide any rightmost columns that don't fit within the width of the widget, so making leftward columns a bit wider can scrunch the secret columns out of view. (Columns have resize handles in between column labels while in Interact mode!)

(+3)

Aha, that should work! Thank you!

(+1)

Another question! For some reason when I try and download the latest version of Public Transit, it doesn't have any of the transitions, and doesn't seem to add them to my Decks when I import in the PublicTransit resource either.


This has occurred in both the downloaded sample decks that come with Decker, and downloading straight from the web version of Public Transit. I want that Melt transition soooooooo bad man, it reminds me of Balatro.

(1 edit) (+3)

I might be wrong but I think you're using an older version of Decker. Possibly 1.54 or earlier. 

The reason I think that is because Decker 1.55 introduced some changes to Lil. The description box under the preview is showing a "0" which suggests that your version of Decker is from before "nil" was introduced.

Could you update to a more recent version and let us know if that fixed it?

(+2)

Yep, you were exactly right! I did have the newest version downloaded, but I didn't realize that It was still opening every deck with the old version I had sitting around. Thank you!

i don't know why i can't figure it out, but i can't use any colours with the animated patterns no matter what i do. i just want red and black instead of white and black lmao. any idea what i'm doing wrong?

(+2)

The “Patterns Interface” section of the Decker docs describes the animated patterns as:

A list of up to 256 pattern indices for animated patterns.

You can include solid “red” and “black” in the animated sequence because they have pattern indices (35 and 1). But if you want a pattern pattern, those are described as:

An 8x8 image interface comprised of patterns 0 and 1.

So actual patterns can’t have red in them, only patterns 0 and 1, which are (by default) white and black. You could set palette 32 to be red instead of white to get red-and-black animations, but that would make every white pixel red, which probably isn’t what you want.

Developer(+2)

As a concrete example, assuming the default palette, if you wanted to set animated pattern 28 to red and black alternating as fast as possible you could use The Listener to issue the following Lil snippet:

patterns[28]:35,47

To halve the speed you could double up each pattern index, e.g.:

patterns[28]:35,35,47,47

There are more examples of this sort of thing in All About Color.

Is that clear?

it's still confusing to me because i have a smooth brain BUT it is adding some colour to the thing so i'm gonna keep playing with it. thank you!

I'm having some troubles working out how to iterate through every row in a grid

If I use like "each x in grid.value" I get each column separately. And I can do it if I refer to each row with the index like "each x in count y" and then "grid.value[x]" that seems to be an option but I can't seem to find a way of getting the total size so that I know how far to go.

Is there something I'm missing? Is there a cleverer way of doing this?

Developer

The "rows" primitive turns a table into a list of dictionary, with each dictionary representing a row.

You can thus iterate over the rows of the table stored in a grid something like:

each row in rows mygrid.value
 # ...
end

More broadly, though, what are you trying to do? There might be better alternatives depending on the application.

I'm working on the launcher for my Deck Kiosk - so I'm starting with the sample code you sent me with the directory listing but I want to have it go through and  open up each deck and pull out the name (and maybe the author) for each deck so that things look a bit friendlier than just a filename. I tried doing it as part of the select statement but it didn't seen to work, I guess because the function I was using didn't work nicely over a vector?

(+2)

Hi, I've just started using Decker and it's great. Really fantastic environment to play in. Congratulations!

My question is probably obvious to someone versed in Lua or Lil, but if I want to stock a grid with items from a column in another grid, how could i do that? For example, to display a list of items being carried in an inventory.

At present I have 'invlist' which is a grid containing all the possible items, with names and other date (such as a parameter number for their effects. But I want to have the ability to select from a list of held items which would be displayed on the cards. So I need to draw in data from the names column of 'invlist' to populate a grid based on a numerical list of what the player is holding  However, everything I try seems to hit a brick wall Any newbie advice for populating grids and/or adding items to them?

Developer(+1)

Grid widgets, like this example named "items":


contain tables. You can read or write the table of a grid widget via the .value attribute of the grid. Tables can be indexed numerically (looking up rows) or by strings (looking up columns):

items.value
# +--------------+-------+--------+
# | fruit        | price | amount |
# +--------------+-------+--------+
# | "apple"      | 1     | 1      |
# | "cherry"     | 0.35  | 15     |
# | "banana"     | 0.75  | 2      |
# | "durian"     | 2.99  | 5      |
# | "elderberry" | 0.92  | 1      |
# +--------------+-------+--------+
items.value[3]
# {"fruit":"durian","price":2.99,"amount":5}
items.value.fruit
# ("apple","cherry","banana","durian","elderberry")

In the simplest case of populating another grid with a specific column of a source grid, assigning a list to the destination grid's .value attribute will implicitly cast it to a table:

dest.value:items.value.fruit


For more complex transformations of data, there's Lil's query language:

select fruit price where amount>2 from items.value
# +----------+-------+
# | fruit    | price |
# +----------+-------+
# | "cherry" | 0.35  |
# | "durian" | 2.99  |
# +----------+-------+

A query never modifies tables in-place; it returns a new table. Just like before, we can take the source grid's .value, query it, and assign the result to another grid's .value attribute:

dest.value:select fruit amount where fruit in "cherry","banana" from items.value


There are many examples of using queries on tables in the Lil reference manual section Lil, The Query Language. If you aren't using it already, Decker's Listeneris very helpful for trying queries interactively or generally testing out snippets of code.

Does any of that point you in a useful direction? I can try to furnish more specific examples of how to formulate queries for your project if you provide additional detail about how your data is organized.

Thank you - this has got me very close.

I came up with something like

 invdisplay.value:select Name where Item in 0, 1 from invlist.value

This allows me to fill invdisplay with the names of items 0 and 1 from invlist, which is great!

But I also have  a grid for tracking the inventory, so it is a table containing a single column of values such as 0, 2, 5, for example.

I just can't figure out how to turn that column into something usable in this select query, since something like the following does not work:

invdisplay.value:select Name where Item in carrying.value from invlist.value

Any clues?!

All the best,

Phil

Developer(+1)

You have several approaches available.

The @ operator can be used to index a list, dictionary, or table by a list of indices or keys. For example:

items.value
# +--------------+-------+--------+
# | fruit        | price | amount |
# +--------------+-------+--------+
# | "apple"      | 1     | 1      |
# | "cherry"     | 0.35  | 15     |
# | "banana"     | 0.75  | 2      |
# | "durian"     | 2.99  | 5      |
# | "elderberry" | 0.92  | 1      |
# +--------------+-------+--------+
items.value.fruit @ 0,2,3
# ("apple","banana","durian")

Indexing a table in this way gives us a list of rows (each a dictionary), but we can glue those back together with the "table" operator:

items.value @ 0,2,3
# ({"fruit":"apple","price":1,"amount":1},{"fruit":"banana","price":0.75,"amount":2},{"fruit":"durian","price":2.99,"amount":5})
table items.value @ 0,2,3
# +----------+-------+--------+
# | fruit    | price | amount |
# +----------+-------+--------+
# | "apple"  | 1     | 1      |
# | "banana" | 0.75  | 2      |
# | "durian" | 2.99  | 5      |
# +----------+-------+--------+

To clarify my earlier examples, in most applications the "in" operator attempts to check whether an item on the left (or each item in a list on the left) appears within a list on the right:

3 in 2,4,5        # 0
5 in 2,4,5        # 1
(3,5) in 2,4,5    # (0,1)

Within a query, you could do something roughly equivalent to our first example by referencing the implicit "magic column" named "index":

select where index in 0,2,3 from items.value
# +----------+-------+--------+
# | fruit    | price | amount |
# +----------+-------+--------+
# | "apple"  | 1     | 1      |
# | "banana" | 0.75  | 2      |
# | "durian" | 2.99  | 5      |
# +----------+-------+--------+

If your desired indices are stored in a table, you'll need to pluck out a column of that table before you can compare it to another column with "in" or index with "@":

invgrid.value
# +-----------+
# | itemIndex |
# +-----------+
# | 0         |
# | 2         |
# | 3         |
# +-----------+
invgrid.value.itemIndex
# (0,2,3)
table items.value @ invgrid.value.itemIndex
# +----------+-------+--------+
# | fruit    | price | amount |
# +----------+-------+--------+
# | "apple"  | 1     | 1      |
# | "banana" | 0.75  | 2      |
# | "durian" | 2.99  | 5      |
# +----------+-------+--------+
select where index in invgrid.value.itemIndex from items.value
# +----------+-------+--------+
# | fruit    | price | amount |
# +----------+-------+--------+
# | "apple"  | 1     | 1      |
# | "banana" | 0.75  | 2      |
# | "durian" | 2.99  | 5      |
# +----------+-------+--------+

You might consider keeping track of inventory items based on their names, or some other semantically meaningful "id" or key column, rather than by index; it could be more human-readable, and if you make any mistakes writing your queries it may be more obvious where something has gone wrong.

I would also like to note that grids aren't the only way to store collections of data within Decker, and may not always be the simplest choice. For example, you could also store a list of indices in a field widget via its .data attribute. Say we have a field named "myList":

myList.data:11,22,33

The field will visually show the data as "[11,22,33]". If we read myList.data we can reconstitute the list:

myList.data   # (11,22,33)

Does that help?

(+1)

Thank you again! I am away from my machine RN, but I will give these a try tomorrow!

(+1)
invgrid.value.itemIndex 
# (0,2,3)

Thanks! This was what i was missing! :) Thank you so much for all the wonderful examples.

i edited the march script to get a "vibrate" effect; i was aiming for a screenshake but i need to figure out how to make widgets bigger than the canvas (otherwise it just leaves the background in view when shaking) but that's not what i'm doing today.

today i used this script:

on view do
 zazz.march[p1,p2 canvas1 0.05]
 go[card]
end
successfully on one deck:

the big image is the canvas, with the two lil guys being the points it moves between. worked pretty well for a total newbie like me.

hoooooooooowever................... no matter what i do, i cannot seem to recreate it in my other deck. not when i copy the whole card, and not when i do it step by step.

but it just. won't move. at all.

even when i paste the card into this deck it doesn't work and i'm a little at a loss about how i fumbled this LOL. when i paste THIS card back into the vibrate deck that works, it works?? sorry. it's probably something super basic.

(+3)

Possibly a silly question, but did you make sure to add the "zazz" module to your other deck?

(1 edit)

hahahahahaha nope....... that must be it. but if i'm being honest, i have absolutely no idea how to add a module at all. anyway....

i pulled it over from resources but nothing has changed, which was my only guess as to how to import a module. i must have missed the tutorial on this part specifically somewhere, my bad.

(+3)

Basically you open the deck you need to have the module in, and then drag the deck that has the module into the window. That'll pop up the Font/DA mover and you can move the module across. It looks like you've done that but with still no luck?

Any chance you can upload the deck somewhere so we can have a look?

(+3)

ahhh. i had used import resources, and imported zazz from there. i had to delete that zazz and then drag it in like you said, but now it works? not sure why but. hey. it's working now LOL.

thanks for your help.

(+3)

Hello! I've discovered decker a few days ago and I've been experimenting and messing around on it, recently I discovered the bazaar of contraptions, they are so cool, but I'm not sure where I have to insert the code to put it on my deck.

I've been reading the documentation, tough I haven't finished yet (discovered decker right around finals week, whoops) I'm not sure if the answer is in the documentation, but if it is could someone point to me where to look? (I didn't what to clutter the contraption bazaar with my silly question but lmk if I should ask directly in there) 

(2 edits) (+3)

Not a silly question!

The short answer is you can use ctrl+v (or Edit > Paste Widget in the menu) while you're looking at a card.

The slightly longer answer is this:

Decker's image data, widgets (including contraptions) and even whole cards can be copied and pasted between decks very easily.

As an example: if you copy a plain button widget and then paste it somewhere else... you get a matching button.
But if you paste it into a text editor like notepad you get something that looks a little bit like the code blocks in the contraption bazaar:

%%WGT0{"w":[{"name":"button1","type":"button","size":[60,20],"pos":[230,164]}],"d":{}}

That's because this is what widgets look like when they're stored in your system's clipboard. They start with %%WGT and contain all the information about their size and scripts and data, etc.

So Decker will know that if there's a  %%WGT at the start of a string that you're pasting (that you copied from the bazaar) that means you're pasting a widget!

Just like it would recognize %%IMG as image data or %%CRD as being a whole card.

We're using the forums as a place to pass this easy kind of copy-and-paste clipboard data to each other in order to share our inventions and tools. Because it just works. :)

So, yeah, when you copy a contraption from the bazaar you can just paste it directly onto a card!

Have fun, and good luck with your finals!

(+2)

OMG thanks!! tbh i was literally reverse engineering by reading the code and copying the script parts but doing my own widgets, it was so time consuming, haha. This way is def more easy!! And thanks for the good wishes! have a lovely day.

(+1)

How do I delete cards?

(+1)

The easiest way is to cut them. Use [ Card > Cut Card ] from the menu bar, and then just don't ever paste them back in.

(This gives you a small window to get your card back before it's gone for good.)

(+1)

Thank you!

Is there ANY way to resize an internal canvas(es) on a contraption resize? I cannot figure out how to do it for the life of me. I’ve put it in “on view” for the contraption card, I’ve put it on some internal widgets that have an animate property and are firing every 60Hz.

The ONLY way that it seems to work is in the prototype view, then yes, my canvases are resized to the size of the prototype when interact is turned on. But, as soon as I plop that contraption instance in a card, nope! My canvases refuse to resize. It’s like the size of the canvases are now static and refuse to take a resize parameter.

Is this some sort of limitation of decker or… what am I missing? I feel like I’ve tried everything and whatever it is going to be is probably not intuitive.

Alternatively, I suppose I could put them on an internal state image, which is what I am really using them for, for double buffering and compositing (though, I do need a draw line from a canvas). But, then that raises another question, I am uncertain where to initialize long term state on a card or contraption. I feel like if I put it in the card’s/contraption’s/prototype’s main script, it will get overridden when that script fires again. Does it go in an “on view” with an “initialized sentinel value”?

Also, is there a working example of get_ and set_ for prototypes? The examples don’t help me and everything I’ve tried doesn’t work either.

(+1)

Is there ANY way to resize an internal canvas(es) on a contraption resize?

If you make your prototype “resizable” (when you’re editing a prototype, from the “Prototype” menu make sure the last item “Resizable” is ticked), then you should be able to resize the contraption when you add it to a card. If you also tick “Show Margins” in the Prototype menu, you’ll also get four little handles you can use to mark the left, right, top and bottom margins of the prototype: any part of a widget that is between the edge of the prototype and the margins will stay at that fixed distance from the edge, any part of a widget that is in the middle will be proportionally resized as the contraption is resized.

%%WGT0{"w":[{"name":"prototype11","type":"contraption","size":[98,91],"pos":[86,66],"def":"prototype1","widgets":{"canvas1":{"size":[81,41]}}}],"d":{"prototype1":{"name":"prototype1","size":[100,100],"resizable":1,"margin":[0,25,0,0],"widgets":{"canvas1":{"type":"canvas","size":[83,46],"pos":[8,9]}}}}}

If you paste the above widget definition into a card, you’ll get a contraption with a canvas in the top half of it. The top edge of the canvas is between the top edge of the prototype and the top margin, so it stays at a fixed distance from the top of the contraption as it is resized. The bottom edge of the canvas is between the top and bottom margins, so it moves proportionally as the contraption is resized.

If you are trying to write code to reposition widgets in a deck, that should work, but it may be overidden by the “built in” resizing behaviour described above? I’m not sure, I haven’t tried it.

But, then that raises another question, I am uncertain where to initialize long term state on a card or contraption.

The best place to put long-term state on a card or contraption is in a widget. Widgets don’t have to be in the centre “white” part of a prototype, you can stash them in the dark-grey border area - but make sure they’re locked so the user can’t accidentally interact with them. For most data types (numbers, strings, lists, dicts, tables) you can just use a regular field, and read and write its .data property. If you want to store a bunch of images (such as sprites), the best way is to use a rich-text field; you can paste the images in, and access them from code by reading the .images property.

Also, is there a working example of get_ and set_ for prototypes?

If you edit a prototype and choose “Script…” from the Prototype menu, you can enter a handler like this:

on get_foo do
 "here's a foo"
end

Then, let’s say you make a contraption from this prototype, called mycontraption. If you say mycontraption.foo, that will evaluate to the string "here's a foo". Here’s a pasteable example of that in action:

%%WGT0{"w":[{"name":"mycontraption","type":"contraption","size":[100,100],"pos":[86,66],"def":"prototype1","widgets":{}},{"name":"button1","type":"button","size":[84,20],"pos":[93,40],"script":"on click do\n alert[mycontraption.foo]\nend","text":"Gimme a foo"}],"d":{"prototype1":{"name":"prototype1","size":[100,100],"margin":[0,0,0,0],"script":"on get_foo do\n \"here's a foo\"\nend","widgets":{}}}}

Setting works the same way: define on set_foo val do ... end and it will be called when code does mycontraption.foo:somevalue.

If you want to be able to get and set values interactively, rather than just through code, you can also use “attributes”, but that’s an optional, additional layer on top of get_foo and set_foo that you don’t have to worry about otherwise.

(1 edit)

Thanks, I’ll try these.

As for the resizing widgets and what you’ve said, my gut is that it might be being overridden by the internal resizing logic, I’m not sure really.

What I have experienced is that I have them offscreen, since they are acting as compositing buffers. The “resize event” works fine, as it is triggered by some code that is being run in an animated widget - ONLY when it’s in the prototype view. As soon as an instance of the prototype becomes a contraption instance, all of that code stops working. The canvases will not resize anymore.

Also, thanks for the confirmation on the state. I kind of figured it was like Pd (Pure Data) and it would go in a widget, like how Pd does it.

(+1)

If you can provide an example contraption that exhibits the behaviour you describe, that would help. If you can set it up in a new deck, you can select the contraption, do Edit → Copy Widgets, and then paste the result into a reply here. That’s what I did to create the examples in my reply - if you copy a contraption, Decker even includes its prototype.

(+1)

Thanks for the offer, but I’ve decided on another route.

I’m doing what I wanted through modules, deck.add, etc. That does work for me and it’s clearer to me what’s happening.

It’s more work for me to avoid the prototype/contraption interface, but that’s how it goes.

(+2)

I figured out what the problem was. I didn’t realize you needed to call card.update[] when changing subordinate widget sizes.

Actually, no - that wasn’t it.

Anyways, I’ll have the contraption done soon, but I think I am running into a corner case where it doesn’t like resizing when a canvas is beyond the boundaries or something. The clipping gets to be incorrect and things start wrapping even though I explicitly set the sizes of the canvas and clip.

(1 edit)

I figured it out. I don’t know if it’s a bug or a limitation, but it’s easy to reproduce:

A prototype/contraption background image will not resize itself. It is fixed, no matter what. For instance, if I make a prototype at (200,200) and then resize it, the image is fixed. It also causes strange compositing errors near the edge of the contraption if I am actively drawing into it.

To get around it, I will have to use another canvas as the background image, rather than the contraption’s image - because they should be resizing themselves, obeying the margins. The prototype’s/contraption’s card does not, and is permanently fixed size.

Also, maybe I am abusing the use of the prototype/contraption base image and it is not supposed to be drawn into during interaction.

(+1)

Ah, yeah. The “margins” of a prototype also divide up the prototype background into a 3x3 grid. When a contraption is resized: the top-left tile of the prototype is drawn at the top-left corner of the contraption; the top-centre tile of the prototype is tiled horizontally across the top of the contraption; the top-right tile of the prototype is drawn at the top-right corner of the contraption, and so forth.

The default introduction/tutorial deck you get when you launch Decker has a page on “contraptions”, and one of the examples is a “resizable decorative border” contraption that demonstrates the behaviour nicely.

If you want to draw the background with code, you’ll need a canvas widget if only because the Image protocol you get from card.image doesn’t provide a lot of drawing primitives. You can use a “hidden” canvas widget, draw the background you want, then do card.image:canvas.copy[0,0 canvas.lsize] to paste it onto the contraption background, or (much easier) just make the canvas widget cover the area of your prototype, and Decker’s default resize behaviour (with the margins and such) will make sure it stays in place as the contraption is resized.

(2 edits) (+1)

That’s exactly what I do, except the problem is the base image of the prototype/contraption will be fixed. If I resize the contraption, and the image started at (200,200) after instantiation, it remains at (200,200). It cannot be changed. I’ve tried on view or a subordinate widget that tries to resize it - it stays fixed.

Then, when I composite the subordinate canvases into it, and the contraption is resized, the image will wrap. The image will not resize itself and I can’t force it to resize.

The only way I have gotten around this is by maximizing the card on the prototype page so it starts with a very large image buffer, and then shrink it on view, when it’s actually instantiated. Except, that has problems, too.

So, I figure the only real fix is to not draw on the prototype’s/contraption’s base image, but on a canvas, and show the canvas.

Yep - it works now. It’s either a bug or limitation.

  • If the final target of the composite is the prototype/contraption card image, there are compositing errors and it (the image attached to the prototype/contraption card) will never resize.
  • If I use a “visible” canvas as the target, it does resize and all compositing errors go away.