Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Copy Rollable Table - Change ID..

January 28 (2 weeks ago)

Edited January 28 (2 weeks ago)

I am creating rollable tables for Random Encounters.

I create one, and want another that is very similar (different weights mainly/only).

But I cannot copy that, and update the copy as no option, so I transmogrify it to another game, update and rename.

But now I cannot copy back to original game, as the (I am assuming) internal Id is the same.

Any way around this impasse, or am I doomed to making similar tables...each manually?

January 28 (2 weeks ago)
Manny L.
Pro
Marketplace Creator

The Aaron (who else!) has a script for that, which I used in the past and slightly modified.


Here's my modified version, which was updated to fix a very small bug (it wasn't handling the ampersand [&] escapes properly):

// Github:   https://github.com/shdwjk/Roll20API/blob/master/TableExport/TableExport.js
// By:       The Aaron, Arcane Scriptomancer
// Contact:  https://app.roll20.net/users/104025/the-aaron
var TableExport = TableExport || (function() {
'use strict';
var version  = '0.2.5',
        lastUpdate = 1576529132,
        tableCache = {},
        escapes = {
            '['   : '<%%91%%>',
            ']'   : '<%%93%%>',
            '--' : '<%%-%%>',
            ' --' : '[TABLEEXPORT:ESCAPE]',
            '&' : '<%%amp%%>'
        },
    
    esRE = function (s) {
        var escapeForRegexp = /(\\|\/|\[|\]|\(|\)|\{|\}|\?|\+|\*|\||\.|\^|\$)/g;
        return s.replace(escapeForRegexp,"\\$1");
    },
ch = function (c) {
var entities = {
'<' : 'lt',
'>' : 'gt',
"'" : '#39',
'@' : '#64',
            '*' : 'ast',
            '`' : '#96',
'{' : '#123',
'|' : '#124',
'}' : '#125',
'[' : '#91',
']' : '#93',
'"' : 'quot',
'-' : 'mdash',
' ' : 'nbsp',
            '&' : 'amp'
};
if(_.has(entities,c) ){
return ('&'+entities[c]+';');
}
return '';
},
checkInstall = function() {
        log('-=> TableExport v'+version+' <=-  ['+(new Date(lastUpdate*1000))+']');
},
showHelp = function() {
sendChat('',
            '/w gm '
+'<div style="border: 1px solid black; background-color: white; padding: 3px 3px;">'
+'<div style="font-weight: bold; border-bottom: 1px solid black;font-size: 130%;">'
+'TableExport v'+version
+'</div>'
+'<div style="padding-left:10px;margin-bottom:3px;">'
+'<p>This script dumps commands to the chat for reconstructing a rollable table on another campaign.  While this can be done on your own campaigns via the transmogrifier, this script allows you to pass those commands to a friend and thus share your own creative works with others.<p>'
+'<p><b>Caveat:</b> Avatar images that are not in your own library will be ignored by the API on import, but will not prevent creation of the table and table items.</p>'
+'</div>'
+'<b>Commands</b>'
+'<div style="padding-left:10px;">'
+'<b><span style="font-family: serif;">!export-table --'+ch('<')+'Table Name'+ch('>')+' [ --'+ch('<')+'Table Name'+ch('>')+' ...]</span></b>'
+'<div style="padding-left: 10px;padding-right:20px">'
+'<p>For all table names, case is ignored and you may use partial names so long as they are unique.  For example, '+ch('"')+'King Maximillian'+ch('"')+' could be called '+ch('"')+'max'+ch('"')+' as long as '+ch('"')+'max'+ch('"')+' does not appear in any other table names.  Exception:  An exact match will trump a partial match.  In the previous example, if a table named '+ch('"')+'Max'+ch('"')+' existed, it would be the only table matched for <b>--max</b>.</p>'
+'<ul>'
+'<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'
+'<b><span style="font-family: serif;">--'+ch('<')+'Table Name'+ch('>')+'</span></b> '+ch('-')+' This is the name of a table to export.  You can specify as many tables as you like in a single command.'
+'</li> '
+'</ul>'
+'</div>'
+'</div>'
    +'<div style="padding-left:10px;">'
+'<b><span style="font-family: serif;">!import-table --'+ch('<')+'Table Name'+ch('>')+' --'+ch('<')+'[ show | hide ]'+ch('>')+'</span></b>'
+'<div style="padding-left: 10px;padding-right:20px">'
+'<p>This is the command output by <b>!export-table</b> to create the new table.  You likely will not need issue these commands directly.</p>'
+'<ul>'
+'<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'
+'<b><span style="font-family: serif;">--'+ch('<')+'Table Name'+ch('>')+'</span></b> '+ch('-')+' This is the name of the table to be create.'
+'</li> '
    +'<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'
+'<b><span style="font-family: serif;">--'+ch('<')+'[ show | hide ]'+ch('>')+'</span></b> '+ch('-')+' This whether to show the table to players or hide it.'
+'</li> '
+'</ul>'
+'</div>'
+'</div>'
    +'<div style="padding-left:10px;">'
    +'<b><span style="font-family: serif;">!import-table-item --'+ch('<')+'Table Name'+ch('>')+' --'+ch('<')+'Table Item Name'+ch('>')+' --'+ch('<')+'Weight'+ch('>')+' --'+ch('<')+'Avatar URL'+ch('>')+'</span></b>'
+'<div style="padding-left: 10px;padding-right:20px">'
+'<p>This is the command output by <b>!export-table</b> to create the new table.  You likely will not need issue these commands directly.</p>'
+'<ul>'
+'<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'
+'<b><span style="font-family: serif;">--'+ch('<')+'Table Name'+ch('>')+'</span></b> '+ch('-')+' This is the name of the table to add items to.  <b>Note:</b> unlike for <b>!export-table</b>, this must be an exact name match to the created table.'
+'</li> '
    +'<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'
+'<b><span style="font-family: serif;">--'+ch('<')+'Table Item Name'+ch('>')+'</span></b> '+ch('-')+' This is the name of the table item to create.  <b>Note:</b> Because the string '+ch('"')+' --'+ch('"')+' may occur in a table item name, you may see '+ch('"')+'[TABLEEXPORT:ESCAPE]'+ch('"')+' show up as a replacement in these commands.  This value is corrected internally to the correct '+ch('"')+' --'+ch('"')+' sequence on import.'
+'</li> '
    +'<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'
+'<b><span style="font-family: serif;">--'+ch('<')+'Weight'+ch('>')+'</span></b> '+ch('-')+' This is the weight for this table item and should be an integer value.'
+'</li> '
    +'<li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;">'
+'<b><span style="font-family: serif;">--'+ch('<')+'Avatar URL'+ch('>')+'</span></b> '+ch('-')+' This is the URL for the avatar image of the table item.'
+'</li> '
+'</ul>'
+'</div>'
+'</div>'
+'</div>'
);
},
    nameEscape = (function(){
        var re=new RegExp('('+_.map(_.keys(escapes),esRE).join('|')+')','g');
        return function(s){
            return s.replace(re, function(c){ return escapes[c] || c; });
        };
    }()),
    nameUnescape = (function(){
        var sepacse = _.invert(escapes),
        re=new RegExp('('+_.map(_.keys(sepacse),esRE).join('|')+')','g');
        return function(s){
            return s.replace(re, function(c){ return sepacse[c] || c; });
        };
    }()),
handleInput = function(msg) {
var args, matches, tables, tableIDs=[], errors=[], items, itemMatches, accum='';
if (msg.type !== "api" || !playerIsGM(msg.playerid)) {
return;
}
args = msg.content.split(/\s+/);
switch(args[0]) {
case '!import-table':
args = msg.content.split(/\s+--/);
if(args.length === 1) {
showHelp();
break;
}
if(_.has(tableCache,args[1])) {
sendChat('','/w gm '
+'<div style="border: 1px solid black; background-color: white; padding: 3px 3px;">'
+'<span style="font-weight:bold;color:#990000;">Warning:</span> '
+'Table ['+args[1]+'] already exists, skipping create.'
+'</div>'
);
} else {
tableIDs=findObjs({type: 'rollabletable', name: args[1]});
if(tableIDs.length) {
sendChat('','/w gm '
        +'<div style="border: 1px solid black; background-color: white; padding: 3px 3px;">'
    +'<span style="font-weight:bold;color:#990000;">Warning:</span> '
    +'Table ['+args[1]+'] already exists, skipping create.'
    +'</div>'
);
} else {
tableIDs=createObj('rollabletable',{ 
name: args[1], 
showplayers: ('show'===args[2])
});
tableCache[args[1]]=tableIDs.id;
}
}
break;
case '!import-table-item':
args = msg.content.split(/\s+--/);
if(args.length === 1) {
showHelp();
break;
}
args[2] = nameUnescape(args[2]);
if(!_.has(tableCache,args[1])) {
tableIDs=findObjs({type: 'rollabletable', name: args[1]});
if(!tableIDs.length) {
sendChat('','/w gm '
        +'<div style="border: 1px solid black; background-color: white; padding: 3px 3px;">'
    +'<span style="font-weight:bold;color:#990000;">Error:</span> '
    +'Table ['+args[1]+'] doesn not exist.  Cannot create table item.'
    +'</div>'
    );
                        break;
                    } else {
                        tableCache[args[1]]=tableIDs[0].id;
                    }
                }
                createObj('tableitem',{
                    name: args[2],
                    rollabletableid: tableCache[args[1]],
                    weight: parseInt(args[3],10)||1,
                    avatar: args[4]||''
                });
                break;
                
case '!export-table':
                args = msg.content.split(/\s+--/);
                if(args.length === 1) {
                    showHelp();
                    break;
                }
tables=findObjs({type: 'rollabletable'});
matches=_.chain(args)
.rest()
.map(function(n){
var l=_.filter(tables,function(t){
return t.get('name').toLowerCase() === n.toLowerCase();
});
return ( 1 === l.length ? l : _.filter(tables,function(t){
return -1 !== t.get('name').toLowerCase().indexOf(n.toLowerCase());
}));
})
.value();
_.each(matches,function(o,idx){
if(1 !== o.length) {
if(o.length) {
errors.push('Rollable Table [<b>'+args[idx+1]+'</b>] is ambiguous and matches '+o.length+' names: <b><i> '+_.map(o,function(e){
return e.get('name');
}).join(', ')+'</i></b>');
} else {
errors.push('Rollable Table [<b>'+args[idx+1]+'</b>] does not match any names.');
}
}
},errors);
if(errors.length) {
sendChat('','/w gm '
+'<div style="border: 1px solid black; background-color: white; padding: 3px 3px;">'
+'<div><span style="font-weight:bold;color:#990000;">Error:</span> '
+errors.join('</div><div><span style="font-weight:bold;color:#990000;">Error:</span> ')
+'</div>'
+'</div>'
);
break;
}
if( ! errors.length) {
matches=_.chain(matches)
.flatten(true)
.map(function(t){
tableIDs.push(t.id);
                            return t;
})
.value();
items=findObjs({type: 'tableitem'});
itemMatches=_.chain(items)
.filter(function(i){
return _.contains(tableIDs,i.get('rollabletableid'));
})
                        .reduce(function(memo,e){
                            if(!_.has(memo,e.get('rollabletableid'))) {
                                memo[e.get('rollabletableid')]=[e];
                            } else {
                                memo[e.get('rollabletableid')].push(e);
                            }
                            return memo;
                        },{})
.value();
                    _.each(matches, function(t){
                        accum+='!import-table --'+nameEscape(t.get('name'))+' --'+(t.get('showplayers') ? 'show' : 'hide')+'<br>';
                        _.each(itemMatches[t.id], function(i){
                            accum+='!import-table-item --'+nameEscape(t.get('name'))+' --'+nameEscape(i.get('name'))+' --'+i.get('weight')+' --'+i.get('avatar')+'<br>';
                        });
                    });
                    sendChat('', '/w gm '+accum);
}
break;
}
},
    handleRemoveTable = function(obj){
        tableCache = _.without(tableCache,obj.id);
    },
registerEventHandlers = function() {
on('chat:message', handleInput);
        on('destroy:rollabletable', handleRemoveTable);
};
return {
CheckInstall: checkInstall,
RegisterEventHandlers: registerEventHandlers
};
}());

on("ready",function(){
'use strict';
TableExport.CheckInstall();
TableExport.RegisterEventHandlers();
});


if you want the original, I got it from the Roll20 github, here:

    https://github.com/shdwjk/Roll20API/blob/master/TableExport/TableExport.js


This allows you to export and import tables!

January 28 (2 weeks ago)

Edited January 28 (2 weeks ago)

Since you have a Pro subscription, you can use TableExport to export the table and make adjustments, then import it back in and it'll have a new table ID.

Or it's also pretty simple to just throw the table into an Excel or Google Sheets spreadsheet and using a CONCAT function to create the list of TableExport commands to create the tables. 

Here's an example of what I use:


ABCDEFGH
1
MACRONameWeight Import TableTable Name Item Name%
2
=CONCATENATE(E2,F2,G2,H2)

=IF(C2="","!import-table","!import-table-item")=CONCATENATE(" --",RandomEncounters)=IF(C2="","",CONCATENATE(" --",C2))=IF(C2=""," --hide"," --",D2)
3
=CONCATENATE(E3,F3,G3,H3)Orcs [[2d4]]1=IF(C3="","!import-table","!import-table-item")=CONCATENATE(" --",RandomEncounters)=IF(C3="","",CONCATENATE(" --",C3))=IF(C3=""," --hide"," --",D3)

You only have to worry about filling out columns B and C and copying the rest of the formulas down.  Columns D, E, F, G, and H will be combined together in column B, and then you can just select the entire column and paste it into chat to use TableExport. You may need to add a SUBSTITUTE function column as well if there are special characters (especially left and right brackets) that need to be parsed by TableExport and not by the Roll20 dice roller when the table is imported.

In column A (starting on row 2), that would be this:

=SUBSTITUTE(SUBSTITUTE(B2,"[",<%%91%%>),"]",<%%93%%>)
January 28 (2 weeks ago)

Thankyou both

January 28 (2 weeks ago)
timmaugh
Pro
API Scripter

I'll also plug my TableToTable script... which can get tables into HTML form (in a handout), and read tables from there, too. So you can build your table in Excel, Google Sheets, etc., then import it.

I did a series of videos on it.

January 28 (2 weeks ago)

Edited January 28 (2 weeks ago)

Hmm, having some trouble... nothing happens! 

I removed the --Hide and still see nothing.  Added the table, and additem does nothing.

Cannot get any of the functionality to work - shows nothing in either chat window or API sandbox (except the

"-=> TableExport v0.2.5 <=-  [Mon Dec 16 2019 20:45:32 GMT+0000 (Coordinated Universal Time)]"

)

Tried both the normal and experimental - same

Is this supposed to work on Jumpgate?

How do I turn on verbose mode?

Other API scripts work fine.

Is this right:-

!import-table --RandomEncounters
!import-table-item --RandomEncounters --Orcs [[2d4]] --1


January 28 (2 weeks ago)


timmaugh said:

I'll also plug my TableToTable script... which can get tables into HTML form (in a handout), and read tables from there, too. So you can build your table in Excel, Google Sheets, etc., then import it.

I did a series of videos on it.


I see the menu, but seems to not function - clearly I am doing something wrong somewhere.  But for example the Help Panel info shows when I hover, but I cannot click it. The three Get/new/Append work as far as selecting a table, or new name, but then don't do anything.

I do not access sites like that - and anyway I find video-learning much less effective than text.

Thanks for trying!




January 28 (2 weeks ago)

Edited January 28 (2 weeks ago)
Manny L.
Pro
Marketplace Creator

I just tried the script in my game and it worked fine. The idea is you run export table and it creates the import script, so you can copy/paste it into another game.


Here's a sample:


Command (NB: I already have the table, called CT-1_CrushCritical in my game):

!export-table --CT-1_CrushCritical


Output:

!import-table --CT-1_CrushCritical --show
!import-table-item --CT-1_CrushCritical -- <%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=-49-05}} {{Description=Weak grip. No extra damage.}} --55 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=06-20}} {{Description=Minor fracture of ribs.}} {{Hits = +5}} {{Wound = Broken Rib}} {{Activity = -5}} --15 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=21-35}} {{Description=Blow to side.}} {{Hits = +4}} {{Activity = -40 x 1 round}} --15 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=36-50}} {{Description=Blow to forearm.}} {{Hits = +5}} {{Stunned = 1 round}} --15 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=51-65}} {{Description=Blow to shield shoulder breaks shield. If no shield: shoulder broken, arm useless.}} {{Hits = +5}} {{w/o shield: Wound = Shield Arm - Shoulder Broken}} --15 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=66-79}} {{Description=Blow breaks bone in leg.}} {{Hits = +12}} {{Wound = Broken Leg}} {{Activity = -40}} {{Stunned = 2 rounds}} --14 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=80}} {{Description=Strike to forehead.}} {{Hits = +30}} {{Wound = Eye Destroyed}} {{Stunned = 24 rounds}} {{w/o helm = 1 month coma}} --1 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=81-86}} {{Description=Blow breaks weapon arm. Arm useless. Tendon damage.}} {{Hits = +8}} {{Wound = Weapon Arm - Broken and Tendon Damaged}} {{Stunned = 2 rounds}} --6 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=87-89}} {{Description=Shatter knee.}} {{Hits = +9}} {{Wound = Knee Shattered}} {{Activity = -60}} {{Condition = Downed}} {{Stunned = 3 rounds}} --3 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=90}} {{Description=Blow to back of neck paralyzes from the shoulders down.}} {{Hits = +25}} {{Wound = Neck - Broken and Nerve Destroyed}} {{Condition = Paralyzed}} --1 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=91-96}} {{Description=Unconscious for 4 hours due to blow to side of head.}} {{Hits = +20}} {{w/o helm = Skull Crushed, Dead}} --6 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=97-99}} {{Description=Blast to chest sends ribcage though lungs. Drops and dies in 6 rounds. Vicious.}} {{Condition = Dead in 6 rounds}} --3 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=100}} {{Description=Blow to jaw drives bone into brain. Dies instantly.}} {{Condition = Dead}} --1 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=101-106}} {{Description=Blow breaks hip.}} {{Hits = +15}} {{Wound = Hip Broken}} {{Activity = -75}} {{Condition = Downed}} {{Stunned = 3 rounds}} --6 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=107-109}} {{Description=Neck strike crushes throat. Cannot breath and stunned. Poor fool then expires.}} {{Wound = Throat Crushed}} {{Stunned = 12 rounds}} {{Condition = Dead in 12 rounds}} --3 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=110}} {{Description=Crushes hip.}} {{Hits = +35}} {{Wound = Hip Crushed and Nerves Destroyed}} {{Stunned = 2 rounds}} {{Condition = Dead in 6 rounds}} --1 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=111-116}} {{Description=Shatter elbow in weapon arm. Arm useless.}} {{Hits = +35}} {{Wound = Weapon Arm Elbow Shattered}} {{Stunned = 5 rounds}} --6 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=117-119}} {{Description=Blow to side crushes chest cavity. Drops and dies in 3 rounds.}} {{Wound = Chest Crushed, Multiple Organs and Bones Destroyed}} {{Condition = Downed, Dead in 3 rounds}} --3 --
!import-table-item --CT-1_CrushCritical --<%%amp%%>{template:default} {{name=Crush Critical Result}} {{Roll=120}} {{Description=Blast to chest area. Destroy heart, foe dies immediately. Fine work.}} {{Hits = +25}} {{Wound = Heart Destroyed}} {{Condition = Dead}} --1 --




I've not enabled Jumpgate in my game , so not sure if that would affect any of the script behaviour.


If you want to test this in your game, you can use the above commands in reverse, e.g. run that import script followed by the export command.

January 29 (2 weeks ago)

I tried it in a non-Jumpgate game and worked

I copied that game to make it Jumpgate - also works

Retried in the game I want it in - did not work.

So must be a clash of scripts? - I have a lot of API scripts in that game.  It's midnight here so I will sort it out later ....  Probably create in a new game then copy over using the Transmogrifier, or try disabling some API. Or just have a game for random encounters which I run as well as main game!


February 07 (6 days ago)

Ok so I have two test games now, one Legacy, one Jumpgate.

In both I can create random encounter tables, using the script Manny posted.

!import-table --RandomEncounters
!import-table-item --RandomEncounters --Orcs [[2d4]] --1

Issue is that it posts as Orcs $[[0]] not Orcs [[2d4]]

I fix this in the table manually and does not roll when use the roll (with or without the $).  So I find and use Rollable Table Macros and the versio without $ rolls the value, in both Legacy and Jumpgate.

So how do I stop that script adding the $ .. I used the one linked (the original) and also adds the $

I assume it is this code -

        var entities = {
            '<' : 'lt',
            '>' : 'gt',
            "'" : '#39',
            '@' : '#64',
            '*' : 'ast',
            '`' : '#96',
            '{' : '#123',
            '|' : '#124',
            '}' : '#125',
            '[' : '#91',
            ']' : '#93',
            '"' : 'quot',
            '-' : 'mdash',
            ' ' : 'nbsp',
            '&' : 'amp'
        };
        if(_.has(entities,c) ){
            return ('&'+entities[c]+';');

So why is it there? 

Anyway I removed the two lines

            '[' : '#91',
            ']' : '#93',

and still converts [[2d4]] into $[[0]]

Tried /[[2d4]] and \[[2d4]] but just added the extra character.





February 07 (6 days ago)

The TableExport command needs to 'escape' the brackets (so that Roll20 doesn't recognize them as a roll when the command is first entered into chat), so it should look like this instead:

!import-table --RandomEncounters
!import-table-item --RandomEncounters --Orcs <%%91%%><%%91%%>2d4<%%93%%><%%93%%> --1
February 07 (6 days ago)


Jarren said:

The TableExport command needs to 'escape' the brackets (so that Roll20 doesn't recognize them as a roll when the command is first entered into chat), so it should look like this instead:

!import-table --RandomEncounters
!import-table-item --RandomEncounters --Orcs <%%91%%><%%91%%>2d4<%%93%%><%%93%%> --1


Thanks Jarren.  That fixed it.

Sadly I have now to build the tables I have been putting off, lol