I noticed that the ability descriptions in my script cut off after line breaks. The formatting for the ability descriptions is necessary due to the wide range of ability types in the game I'm coding; some have success/fail conditions, some have upgrades, and it's much easier to include it all in one text field. Before, I just sent these descriptions out via default template roll buttons and they worked fine, but I decided I wanted to do launch custom FX linked to the custom character sheets, so API was necessary. Now, those descriptions are cutting off at the first line break. No error message, but the rest is pasted outside of the roll template. Is there any way around this? I've looked for solutions but can't seem to find anyone addressing this. Should I be using splitArgs somehow? I'm at a loss. The description attribute I have to output is "power", and it usually looks like: Make a Basic attack Roll Success: Do a thing. Failure: Do the thing, but at half effect and suffer X. Upgrade 1: Do it faster Upgrade 2: Do it cooler. Here's the button input: !fxpower --@{character_id} --@{target|character_id} --@{powername} --@{powercost} --@{powerfx} --@{selected|token_id} --@{target|token_id} --@{power} Here's the code: // wait till the ready event before registering a chat handler on('ready', () => { // create a function to return attribute value, given character id and attribute name. const getLocation = function(id, choice) { let location = parseInt((findObjs({ type: 'attribute', characterid: id, name: choice })[0] || { get: () => -1 }).get('current')); return location; }; on('chat:message', (msg) => { // make sure the message is an api command, then verify it starts with !fxpower if ('api' === msg.type && /^!fxpower\b/i.test(msg.content)) { const args = msg.content.split(/\s+--/); log(args); let c = getObj('character',args[1]); // verify we got a character if(c){ let name = getAttrByName(c.id, "character_name"); let skillAttr = findObjs({type:'attribute',characterid:args[1]}) log(name); let t = getObj('character',args[2]); if (t) { let tname = getAttrByName(t.id, "character_name"); log(tname); const pname = args[3]; const cost = args[4]; const fx = args[5]; log(fx); const ctoken = args[6]; const ttoken = args[7]; const power = args[8]; log(power); //find the right custom fx based on the attribute let fxid = findObjs({_type: "custfx", name: fx})[0].id; log(fxid); //find the coordinates of a const tokenCenter = (id) => { const token = getObj('graphic', id); return { x: Math.round(token.get('left')), y: Math.round(token.get('top')) } }; let output = `&{template:default} {{name= ${name} }} {{POWER= ${pname} }} {{COST= ${cost} }} {{DESC.= ${power} }}`; sendChat('', output); if ((fx == "hammer") || (fx == "melee") || (fx == "stab") || (fx == "bite")){ let p = tokenCenter(ttoken); spawnFx(p.x, p.y, fxid) } else { spawnFxBetweenPoints(tokenCenter(ctoken), tokenCenter(ttoken), fxid); log(tokenCenter(ttoken)); log(tokenCenter(ctoken)); log(spawnFxBetweenPoints(tokenCenter(ctoken), tokenCenter(ttoken), fxid)); } } } } }); });