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

[Script] UniversalVTTImporter -- Import .dd2vtt files to create Dynamic Lighting Lines and Lights!

Andan said: ...and of course, after onemore  !uvtt, the new settings showed up. Thanks for the help  The Aaron !
Worked like a charm! I love the RPG community, thanks a bunch for making this public.
1608047763
The Aaron
Roll20 Production Team
API Scripter
No problem!  Glad it's working for you!
I'm very new to game mastering on roll20. I'm confused by the instructions. How do I install this software? Is there a different tool that generates the .dd2vtt file? Sorry, just confused by the instructions and the universal VTT tool doesn't have a readme in the GitHub.
1608125661
The Aaron
Roll20 Production Team
API Scripter
API scripts require a pro subscription. .dd2vtt fires are the export format of Dungeon Draw. 
I have a question does the Script support updated Dynamic Lightning?
1612013142
The Aaron
Roll20 Production Team
API Scripter
Yes, such as it is. It will detect which is in use on the page and set the lighting appropriately for it. 
1614563993

Edited 1614564015
Hello, this looks cool! However, I am also getting the issue that Malik H. had, the "Error: Universal VTT Data is missing or corrupt" error. I have the graphic selected, used the Universal VTT Import Sanitizer from the Universal VTT file (from Dungeondraft), and pasted the output into GM notes of the graphic selected. I shut off all other API scripts like he did, but still am getting the error. The output is below in the codeblock: {"format":0.2,"resolution":{"map_origin":{"x":0,"y":0},"map_size":{"x":35,"y":30},"pixels_per_grid":70},"line_of_sight":[[{"x":19,"y":23},{"x":23,"y":23},{"x":23,"y":24},{"x":22,"y":24},{"x":22,"y":26},{"x":11,"y":26},{"x":11,"y":25},{"x":12,"y":25},{"x":12,"y":23},{"x":13,"y":23},{"x":13,"y":24},{"x":19,"y":24},{"x":19,"y":23}],[{"x":18,"y":18},{"x":20,"y":18},{"x":20,"y":19},{"x":24,"y":19},{"x":24,"y":18},{"x":25,"y":18},{"x":25,"y":22},{"x":19,"y":22},{"x":19,"y":20},{"x":18,"y":20},{"x":18,"y":18}],[{"x":24,"y":17},{"x":24,"y":12},{"x":28,"y":12},{"x":28,"y":15},{"x":30,"y":15},{"x":30,"y":21},{"x":29,"y":21},{"x":29,"y":22},{"x":26,"y":22},{"x":26,"y":17},{"x":24,"y":17}],[{"x":19,"y":8},{"x":21,"y":8},{"x":21,"y":10},{"x":20,"y":10},{"x":20,"y":17},{"x":17,"y":17},{"x":17,"y":20},{"x":13,"y":20},{"x":13,"y":22},{"x":12,"y":22},{"x":12,"y":21},{"x":7,"y":21},{"x":7,"y":20},{"x":11,"y":20},{"x":11,"y":13},{"x":10,"y":13},{"x":10,"y":9},{"x":11,"y":9},{"x":11,"y":8},{"x":15,"y":8},{"x":15,"y":9},{"x":19,"y":9},{"x":19,"y":8}],[{"x":11,"y":4},{"x":16,"y":4},{"x":16,"y":5},{"x":15,"y":5},{"x":15,"y":6},{"x":11,"y":6},{"x":11,"y":4}],[{"x":30.992188,"y":0},{"x":31,"y":0},{"x":31,"y":2},{"x":33,"y":2},{"x":33,"y":15},{"x":31,"y":15},{"x":31,"y":21},{"x":34,"y":21},{"x":34,"y":25},{"x":29,"y":25},{"x":29,"y":23},{"x":26,"y":23},{"x":26,"y":28},{"x":22,"y":28},{"x":22,"y":27},{"x":10,"y":27},{"x":10,"y":25},{"x":5,"y":25},{"x":5,"y":21},{"x":6,"y":21},{"x":6,"y":20},{"x":2,"y":20},{"x":2,"y":18.027344},{"x":-0.800781,"y":18.027344},{"x":-0.800781,"y":14.984375},{"x":2,"y":14.984375},{"x":2,"y":13},{"x":9,"y":13},{"x":9,"y":9},{"x":6,"y":9},{"x":6,"y":1},{"x":11,"y":1},{"x":11,"y":3},{"x":16,"y":3},{"x":16,"y":1},{"x":22,"y":1},{"x":22,"y":5},{"x":19,"y":5},{"x":19,"y":7},{"x":22,"y":7},{"x":22,"y":10},{"x":24,"y":10},{"x":24,"y":11},{"x":28,"y":11},{"x":28,"y":10},{"x":27,"y":10},{"x":27,"y":2},{"x":29,"y":2},{"x":29,"y":0.957031},{"x":28.992188,"y":0.957031},{"x":28.992188,"y":-1.320313},{"x":30.992188,"y":-1.320313},{"x":30.992188,"y":0}]],"portals":[],"environment":{"baked_lighting":true,"ambient_light":"ffffffff"},"lights":[]} What am I doing wrong, if anything? Thanks.
I am also getting the " (From ): Error: Universal VTT Data is missing or corrupt." Error...
1614663087
The Aaron
Roll20 Production Team
API Scripter
Hmm. Sorry I didn't get back to you today, it's a super busy week for me. I'll try and take a look tomorrow. 
It worked this time. Not sure why it didn't before, but I was able to get it to go. Once again -- ty for your hard work!!
1614752688
The Aaron
Roll20 Production Team
API Scripter
That's great to hear!  I still need to investigate Caymon's issue, maybe it's working for them now too. 
1614799817

Edited 1614800411
I'm not understanding how to run the !uvtt. I've tried "/run !uvtt", "/run!uvtt", and just "!uvtt". nothing seems to work.I keep getting "Unrecognized Command". I just started using Dungeondraft and I would love to be able to import them easily. I do have a Pro subscription to Roll20.
1614800112
The Aaron
Roll20 Production Team
API Scripter
Have you installed UniversalVTTImporter from the Script Library on the API Scripts page of your game?
Not that I know of. How do I go about doing that?
Nevermind. I figured it out. Thanks for everything, this makes map making so much easier.
1614801732
The Aaron
Roll20 Production Team
API Scripter
Great!  Let me know if you run into any issues or think of anything that could be added to this.
oh, so we need a Pro account to use this? I bought the plus in order to unlock dynamic light. But I can't because even with dynamic light, if I can't use API script, I can't use it? Did I miss something?
1615387994
The Aaron
Roll20 Production Team
API Scripter
That's correct, sorry for the delay in responding.  The API is a Pro Subscriber Perk.  You can draw Dynamic Lighting lines with a Plus subscription, but you need a Pro subscription to use API scripts.
Hi Aaron the wonderful API!. I think this is likely my lack of understanding but after I run the script my maps end up with circles everywhere? I have attached some screenshots. Happy to provide any further clarification as necessary.
1619367742
The Aaron
Roll20 Production Team
API Scripter
Those are likely the light sources for the map.  If you go to the DL layer, you'll see some green spots where each light source is centered. That said, that highlighted a bug in the way bright and dim light are specified for UDL, which I've now fixed and pushed up.  it should be available in the 1-click Tuesday.  You'll have to select your map and run: !uvtt --clear !uvtt to fix the light sources, or manually edit them, sorry about that.
1619367793
The Aaron
Roll20 Production Team
API Scripter
Update v0.1.7 -- Fixed Bright and Dim Light calculations on UDL. (Thanks  iamonlv426 )
Thanks, Aaron that's brilliant really appreciate your prompt reply. 
Hey Aaron I still haven't seen it appear in the 1-click as yet - how long does it normally take?
1620052804
The Aaron
Roll20 Production Team
API Scripter
Hmm..  Looks like the API pull requests weren't pulled in last week.  I'd expect it to show up tomorrow evening.
Thanks Aaron.
This API script is awesome.  Such a time saver. I'm trying to use it to set the lighting for a multi-level building, and am running into some usability speed bumps.  Since it's using the GM notes to get the coordinate info, I can only store the lighting geometry for one level of the building, and need to save the JSON for the other floors elsewhere.  Clearing the lighting, swapping the JSON out manually, and rerunning the `uvtt` command is workable, but definitely breaks the flow of gameplay. To aid in scripting, could optional arguments be added to the `uvtt` command to specify the lighting geometry and target token object manually? That or a way for it to index into a list of geometries in the GM notes based on the current index in the selected token's rollable table.
1622770884
The Aaron
Roll20 Production Team
API Scripter
hmm.  I'm having a hard time understanding why the GMNotes wouldn't hold all the light info, or alternately why you'd need to overwrite the GMNotes for different graphics?  Can you lay it out lay it out in more detail for me, or perhaps PM me a link to your assets so I can try and duplicate the issue?
I can't get any maps to work with this anymore. In the past, the standard instructions have worked just fine, but even with the API up to date, nothing happens when I run the !uvtt command. Is there anything new that I'm missing?
1623774186
The Aaron
Roll20 Production Team
API Scripter
You have the graphic selected, and you've put the json data in the gm notes on it?
I did. No idea what happened, but I deleted and reinstalled the API again, and it worked this time. Unsure why, but at least it works!
1623774465
The Aaron
Roll20 Production Team
API Scripter
Hmm.  Tuesday is when they do API updates, it may have been that the API sandbox in your game was in a weird state.  Glad you got it working and let me know if you have any more issues. 
Hi @aaron,  first off, I love your scripts.  I installed this one and was able to successfully import all the dynamic lighting for a map in minutes. the instructions were spot on. But. now I tried a second map on a second page and it keeps complaining about missing or corrupt vtt data. I did everything the same... I even tried re-importing the vtt data that worked the first time and it still complains about bad data. Any Ideas? I already tried downgrading to 1.6 and deleted and reinstalled. I restarted the sandbox several times and reuploaded the image too. 
1626884036
The Aaron
Roll20 Production Team
API Scripter
Hmm. That's peculiar. If you want to pm me the file contents, or invite me to your game and GM me, I can take a look. 
Never mind. I figured it out in the end. I've been installing too many extensions! got a bit carried away. After diasbling the conflicting code it all worked as expected. 
1626909046
The Aaron
Roll20 Production Team
API Scripter
Great!
1629196266

Edited 1629196772
Alex D. said: Never mind. I figured it out in the end. I've been installing too many extensions! got a bit carried away. After diasbling the conflicting code it all worked as expected.  Can you please let us know what the conflicting code was? I am having the same issue and also have a few other scripts and extensions installed, so I'd like to try and narrow it down if possible. Edit: I discovered the solution to the problem. I had not assigned the map token to represent an actual location in the journal, it was just a generic token that I had put down. To solve the issue, I created a 'character' for the map and assigned the map token to it, making sure that the token represented the map, before running the command again. Hopefully this helps anyone who makes the same mistake. 
1629289721
The Aaron
Roll20 Production Team
API Scripter
Hmm. It shouldn't require a token representing a character.  I'll have to look into this. 
1630001473

Edited 1630072035
For anyone using DungeonFog and their UniversalVTT .df2vtt format, the sanitizer works without issue.
1630004903
The Aaron
Roll20 Production Team
API Scripter
Woot!  That's great news, I didn't even realize they were using this format. 
1631314606

Edited 1631761707
Alex D. said: Hi @aaron,  first off, I love your scripts.  I installed this one and was able to successfully import all the dynamic lighting for a map in minutes. the instructions were spot on. But. now I tried a second map on a second page and it keeps complaining about missing or corrupt vtt data. I did everything the same... I even tried re-importing the vtt data that worked the first time and it still complains about bad data. Any Ideas? I already tried downgrading to 1.6 and deleted and reinstalled. I restarted the sandbox several times and reuploaded the image too.  I'm having this same issue. However, I do not have any other scripts installed and so I'm not sure what could be causing this. Another discrepancy is I am still able to recreate the same map I did the first time (73x25). The one that keeps getting the error is pretty large (75x57) - could that be an issue? Edit: Tried it again with a new, smaller map (25x38) and it worked! I'll keep that in mind as I continue to add on to my ridiculously large dungeon. Edit 2: Folks, make sure you hit the "Choose File" button when uploading your file to the sanitizer, lol.
1631318473
The Aaron
Roll20 Production Team
API Scripter
Interesting!  I wonder what the issue is.  If you can PM me the 73x25 one, I'll try to figure out what's going on.
1633744265

Edited 1633745755
Based on my simple testing so far with their pre-gen'd maps, I've confirmed Arkenforge's .uvtt format also works in the scrubber! But more testing is recommended. Gonna test to see if I can do something similar with animated maps too but that's doubtful. Upon further testing, got it working with animated too (by following regular process then Arkenforge's animated steps then making "image" invisible as you can't use GM Notes on animated maps). But I did notice it imports the lighting info wrong and gave me -4475 ft radius on the lights. Small price to pay for everything else setup.
1633759544
The Aaron
Roll20 Production Team
API Scripter
Hmm. That's not right. Can you PM me the JSON you used so I can track down the issue?
If this isn't the right place for me to post this, I apologize. But I figure that I'm not the only person using Dungeondraft, and one of the recent updates added the ability to place objects that block line of sight for dynamic lighting. Opaque objects in Dungeondraft don't work with the import sanitizer out of the box, which was disappointing. But I monkeyed with the output until I got it to work, and I'm posting it here because I don't know of anyplace that would be obviously better. When a .DD2VTT file generated by Dungeondraft is added to the sanitizer, it will include some JSON markup like this: {"format":0.3,"resolution":{"map_origin":{"x":0,"y":0},"map_size":{"x":40,"y":40},"pixels_per_grid":70},"line_of_sight":[[{"x":29.822109,"y":2.938543},{"x":29.243984,"y":3.2875}],[{"x":29.285625,"y":2.865625},{"x":29.884609,"y":3.308332}]], "objects_line_of_sight":[[{"x":11.625455,"y":10.461274},{"x":11.635423,"y":10.168058},{"x":11.636104,"y":10.160276},{"x":11.565085,"y":10.07564},{"x":11.479475,"y":10.06815},{"x":11.417505,"y":10.148993},{"x":11.417165,"y":10.152884},{"x":11.351352,"y":10.143206},{"x":11.347461,"y":10.142865},{"x":11.280827,"y":10.725211},{"x":11.280487,"y":10.729103},{"x":10.481196,"y":10.721912},{"x":10.480856,"y":10.725803},{"x":10.396121,"y":10.663494},{"x":10.372772,"y":10.661451},{"x":10.334346,"y":10.697301},{"x":10.334005,"y":10.701192},{"x":9.922686,"y":10.696576},{"x":9.922345,"y":10.700467},{"x":9.626113,"y":10.635339},{"x":9.594982,"y":10.632615},{"x":9.612396,"y":10.657665},{"x":9.611375,"y":10.669339},{"x":9.42814,"y":10.657229},{"x":9.4009,"y":10.654846},{"x":9.342335,"y":10.696776},{"x":9.338444,"y":10.696436},{"x":9.321956,"y":10.840077},{"x":9.318551,"y":10.878991},{"x":9.3867,"y":10.951613},{"x":9.386359,"y":10.955504},{"x":10.876807,"y":10.995715},{"x":10.877148,"y":10.991824},{"x":10.892519,"y":11.040223},{"x":10.892179,"y":11.044114},{"x":11.188265,"y":11.066097},{"x":11.258309,"y":11.072226},{"x":11.272078,"y":11.27341},{"x":11.26663,"y":11.335672},{"x":11.166483,"y":11.942533},{"x":11.165802,"y":11.950316},{"x":11.192993,"y":12.042883},{"x":11.192653,"y":12.046774},{"x":11.346947,"y":12.075958},{"x":11.346606,"y":12.079849},{"x":11.43139,"y":12.051976},{"x":11.439173,"y":12.052657},{"x":11.464076,"y":11.992097},{"x":11.467968,"y":11.992437},{"x":11.545346,"y":10.928727},{"x":11.546027,"y":10.920945},{"x":11.629346,"y":10.461615}]] The portion beginning "line_of_sight":[[ is where Dungeondraft puts the JSON for stuff drawn using the wall tool, and that stuff works fine. But later on, there is another piece of markup ]], "objects_line_of_sight":[[ Which is where the XY coordinates from the "line of sight" section end (that's the "]]" part), and a new section begins. That section  is where Dungeondraft puts the stuff generated for objects that are meant to be opaque to lighting/line of sight. The script does not recognize any of the stuff in that section. But you can easily fix that; just edit the portion that reads ]], "objects_line_of_sight":[[ so that it instead reads ], [ before you run !uvtt, and the importer will draw them in the Dynamic Lighting layer. This way, all the stuff that would have been in "objects_line_of_sight" is instead in "line_of_sight", which UVTT Importer will interpret properly.
1634510148

Edited 1634512259
I hate to bring up a question on a thread that is clearly very old. But I wanted to know if this was was for the current version of dynamic lighting or the legacy... I threw together just a super simple cave in order to try this tool, and it does not seem to be doing anything, and !uvtt --help Is not pulling anything up when I type it in chat. I made the files, uploaded the jpeg to my maps and backgrounds layer,and copied the dd2vtt file into my gm notes, turned on dynamic lighting, and then selected my map and ran the command. However, this doesn't seem to do anything! Any ideas as to what a rookie like me may have done wrong?
1634517683
The Aaron
Roll20 Production Team
API Scripter
What version do you have installed?  Check the API Console for some text that shows the version. 
1634517722
The Aaron
Roll20 Production Team
API Scripter
Edward R. said: If this isn't the right place for me to post this, I apologize. But I figure that I'm not the only person using Dungeondraft, and one of the recent updates added the ability to place objects that block line of sight for dynamic lighting. Opaque objects in Dungeondraft don't work with the import sanitizer out of the box, which was disappointing. But I monkeyed with the output until I got it to work, and I'm posting it here because I don't know of anyplace that would be obviously better. When a .DD2VTT file generated by Dungeondraft is added to the sanitizer, it will include some JSON markup like this: {"format":0.3,"resolution":{"map_origin":{"x":0,"y":0},"map_size":{"x":40,"y":40},"pixels_per_grid":70},"line_of_sight":[[{"x":29.822109,"y":2.938543},{"x":29.243984,"y":3.2875}],[{"x":29.285625,"y":2.865625},{"x":29.884609,"y":3.308332}]], "objects_line_of_sight":[[{"x":11.625455,"y":10.461274},{"x":11.635423,"y":10.168058},{"x":11.636104,"y":10.160276},{"x":11.565085,"y":10.07564},{"x":11.479475,"y":10.06815},{"x":11.417505,"y":10.148993},{"x":11.417165,"y":10.152884},{"x":11.351352,"y":10.143206},{"x":11.347461,"y":10.142865},{"x":11.280827,"y":10.725211},{"x":11.280487,"y":10.729103},{"x":10.481196,"y":10.721912},{"x":10.480856,"y":10.725803},{"x":10.396121,"y":10.663494},{"x":10.372772,"y":10.661451},{"x":10.334346,"y":10.697301},{"x":10.334005,"y":10.701192},{"x":9.922686,"y":10.696576},{"x":9.922345,"y":10.700467},{"x":9.626113,"y":10.635339},{"x":9.594982,"y":10.632615},{"x":9.612396,"y":10.657665},{"x":9.611375,"y":10.669339},{"x":9.42814,"y":10.657229},{"x":9.4009,"y":10.654846},{"x":9.342335,"y":10.696776},{"x":9.338444,"y":10.696436},{"x":9.321956,"y":10.840077},{"x":9.318551,"y":10.878991},{"x":9.3867,"y":10.951613},{"x":9.386359,"y":10.955504},{"x":10.876807,"y":10.995715},{"x":10.877148,"y":10.991824},{"x":10.892519,"y":11.040223},{"x":10.892179,"y":11.044114},{"x":11.188265,"y":11.066097},{"x":11.258309,"y":11.072226},{"x":11.272078,"y":11.27341},{"x":11.26663,"y":11.335672},{"x":11.166483,"y":11.942533},{"x":11.165802,"y":11.950316},{"x":11.192993,"y":12.042883},{"x":11.192653,"y":12.046774},{"x":11.346947,"y":12.075958},{"x":11.346606,"y":12.079849},{"x":11.43139,"y":12.051976},{"x":11.439173,"y":12.052657},{"x":11.464076,"y":11.992097},{"x":11.467968,"y":11.992437},{"x":11.545346,"y":10.928727},{"x":11.546027,"y":10.920945},{"x":11.629346,"y":10.461615}]] The portion beginning "line_of_sight":[[ is where Dungeondraft puts the JSON for stuff drawn using the wall tool, and that stuff works fine. But later on, there is another piece of markup ]], "objects_line_of_sight":[[ Which is where the XY coordinates from the "line of sight" section end (that's the "]]" part), and a new section begins. That section  is where Dungeondraft puts the stuff generated for objects that are meant to be opaque to lighting/line of sight. The script does not recognize any of the stuff in that section. But you can easily fix that; just edit the portion that reads ]], "objects_line_of_sight":[[ so that it instead reads ], [ before you run !uvtt, and the importer will draw them in the Dynamic Lighting layer. This way, all the stuff that would have been in "objects_line_of_sight" is instead in "line_of_sight", which UVTT Importer will interpret properly. Oh!  I had no idea they added this!  I'll get the script updated to support it, thanks for letting me know!
1634539548
The Aaron
Roll20 Production Team
API Scripter
Update v0.1.8 -- Added support for Opaque Objects, Window Portals, Colored Lights  (Thanks  Edward R. ) Many new configuration options in the help: !uvtt --help Create Open Portals is renamed to Open Portals Mode .  There are now 4 options rather than just on and off: Movement Blocking Window will draw a line that blocks movement but not sight. (Default) Movement Blocking Window with Glass creates the line as above, but also creates a glass window pane on the map layer. GM Layer Line is the old "On" setting, and just draws the portal on the GM Layer instead of the DL layer, ready to move back and forth to open and close it. None is the old "Off", and draws nothing at all. Window Color sets the color for the Window Pane on the map layer, and the color of open portal lines on the GM or DL layer. Window Width sets the width of the Window Pane on the map layer.  Open portal lines on the GM and DL layers get the Door Width . Object Color sets the color that Opaque Objects are drawn in on the DL layer. Object Width sets the width that Opaque Objects are drawn in on the DL layer. Object Transparent sets if Opaque Objects should just block movement and not sight. Note that you can now specify --no-objects to not use Opaque Objects at all: !uvtt --no-objects Light Color has been renamed to DL Layer Light Marker Color to better reflect what it is and remove confusion. Use Light Color toggles if you want to use the colors specified for lights in the import file.  DungeonDraw can export a map with the lighting color applied to the map, or with the map unlit.  Here's a comparison of the same map exported with and without lighting, and using Roll20 Light Colors and without: Unless you plan to move lights, or turn them on and off, you might chose to just export the color and not import the color, so that's why there's an option. One minor quality of life change, UniversalVTTImporter will now automatically clear previously created objects when you run it again.  That makes it easy to try different configurations and then reimport all your maps when you have the setting you like.  To be clear, running: !uvtt on a map you've already imported will now be the same as running this was: !uvtt --clear !uvtt The new code should show up in the 1-click on Tuesday, or you can get it now from my repo.
1634540209
The Aaron
Roll20 Production Team
API Scripter
Additionally, I've updated the Sanitizer website so that it will also show the image embedded in the .dd2vtt file you upload.  That lets you download the image for upload in the case that the .dd2vtt file is all you have or want to have.