October 30, 2019, 7:13 am

Hey everyone, we got another great update for you today! We have added 2 very long requested features a Music Player and PDF support!

There are also a ton of great additions and improvements listed below in the patch notes.

Music Player
  • The music player let's you play audio files (.mp3, .wav, .ogg, ogv) which are synced for all players.
  • Great for room music or so your DnD campaign has the right mood!
  • Supports playlists with ordering, shuffling, and looping.
Custom PDF
  • New object Custom PDF, that allows you import a PDF onto a tile.
  • This converts the PDF into a series of images, to make it easy to import your rule books!
  • Supports multiple pages: swap between them with the contextual menu, next/previous state hotkeys, or the buttons on the left and right side.
  • Can popout the PDF to the screen by hitting the hidden UI button on the top left of the PDF object.
  • You can joint this to any objects to add any visual flair you would like to match the game.
Cloud Manager Folders
  • Cloud manager now supports folders just like Saved Games/Objects.
  • When you import all loaded assets into cloud it puts them in a folder defaulting to the Game name.
  • Can now name files that are uploaded to the Cloud instead of just using the file name on disk.
Sound Improvements
  • Custom Objects that are set to dice or coin will now get that correct sounds for their selected material type.
  • Improved sounds for objects interacting with locked objects.
  • Added glass material type for Custom AssetBundle and Custom Model.
Alpha Transparency Support
  • Added alpha support to the color picker.
  • Can now draw with semi tranparency.
  • Can color tint objects to have alpha transparency, which goes nicely with the new glass material type.
  • Objects with alpha transparency will not cast shadows.
Magnify Revamp
  • Magnify (hotkey m) overhauled to be round.
  • Scroll up or down to control the zoom level of the magnify.
  • Fixed visual issues with previous magnify.
General Improvements
  • Added loading percent next to the player names on the top right.
  • For the top bar in-game the Scripting, Workshop Upload, and Cloud Manager menus have been moved under "Modding".
  • Improved auto-raise to work better with overhangs.
  • Added a workshop indicator next to the chat window that you can hover over and get info about how far along the workshop subscription check is at.
  • Moved physics mode (semi-lock, locked, etc) from Configuration to Server Options.
  • Greatly improved compatibility with old AssetBundles shaders. This will fix a lot of broken DLCs.
  • Improved Fog of War performance.
  • File Browser now remembers the last opened path.
  • Updated Voice Chat plugin.
  • Voice chat is now using a higher quality setting.
  • Added hidden zone opacity sliders to Misc settings.
Scripting Improvements
  • New global class Vector:
Constructors:

Vector(num, num, num) --> return a vector with specified (x, y, z) components
Vector(table) --> return a vector with x/y/z or 1/2/3 conponents from source table (x/y/z first)
Vector.new(...) --> same as Vector(...)

Vector.max(vec1, vec2) --> return a vector with max components between vec1 and vec2
Vector.min(vec1, vec2) --> return a vector with min components between vec1 and vec2
Vector.between(vec1, vec2) --> return a vector pointing from vec1 to vec2
vec:copy() --> copy self into a new vector and retur it

Component access:
vec.x, vec.y, vec.z --> read/write component
v[1], v[2], v[3] --> read/write component
vec:get() => num, num, num --> returns x, y, z components of self

Methods modifying self and returning self:
vec:setAt(key, num) --> same as "vec[key] = num"
vec:set(num, num, num) --> set x, y, z components to passed values
vec:add(otherVec) --> adds components of otherVec to self
vec:sub(otherVec) --> subtracts components of otherVec from self
vec:scale(otherVec) --> multiplies self components by corresponding compnents from otherVec
vec:scale(num) --> multiplies self components by a numeric factor
vec:clamp(num) --> if self magnitude is higher than provided limit, scale self down to match it
vec:normalize() --> scale self to magnitude of 1
vec:project(otherVec) --> make self into projection on another vector
vec:reflect(otherVec) --> reflect self over a plane defined through a normal vector arg
vec:inverse() --> multiply self components by -1
vec:moveTowards(otherVec, num) --> move self towards another vector, but only up to a provided distance limit
vec:rotateTowards(otherVec, num) --> rotate self towards another vector, but only up to a provided angle limit
vec:projectOnPlane(otherVec) --> project self on a plane defined through a normal vector arg

Methods not modifying self:
vec:dot(otherVec) --> return a dot product of self with otherVec
vec:magnitude() --> return self magnitude (length)
vec:sqrMagnitude() --> return self magnitude (length) squared
vec:distance(otherVec) --> returns distance between self and otherVec
vec:sqrDistance(otherVec) --> returns squared distance between self and otherVec
vec:equals(otherVec, num) --> returns true if otherVec same as self (optional numeric tolerance param), false otherwise
vec:string(str) --> return string describing self, optional string prefix
vec:angle(otherVec) --> return an angle between self and otherVec, in degrees [0, 180]
vec:cross(otherVec) --> return a cross-product vector of self and otherVec
vec:lerp(otherVec, num) --> return a vector some part of the way between self and otherVec, numeric arg [0, 1] is the fraction
vec:normalized() --> return a new vector that is normalized (length 1) version of self
vec:orthoNormalize() --> return three normalized vectors perpendicular to each other, first one being in the same dir as self
vec:orthoNormalize(otherVec) --> same as vec:orthoNormalize(), but second vector is guranteed to be on a self-otherVec plane

Operators:
vecOne + vecTwo --> return a new vector with added components of vecOne and vecTwo
vecOne - vecTwo --> return a new vector with subtracted components of vecTwo from vecOne
vecOne * vecTwo --> return a new vector with multiplied components of vecOne and vecTwo, NOT a dot product (!)
vec * number --> return a new vector with all components from vec scaled by a numeric factor
number * vec --> same as "vec * number"
vecOne == vecTwo --> return true if both vectors identical or within a small margin of each other, false otherwise
tostring(vec) --> return a string description of a vector
  • New global class Color:
Constructors:
Color(num, num, num) --> return a color with specified (r, g, b) components
Color(num, num, num, num) --> return a color with specified (r, g, b, a) components
Color(table) --> return a color with r/g/b/a or 1/2/3/4 components from source table (letter keys prioritized)
Color.new(...) --> same as Color(...)

Color.fromString(colorStr) --> return a color from a color string ('Red', 'Green' etc), capitalization ignored
Color.fromHex(hexStr) --> return a color from a hex representation string (e.g. '#ff112233'), hash sign and alpha are optional
col:copy() --> copy self into a new color and return it

Color.Purple [etc] --> shorthand for Color.fromString('Purple'), works for all player and added colors, capitalization ignored

Component access:
col.r, col.g, col.b, col.a --> read/write component
col[1], col[2], col[3], col[4] --> read/write component
col:get() => num, num, num, num --> returns r, g, b, a components of self

col:toHex(includeAlpha) --> returns a hex string for self, boolean parameter
col:toString(num) --> returns a color string if matching this instance, nil otherwise, optional numeric tolerance param

Methods modifying self and returning self:
col:setAt(key, num) --> same as "col[key] = num"
col:set(num, num, num, num) --> set r, g, b, a components to passed values

Methods not modifying self:
col:equals(otherCol, num) --> returns true if otherCol same as self, false otherwise, optional numeric tolerance param
col:lerp(otherCol, num) --> return a color some part of the way between self and otherCol, numeric arg [0, 1] is the fraction

Operators:
colOne == colTwo --> return true if both colors identical or within a small margin of each other, false otherwise
tostring(col) --> return a string description of a color

Other:
Color.list --> table of all color strings
Color.Add(name, yourColor) --> add your own color definition to the class (string name, Color instance yourColor)
  • Added an overload to UI.setXml() and UI.setXmlTable() to take a CustomAssets as the last param.
  • Music Player exposed to Lua.
  • Added logString function, which returns a string representation of a lua object (the same representation the log function uses)
  • Fixed cleanup issue with Xml custom assets UI from lua for clients.
  • Fixed turns not network syncing for Lua.
VR
  • Improved movement - added movement inertia. Can be calibrated or disabled in VR settings.
  • Grid overlay now renders in VR.
  • Fog of War now renders in VR.
  • Added VR documentation to api website: https://api.tabletopsimulator.com/vr/
Spectator Mode
  • Spectator window may now display the view grey players have (for example, cards in your hand will be hidden). Enable with +spectator_restrict_view
  • Spectator window now renders the grid. May be turned off with -spectator_show_grid
System Console
  • Added documentation for system console to tabletop api website: https://api.tabletopsimulator.com/systemconsole/
  • Inline variable evaluation changed to use { and } (instead of < and >). See above page for details.
  • You may now use alias to run commands when a toggle variable's value is changed.
  • skip now allows for various comparisons, and fuzzy equality check.
  • Added ui_anchor, ui_label and ui_toggle commands (to accompany ui_button), allowing you more options for easily running commands / changing setting during play.
New commands: (for more info see above page, or use help )
  • append - Adds text, or the last entered command, to a text variable.
  • camera_reset_on_load - Whether the camera resets its position when you do a Save & Play in Atom.
  • chat_input - Activates chat input box.
  • component_examine - Sets game component currently being examined.
  • component_move, component_rotate, component_position, component_rotation - Apply movements to components.
  • eval - Evaluates an expression and stores it in a variable.
  • examine_position, examine_rotation - Return information on the currently examined component.
  • hidden_zone_showing_opacity, hidden_zone_hiding_opacity - Set visual opacity of hidden zones.
  • lua - Execute a lua statement.
  • music_add, music_mute, music_next, music_pause, music_play, music_prev, music_repeat, music_shuffle, music_timecode - Commands to control new music player.
  • spectator_restrict_view - Whether the spectator window shows your view, or that of a grey player.
  • spectator_show_grid - Whether the grid is rendered in the spectator window.
  • team - Stores / sets team you are currently on.
  • ui_anchor - Sets position UI elements are made relative to (default is 0,0 - the center of the screen)
  • ui_label - Add static text UI element.
  • ui_toggle - Add checkbox UI element.
  • vector_x, vector_y, vector_z - Return an individual axis from a vector variable.
  • vr_move_with_inertia - Whether you have inertia in VR.
  • vr_move_friction - When you have inertia, how quickly you slow down.
  • vr_scale_rotate_rate - How much smoothing is applied during scaling/rotating.
Fixes
  • Fixed scroll wheel being inverted for Linux.
  • Fixed Components menu chess Wood White King being missing.
  • Fixed search and expand for Games menu.
  • Fixed misc issues with spectator camera.