Getting a button to render from a rollable table is tricky (I won't say it can't be done, because that's when someone like Tuo or RainbowEncoder shows how it can be done). =D
However.
I know you can do it with the Metascript Toolbox. (Metascripts are a class of scripts that help other scripts and provide basic functionality Roll20 does not expose; watch this video to learn more.)
Before I begin, I should say that I don't know the system, and that I'm operating with a few basic assumptions:
1) The expected gameplay is that when your party enters a room, the GM can click a button and have the room auto-generated by reading tables, and pursuing deeper levels of info from related tables
2) For certain returns, there could be either a) choices, or b) applicable options that are dependent on circumstances or gameplay (in other words, there might be a time where you know exactly what the room is, but there might be other times where it's a "Roll from table X if a character is wearing iron" and/or "Roll from table Y if a character is actively maintaining any spell", etc.)
So.
Let's say that you have a macro/ability named "OchGetARoom"
![](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExcXNwNTc2dmd3dW82OGZiZGowenlyaG5naWVwZnMxYm1oOXVhZGh2MyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3o7TKLA7WTuLe4vaLK/giphy.gif)
That macro would roll against a table I'll call "BaseRoomGenerator":
!&{template:default} [[ 1t[BaseRoomGenerator] ]].items {&simple}
The BaseRoomGenerator table has items that look like this:
{{name=Storage Room}} {{Size= [[ 1t[StorageRooms] ]].items }} {{Description=..color text here...}} {{Options=<<discussed below>>}}
{{name=Cavern}} {{Size= [[ 1t[CavesAndCaverns] ]].items }} {{Description=..color text here...}} {{Options=<<discussed below>>}}
...etc...
In other words, the BaseRoomGenerator table has the template fields that will complete the original macro's call to use the default template (you can use other templates -- I just don't want to make an assumption about what system you're using, nor craft a solution that's so specific to your case that others who come across this post wouldn't be able to use it). Note that further calls to other tables (like getting the size of each room) should be structured as:
[[ 1t[TableName] ]].items
...in order to extract the text from the return and make it able to recursively descend through the table rolls.
If the roll against the table sits within a single template part (like the calls to get the Size), then the data returned should just contain text (or calls to tables that provide only text). If the data you need to return from a table contains whole template parts ITSELF, then you should put the inline roll that will retrieve said data *outside* a template part. For instance...
If a call to the StorageRooms table will return only a size (such as 24x24 ft), then the inline roll referencing the information should be in a template part:
{{Size= [[ 1t[StorageRooms] ]].items }}
On the other hand, a room may require you to roll for occupants who are present in the room. Let's say that the RoomOccupants table is structured as a series of template parts:
{{Orc=An orc sharpening his blade.}}
{{Orcs (2)=A pair of orcs are having a contest to decide who can weave the prettiest macrame.}}
{{Bog Troll=A smelly beast armed with a [[1t[WeaponRandomizer] ]].items }}
...then the call to roll a series of times against that table should be between template parts:
{{Some Part=Previous template part.}} [[ [[1d4]]t[RoomOccupants] ]].items
That would roll between 1 and 4 times against the RoomOccupants table, returning each as a new template part to be appended to the main template message. (If you were using a different template that didn't have the freedom of just naming a new template part and having it automatically be included, you could obviously structure this so that it returned within a single template part -- in fact the ".items" syntax defaults to a comma-delimited output of the returned items, so you could easily structure the table entries without the double braces that denote a template part.)
Outputting Buttons
Now, back to the idea of outputting buttons from a table in case you have to manually continue generating details. The way the Metascript Toolbox works (specifically, ZeroFrame, one of the metascripts in the toolbox) is that if you have button syntax in your table, it will output the button to chat for you. I keep a table in my game to remind me the formats that are available:
![](https://files.d20.io/images/425548267/f5l67MdwEfm93EXz5Ne63w/original.png?1737391750)
(in fact, I think I don't have all of the tricks represented, as I don't have the formats that utilize a tick mark...)
Note that the lines for a Macro button, a ZF Template button, and an FX button all have a the HTML code for a line break (i.e., ) immediately after the opening exclamation point.
So if I run a command like:
![[ 1t[TableOfButtons] ]].items {&simple}
I will get an output of a button:
![](https://files.d20.io/images/425548958/CK3baGRVobo0TtLAcwPh8g/original.png?1737392196)
And if I click on that button, it will work just as normal. If I increase the number of calls against that table:
![[ 4t[TableOfButtons] ]].items {&simple}
...I'll get that number of returns of buttons:
![](https://files.d20.io/images/425549205/dCtb1D5TH06AvOdBbMJVVw/original.png?1737392363)
You can separate the returned items using characters other than a comma (for instance, line breaks might be nice). Read this post to learn more about the ".items" inline roll syntax.
One other thing... the button in that table that is the "ZF Template" option references a macro called TemplateResolutionTest. The text of that macro is:
!&{template:default}{{name=Deep Template}}{{Result=[[1t[TableOfButtons]]].items}}{&simple}
In other words, it is going to go back to the TableOfButtons and get a new button to drop into the template output. So if I get a "ZF Template" button as my return from the TableOfButtons:
![](https://files.d20.io/images/425549956/NDWFGj3RDf3K9DHbRP7Emw/original.png?1737392843)
...then, when I click it, I will get a new return from the TableOfButtons, this time contained in a default template layout, and returning a new random return from the TableOfButtons:
![](https://files.d20.io/images/425550140/SF_Yj7VAJrQRrr5ZbM9XzQ/original.png?1737392953)
...which shows how the whole process can continue from message to message until you've built/finalized your room.
Anyway, that's a ton of info which all sort of comes into play in the process, but I can understand it might not be as clear to see how it matters when you're just starting out trying to replicate this setup. If you can't see the finish line from here, post back and I can mock this up in my own game and show a working model with screenshots.