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

Question for someone in know

1707325324

Edited 1707325395
My question is I have long used a blank custom character sheet to be able to quickly pull torches, lanterns etc. by having the torch or lantern token saved to the sheet as a torch or lantern etc.  Once I pull those to place on a map and then move it to the map layer so that it is a permeant fixture on a map which is to say no longer a token tied to a character sheet, yet it is.  Is it at that point still token and therefore have to load as such and thusly possibly causing issues with Looping script errors?
1707326950

Edited 1707327237
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Hi Aramathis! Tokens are perfectly capable of existing on any layer. Their display behavior may change, but moving a token that represents a character to the DL or Map layer does not break the Represents field. If you make sure your torch token is using an NPC sheet (assuming the D&D 5th Edition by Roll20 Sheet), and don't add any data and don't link any bars, the performance overhead should be negligible, even with many tokens placed.
1707327309
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Looking back at your question, none of the procedures you outline utilize a script. Can you describe the error you are experiencing in more detail>
1707329552

Edited 1707329796
Hi Keith, my situation is really that my campaign in so large that scripts just do not work anymore because I get a looping error even if I reload it, it will instantly go to error again(see below). I have asked in the past and been advised to make a vault game storing all my maps which I have done but having to move the character sheets back and forth to the main game from the vault etc. is really troublesome. The reason I asked this time  is I was thinking that maybe the torches and lanterns on many of my saved maps may be seen as separate characters since they are tied to a character sheet that says Torch, lantern etc. but are then sent to the map layer as a village permanent lantern as an example.  Below is the error I get: Your scripts are currently disabled due to an error that was detected. Please make appropriate changes to your script's code and click the "Save Script" button. We will then attempt to start running the scripts again.  More info...  If this script was installed from the Mod Library, you might find help in the Community API Forum. For reference, the error message generated was:  Possible infinite loop detected, shutting down. -------------- It would be nice if the timer that times out giving this Looping error could be extended but I assume that would have to be for everyone and most game are not as large .
1707329949
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
If this is a game-size related error, your game must be extremely large indeed. My current campaign runs about 4 dozen scripts, has 265 characters and 193 pages. My guess is that unless yours is larger than that by a good margin, the problem is likely a particular script.  You could try disabling scripts by halves and zeroing in on the problem script.
1707330788

Edited 1707331425
I only use three scripts so I will post them for you. The most important one is hex facing script.&nbsp; I have disabled the other two scripts and just this 1 script along causes the looping error.&nbsp; I then disabled it and loaded the Sheet Detector with the same result. The third script is called Realrollable table but since none of them work even with the others off I have no idea. Now on another smaller game my facing script works fine which lead me to think it was size. I would be very grateful if I could get the scripts working again.&nbsp; My current game has about 400 saved maps, 150 characters with 3 scripts that of course&nbsp; do not work. This below is the most important of the three:&nbsp; Facing Script made by The Aaron, he has a newer version but it didnt work when I tried it. // Github: <a href="https://github.com/shdwjk/Roll20API/blob/master/Facing/Facing.js" rel="nofollow">https://github.com/shdwjk/Roll20API/blob/master/Facing/Facing.js</a> // By: The Aaron, Arcane Scriptomancer // Contact: <a href="https://app.roll20.net/users/104025/the-aaron" rel="nofollow">https://app.roll20.net/users/104025/the-aaron</a> var Facing = Facing || (function() { 'use strict'; var version = '0.1.3', lastUpdate = 1490707181, schemaVersion = 0.1, defaults = { image: ' <a href="https://s3.amazonaws.com/files.d20.io/images/9183999/XcViJVf7-cGOXcZq1KWp-A/thumb.png?1430541914" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/9183999/XcViJVf7-cGOXcZq1KWp-A/thumb.png?1430541914</a> ', attributeName: 'facing', scale: 2.5 }, checkInstall = function() { log('-=&gt; Facing v'+version+' &lt;=- ['+(new Date(lastUpdate*1000))+']'); if( ! _.has(state,'Facing') || state.Facing.version !== schemaVersion) { log(' &gt; Updating Schema to v'+schemaVersion+' &lt;'); switch(state.Facing &amp;&amp; state.Facing.version) { case 0: default: state.Facing = { version: schemaVersion, config: { image: defaults.image, attributeName: defaults.attributeName, relative: true, scale: defaults.scale }, ringed: {} }; break; } } }, ch = function (c) { var entities = { '&lt;' : 'lt', '&gt;' : 'gt', "'" : '#39', '@' : '#64', '{' : '#123', '|' : '#124', '}' : '#125', '[' : '#91', ']' : '#93', '"' : 'quot', '-' : 'mdash', ' ' : 'nbsp' }; if(_.has(entities,c) ){ return ('&amp;'+entities[c]+';'); } return ''; }, getCleanImgsrc = function (imgsrc) { var parts = imgsrc.match(/(.*\/images\/.*)(thumb|max)(.*)$/); if(parts) { return parts[1]+'thumb'+parts[3]; } return; }, getRingedPair = function(id) { var ringed; _.find(state.Facing.ringed,function(slaveid,masterid){ if(id === masterid || id === slaveid) { ringed = { master: getObj('graphic',masterid), slave: getObj('graphic',slaveid) }; ringed.attribute = findObjs({ type: 'attribute', name: state.Facing.config.attributeName, characterid: ringed.master &amp;&amp; ringed.master.get('represents') })[0] || {set:function(){}}; return true; } return false; }); return ringed; }, getRinged = function(id) { var ringed; _.find(state.Facing.ringed,function(slaveid,masterid){ if(id === masterid){ ringed = getObj('graphic',slaveid); return true; } if(id === slaveid) { ringed = getObj('graphic',masterid); return true; } return false; }); return ringed; }, createRinged = function(id) { // get root obj var master = getObj('graphic',id), slave = getRinged(id), layer, dim; if(!slave &amp;&amp; master) { layer=( 'gmlayer' === master.get('layer') ? 'gmlayer' : 'map'); dim=(Math.max(master.get('height'),master.get('width'))*state.Facing.config.scale); slave = createObj('graphic',{ imgsrc: state.Facing.config.image, layer: layer, pageid: master.get('pageid'), top: master.get('top'), left: master.get('left'), height: dim, width: dim, rotation: master.get('rotation') }); master.set({ rotation: 0 }); ( findObjs({ type: 'attribute', name: state.Facing.config.attributeName, characterid: master.get('represents') })[0] || (master.get('represents') &amp;&amp; createObj('attribute',{ name: state.Facing.config.attributeName, characterid: master.get('represents') })) || { set: function(){} }).set({ current: slave.get('rotation') }); if('gmlayer' === layer) { toBack(slave); } else { toFront(slave); } state.Facing.ringed[master.id]=slave.id; } }, removeRinged = function(id) { var pair=getRingedPair(id); if(pair) { if(id === pair.master.id ) { pair.slave.remove(); } delete state.Facing.ringed[pair.master.id]; } }, zeroToken = function(id) { var pair=getRingedPair(id); if(pair) { pair.slave.set({ rotation: 0 }); } }, facingToken = function(id) { var pair=getRingedPair(id); if(pair) { removeRinged(id); } else { createRinged(id); } }, handleRemoveToken = function(obj) { // special handling for deleting slaves? removeRinged(obj.id); }, handleTokenChange = function(obj,prev) { var pair = getRingedPair(obj.id), layer, dim, rot; if(pair) { if(pair.master.id === obj.id) { layer=( 'gmlayer' === pair.master.get('layer') ? 'gmlayer' : 'map'); dim=(Math.max(pair.master.get('height'),pair.master.get('width'))*state.Facing.config.scale); rot=pair.master.get('rotation'); if(rot !== prev.rotation ) { if(state.Facing.config.relative) { rot = (pair.slave.get('rotation') + rot + 360) % 360; } } else { rot = pair.slave.get('rotation'); } pair.attribute.set({ current: rot }); pair.slave.set({ layer: layer, top: pair.master.get('top'), left: pair.master.get('left'), height: dim, width: dim, rotation: rot }); pair.master.set({ rotation: 0 }); if('gmlayer' === layer) { toBack(pair.slave); } else { toFront(pair.slave); } } else { pair.slave.set({ width: prev.width, height: prev.height, top: prev.top, left: prev.left, layer: prev.layer, flipv: prev.flipv, fliph: prev.fliph }); pair.attribute.set({ current: pair.slave.get('rotation') }); } } }, getConfigOption_RingImage = function() { var text = state.Facing.config.image; return '&lt;div&gt;'+ 'Direction Indicator:'+ '&lt;img src="'+text+'" style="width: 70px; height: 70px;"&gt;'+ '&lt;a href="!facing-config --set-image|@{target|token_id}"&gt;'+ 'Pick'+ '&lt;/a&gt;'+ '&lt;a href="!facing-config --set-image|"&gt;'+ 'Default'+ '&lt;/a&gt;'+ '&lt;/div&gt;'; }, getConfigOption_AttributeName = function() { var text = state.Facing.config.attributeName; return '&lt;div&gt;'+ 'Attribute Name to set facing value: &lt;b&gt;'+ text+ '&lt;/b&gt;&lt;a href="!facing-config --set-attribute-name|?{What attribute should the facing be stored in (empty for default):|'+state.Facing.config.attributeName+'}"&gt;'+ 'Set Name'+ '&lt;/a&gt;'+ '&lt;/div&gt;'; }, getConfigOption_Relative = function() { var text = (state.Facing.config.relative ? 'On' : 'Off' ); return '&lt;div&gt;'+ 'Relative Rotation is currently &lt;b&gt;'+ text+ '&lt;/b&gt; '+ '&lt;a href="!facing-config --toggle-relative"&gt;'+ 'Toggle'+ '&lt;/a&gt;'+ '&lt;/div&gt;'; }, getConfigOption_Scale = function() { var text = state.Facing.config.scale; return '&lt;div&gt;'+ 'Scale is currently &lt;b&gt;'+ text+ '&lt;/b&gt; '+ '&lt;a href="!facing-config --set-scale|?{Scale to adjust Facing Token to (empty for default):|'+state.Facing.config.scale+'}"&gt;'+ 'Set'+ '&lt;/a&gt;'+ '&lt;/div&gt;'; }, getAllConfigOptions = function() { return getConfigOption_RingImage()+ getConfigOption_AttributeName()+ getConfigOption_Relative()+ getConfigOption_Scale(); }, showHelp = function(who) { sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +'&lt;div style="font-weight: bold; border-bottom: 1px solid black;font-size: 130%;"&gt;' +'Facing v'+version +'&lt;/div&gt;' +'&lt;div style="padding-left:10px;margin-bottom:3px;"&gt;' +'&lt;p&gt;Facing adds a ring below the selected token with a pointer for the direction the token is facing. Rotating the token will rotate the ring and then the token will reset to no rotation. If the token is associated with a character, Facing will maintain an attribute on the character with the current facing stored in it.&lt;/p&gt;' +'&lt;/div&gt;' +'&lt;b&gt;Commands&lt;/b&gt;' +'&lt;div style="padding-left:10px;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;!facing [--help]&lt;/span&gt;&lt;/b&gt;' +'&lt;div style="padding-left: 10px;padding-right:20px"&gt;' +'&lt;p&gt;Adds or removes the Facing ring below a token.&lt;/p&gt;' +'&lt;ul&gt;' +'&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;--help&lt;/span&gt;&lt;/b&gt; '+ch('-')+' Shows the Help screen' +'&lt;/li&gt; ' +'&lt;/ul&gt;' +'&lt;/div&gt;' +'&lt;/div&gt;' +'&lt;div style="padding-left:10px;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;!zero [--help]&lt;/span&gt;&lt;/b&gt;' +'&lt;div style="padding-left: 10px;padding-right:20px"&gt;' +'&lt;p&gt;Aligns the indicator to north.&lt;/p&gt;' +'&lt;ul&gt;' +'&lt;li style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;"&gt;' +'&lt;b&gt;&lt;span style="font-family: serif;"&gt;--help&lt;/span&gt;&lt;/b&gt; '+ch('-')+' Shows the Help screen' +'&lt;/li&gt; ' +'&lt;/ul&gt;' +'&lt;/div&gt;' +'&lt;/div&gt;' +getAllConfigOptions() +'&lt;/div&gt;' ); }, handleInput = function(msg) { var args, who; if (msg.type !== "api" ) { return; } who=(getObj('player',msg.playerid)||{get:()=&gt;'API'}).get('_displayname'); args = msg.content.split(/\s+/); switch(args.shift()) { case '!facing': if(!msg.selected || _.contains(args,'--help')) { showHelp(who); return; } _.each(msg.selected,function(s){ facingToken(s._id,who); }); break; case '!zero': if(!msg.selected || _.contains(args,'--help')) { showHelp(who); return; } _.each(msg.selected,function(s){ zeroToken(s._id,who); }); break; case '!facing-config': if(!playerIsGM(msg.playerid)) { sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +'&lt;div&gt;&lt;b&gt;Error:&lt;/b&gt; Only the GM may configure Facing.&lt;/div&gt;' +'&lt;/div&gt;' ); return; } if(_.contains(args,'--help')) { showHelp(who); return; } if(!args.length) { sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +'&lt;div style="font-weight: bold; border-bottom: 1px solid black;font-size: 130%;"&gt;' +'Facing v'+version +'&lt;/div&gt;' +getAllConfigOptions() +'&lt;/div&gt;' ); return; } _.each(args,function(a){ var opt=a.split(/\|/), tmp,omsg=''; switch(opt.shift()) { case '--set-image': if(opt.length &amp;&amp; opt[0].length) { tmp=getObj('graphic',opt[0]); if(tmp &amp;&amp; getCleanImgsrc(tmp.get('imgsrc')) ) { state.Facing.config.image = getCleanImgsrc(tmp.get('imgsrc')); } else { omsg='&lt;div&gt;&lt;b&gt;Error:&lt;/b&gt; '+ ( tmp ? 'Cannot use Marketplace Images.' : 'Not a valid ID: '+opt[0]) +'&lt;/div&gt;'; } } else { state.Facing.config.image = defaults.image; } sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +omsg +getConfigOption_RingImage() +'&lt;/div&gt;' ); break; case '--set-attribute-name': if(opt.length &amp;&amp; opt[0].length) { state.Facing.config.attributeName = opt[0]; } else { state.Facing.config.attributeName = defaults.attributeName; } sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +getConfigOption_AttributeName() +'&lt;/div&gt;' ); break; case '--toggle-relative': state.Facing.config.relative=!state.Facing.config.relative; sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +getConfigOption_Relative() +'&lt;/div&gt;' ); break; case '--set-scale': if(opt.length &amp;&amp; opt[0].length) { tmp = parseFloat(opt[0]); if(tmp) { state.Facing.config.scale = tmp; } else { omsg='&lt;div&gt;&lt;b&gt;Error:&lt;/b&gt; Not a valid number: '+opt[0]+'&lt;/div&gt;'; } } else { state.Facing.config.scale = defaults.scale; } sendChat('','/w "'+who+'" ' +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' +omsg +getConfigOption_Scale() +'&lt;/div&gt;' ); break; default: sendChat('','/w "'+who+'" ' +'&lt;div&gt;&lt;b&gt;Unsupported Option:&lt;/div&gt; '+a+'&lt;/div&gt;' ); } }); break; } }, registerEventHandlers = function() { on('chat:message', handleInput); on('change:graphic', handleTokenChange); on('destroy:graphic', handleRemoveToken); }; return { CheckInstall: checkInstall, RegisterEventHandlers: registerEventHandlers }; }()); on('ready',function() { 'use strict'; Facing.CheckInstall(); Facing.RegisterEventHandlers(); });
1707346462
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Hmm. You shouldn't have to "update" a script. that should be automatic. When you add a script to your game, are you clicking the "Add Script" button or the "import" button? The Import button should only be used if you are planning to alter the code of the script. Add Script will link you to the source so that your game always loads the latest code, ensuring that the latest bug fixes are available to you. If you are loading the scripts via "Add Script" and still getting an error on your large game but not on a small one, it could either be the size, or a bad config setting that is causing the issue. I'll see if I can call more attention to this.
Any help would be greatly appreciated. I just use the "New Script" click it then cut and paste it in. They work fine on a smaller game but not my large game.&nbsp; Another thing on my large game is that I cannot even make a copy of the game as it fails when I try to. I am not sure on the Bad Config setting how I would know that. Thank you vey much for the assistance as I would love to get it to work again with the scripts.&nbsp;
1707358668
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
The inability to make a copy is a pretty good sign of overwhelming size. Roll20 has made numerous back end improvements on this end--I used to not be able to duplicate my own game, years ago, and it is larger now--but there are still limits. I know transmogging can be a slowdown, but I really would second the recommendation of a&nbsp; Library Campaign . As for adding scripts, the process you describe I use only when a script does not exist in the repo. Adding from One Click is usually a much better practice.
1707363858
The Aaron
Roll20 Production Team
API Scripter
It sounds like the sandbox is taking too long to load all the objects. &nbsp;The only other thing I can think of with be if there is something going wrong with character sheet sheet workers, which also run on the APi Sandbox. You could try disabling all scripts and running just this script to see if it's a sandbox startup issue: on('ready',()=&gt;log('ready event occurred')); If you don't get that message in the console, and get a heartbeat, it's not the scripts.&nbsp;
I am sure that is what it is as I have been all day making a Library campaign and the scripts are all working on the non library game.&nbsp; The only odd thing now is some of the stuff I transmog over is blank or missing on handouts. A second thing is some Transmog maps I can see on my main game and they are&nbsp; giving me a blank screen on the display&nbsp; on the new one even know the mini pic above shows the map image.&nbsp; Thanks so much for weighing in, it is really appreciated.&nbsp;