I will share some hacks I used in the LIP2-Engine. Some of them are basics, some are advanced, but I will try to explain it as easy as possible or approach it in multiple steps.
LIP2-HACK #1: Select a random row of a table
TL;DR: This post approaches the topic in multiple steps. You can also jump to -> Final solution if you want to skip the blabla.
One of the biggest improvements in the LIP2 (besides the controller) is the way how the map is filled with objects.
In the first game, I made a table with 99 rows listing the available objects multiple times and just randomly used one of it on the map using right(random(),2). The problem: There was no way to control, how often an object is really placed on the map. So e.g. there was no guarantee there even is an exit
I wanted to exactly define how often an object should be placed on the map, and thatfor I needed a way to select a row randomly from table, that has not been selected before. Here is how I made it work:
Example 1: Show a random fruit
In our example, we want to get a random fruit of our fruits table.
Create a table called Fruits with a column âfruitâ and a column âorderâ
Fill in fruit names in your column fruit and fill in the formula =random(false) in your column order
On your canvas, create a new formula with =Fruits.sort(false,order).fruit.last()
Example 3: Select every fruit randomly and only once
In the third example we wanât to select only fruits, that have not been selected so far.
There are two ways:
A. Delete the row that you have currently selected
B. Just mark the row as âalready selectedâ to keep your data
I prefer way B and here is how it works:
Add a number-column âeatenâ to your Fruits table using the default value 0
Change the value formula in your selection button to: =Fruits.filter(eaten=0).sort(false, order).fruit.last() to just use âuneatenâ fruits.
Create a new button and give it a name and label (e.g. eatFruit, âEat selected fruitâ)
Choose âmodify rowsâ and select the Fruits table.
Choose âCustom filterâ and use the filter**: fruit=Fruits.filter(eaten=0).sort(false, order).fruit.last()
Choose your column âeatenâ and set the value to 1
Create a new button (e.g. selectAndEatRandomFruit, âSelect and eat random fruitâ)
Choose âpush buttonsâ and select our two buttons âselectFruitâ and âeatFruitâ
Now, every time you click the âSelect and eat random fruitâ button, the first button will bring the current random fruit into our selection and the selcond button will make it unavailable for the next selection.
With the current way, every fruit name can just appear once and has to be unique. You can easily change this by adding a column âRow properties -> row idâ and select rows not by the fruitname, but by the id in the formulas.
Make a âresetâ button, so you can fill your fruits stack with one click. Just use âmodify rowsâ - âall rowsâ - âeaten = 1â
**If you wonder, why we did not use âfruit=Selection.select.first()â in the âeatâ button:
When you push multiple buttons with one button you can imagine it like this: Everything freezes until all buttons are processed.
That means:
Our fruit order stays the same until all buttons are pushed (random will not change) so we can sort by order again and get the same result for both buttons.
When the eat button wants to eat a fruit, there will be no or wrong data in our selection table and not the current selected fruit. So we can not reference to it.
Example 4: The final solution: 1 Table 1 Button This is not how I used it in LIP2, because with the game board and the object list, I needed two tables anyway, but in many cases you only need one like here. The principle is quit the same as in the examples before, but here we use a timestamp to mark eaten rows and to create an order and see which is the current one.
Create a table vegetables with the columns âidâ (row properties -> row id), ânameâ (text), âorderâ (=random()) and âselectedâ (date/time)
create a button with âmodify rowsâ, select the vegetables table and the custom filter id=Vegetables.filter(selected="").sort(false,order).id.last() (this time we select by id, to make it possible to have a vegetable more than once)
use the values: âselected = now()â
you can also add a disabled if: Vegetables.filter(selected="").count()=0
create a formula on your canvas =Vegetables.filter(selected!="").Sort(true,selected).name.last()
I struggled with the last part, I didnât understood why using Filter.(Selected!=1) and it didnât worked on my side. I replaced it with : [Art of Game Design Lenses].Filter(Selected.IsNotBlank()).Sort(true,Selected).Subcategory.Last()
I also removed Filter(selected="") in the button filter, to be able to continuously pick any 113 lenses without excluding already picked lenses.
And finally made my random Game Design Lens picker!!! Thanks again!
By the way @evan or anyone at Coda, in my gif, Iâm in presentation mode, and I find it a bit weird that the canvas content is not centered on the whole screen. Thanks!
Is the way I made this post/tutorial to long/complicated?
Do you like the step by step approach or would you prefer just a final result with 2-3 formuals and the shared doc (e.g. just example 4 of this post, without the rest)?
The tutorial was good, but I often missed some of the formula logic. Like I had to scratch my head a bit to finally find that Sort(true) correspond to ascending. But itâs also Codasâ fault, because the formula sheet is not very clear, especially for noobs like me!
Not a problem for me. Sure, it looks a little longer, but if readers take 2 seconds to appreciate the value and navigate to where they need to go, then awesome. Suppose down the road this could be translated to another format (e.g. a blog).
I liked the step by step method that you did. It allows people to jump in at different points, more easily digest the information, and arguably can be multiple solutions in one (i.e. people with different questions may find this tip helpful since it is broken down in steps). Also, if you only need âstep 1â, you may find yourself now interested in diving deeper once step one works.
Hi @Daniel_Stieber thanks for sharing this. This is very useful for me. I am trying to create a randomised meal planner and was looking for a platform to help me do this easily. Thanks for posting these with such a good explanation!
Does RandomItem() supersede some of the advice here? I always find this thread when I google, but it seems like RandomItem lets me do everything I want to do (so far!) in terms of pulling random elements out of tables.
Wondering if the advice here is from before it was addedâŠ
Hey @Margaret_Robertson ,
you are absolutely right, randomItem() was introduced in March last year, so this hack and also some answers in the threat are outdated.
For anyone coming from Google or elsewhere, here is the post when randomItem along with two other handy formulas was announced:
That makes sense - thanks for clarifying. Itâs a great formula - Iâm working on a massive modular text generator project and am moving the whole thing across from a really gnarly spreadsheet. Massively easier in Coda!