Yeah... there are a few things going on that are stopping you. But, before you lose hope, there are ways to do what you want to do. You can read on through what's going wrong to understand why we have to go about things in the manner we will, or you can jump to the solution. (Or use a chat menu, as Gauss suggested.) First, most † scripts are only going to look for messages that start with a bang. They don't have to, but starting a message with a bang suppresses the message from going directly to the chat interface, and for most scripts this is the intended/necessary usage: if you want a script to take an action, you don't want to see the instructional message (the triggering message) hit the chat; if anything is going to hit the chat, you want it to be whatever the script, itself, would produce (like a report of its actions, or how it changed the state of the game). † - ChatSetAttr and the Metascript Toolbox are notable exceptions to this, in different ways and with different syntactic triggers. If you want more information about how scripts are triggered and interact with messages, watch the first 15 minutes of this video . (If you like what I'm about to describe and want to know how to do more, you might want to continue watching the rest of the video, but that's up to you.) For what you have going on, your overall message doesn't start with a bang -- it's a template message that you want to reach the chat. That means RecursiveTables is probably not going to recognize that it needs to take action on this message. More catastrophic to what you're trying to do, if it DID recognize that it needs to take action on the message, it won't be able to return its data to the template (as if to report the results in a particular field in the template output). This is because, as is discussed in the video, the message is sent to the chat separately from being sent to the scripts. An installed script might take action on the copy of the message that is going through the scripts, but that message is not the version that hits the chat. The copy of the message that hits the chat doesn't pass through the installed scripts, so can't be updated by them. If a script does not rely on the message starting with a bang, it is because it will take action in addition to whatever is being reported in the original, triggering message. For instance, ChatSetAttr contemplates that you would want to output a message announcing a bit of information about the action that just took place in the game while simultaneously taking separate action in the game (i.e., using some of the math in your command line to drive an adjustment to a character's HP). On How the Toolbox Can Help The Metascript Toolbox (a set of metascripts, described in the linked video), works slightly differently. The Toolbox scripts intend to work within the message, changing the message before it hits the chat or before another script sees it. If you need a way to understand that, it is something akin to how Roll20 syntax structures like attribute retrievals work (i.e., @{selected|hp} ). Those update the content of the message before it hits the chat (or reaches scripts). In much the same way, metascripts make other game data retrievable, or make IF/THEN constructions available, or give you ways to access more complex rolls, etc. Metascripts are still bound by the same limitation that we can't alter a message that is already bound for the chat panel (in other words, a non-bangsy message), so we impose the requirement that the command begin with a bang. Even if we just want to output a template message in which we have inserted some game data we've retrieved and/or complex rolls, we enable the scripts' involvement by starting the message's life as a bangsy message. If, after our metascript processing is finished, we want to output the altered message to chat, we use: {&simple} ...somewhere in the line. So a simple test would be something like: !This should hit the chat after metascript processing.{&simple} ...or... ![[4t[item-blessings]]] {&simple} As you can see if you run the above example, you will get the roll output to chat the same way you would if you never started the message with a bang -- with a single returned item showing in the chat. However, you should also notice that if that returned item, itself, contains another inline roll, that roll will have been processed, too. So, the next step is to use the .items() syntax from this post , as well as the carriage return syntax from this post to extract all of the items returned from the table and roll their sub-rolls: ![[4t[item-blessings]]].items({\&cr}) {&simple} Here is an example output from one of my Treasure tables: Finally, since this information can be returned to the command line, we can put the template syntax in the line, and have the output message be templated: !&{template:desc} {{desc=[[4t[item-blessings]]].items({\&cr}) }}{&simple} TL;DR Solution Since queries run before scripts, you can put this in your query fairly easily, so long as you abide by HTML substitution rules for queries. This version bypasses the need for separate macros, but you can see it assumes that each level higher would add an additional roll against the item-blessings table: !&{template:desc} [[{{desc= ?{Item type: | None, [[1d4-2]] gp | Marvelous, [[1t[item-blessings]]].items({\&cr}) {&cr} [[1d6-3]] gp | Wondrous, [[2t[item-blessings]]].items({\&cr}) {&cr} [[3t[item-blessings]]].items({\&cr}) {&cr} [[1d8-4]] gp | Famous, [[4t[item-blessings]]].items({\&cr}) {&cr} [[1d8-4]] gp} }} {&simple}