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. [img]https://i.imgur.com/mXWYwUV.png[/img] [h1][b]Music Player[/b][/h1] [list] [*]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. [/list] [h1][b]Custom PDF[/b][/h1] [list] [*]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. [/list] [h1][b]Cloud Manager Folders[/b][/h1] [list] [*]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. [/list] [h1][b]Sound Improvements[/b][/h1] [list] [*]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. [/list] [h1][b]Alpha Transparency Support[/b][/h1] [list] [*]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. [/list] [h1][b]Magnify Revamp[/b][/h1] [list] [*]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. [/list] [h1][b]General Improvements[/b][/h1] [list] [*]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. [/list] [h1][b]Scripting Improvements[/b][/h1] [list] [*]New global class Vector: [/list] [code] 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 [/code] [list] [*]New global class Color: [/list] [code] 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) [/code] [list] [*]Added an overload to UI.setXml() and UI.setXmlTable() to take a CustomAssets as the last param. [*]Music Player exposed to Lua. [*]Added [b]logString[/b] function, which returns a string representation of a lua object (the same representation the [b]log[/b] function uses) [*]Fixed cleanup issue with Xml custom assets UI from lua for clients. [*]Fixed turns not network syncing for Lua. [/list] [h1][b]VR[/b][/h1] [list] [*]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/ [/list] [h1][b]Spectator Mode[/b][/h1] [list] [*]Spectator window may now display the view grey players have (for example, cards in your hand will be hidden). Enable with [b]+spectator_restrict_view[/b] [*]Spectator window now renders the grid. May be turned off with [b]-spectator_show_grid[/b] [/list] [h1][b]System Console[/b][/h1] [list] [*]Added documentation for system console to tabletop api website: https://api.tabletopsimulator.com/systemconsole/ [*]Inline variable evaluation changed to use [b]{[/b] and [b]}[/b] (instead of [b]<[/b] and [b]>[/b]). See above page for details. [*]You may now use [b]alias[/b] to run commands when a toggle variable's value is changed. [*][b]skip[/b] now allows for various comparisons, and fuzzy equality check. [*]Added [b]ui_anchor[/b], [b]ui_label[/b] and [b]ui_toggle[/b] commands (to accompany [b]ui_button[/b]), allowing you more options for easily running commands / changing setting during play. [/list] New commands: (for more info see above page, or use [b]help [/b]) [list] [*][b]append[/b] - Adds text, or the last entered command, to a text variable. [*][b]camera_reset_on_load[/b] - Whether the camera resets its position when you do a [b]Save & Play[/b] in Atom. [*][b]chat_input[/b] - Activates chat input box. [*][b]component_examine[/b] - Sets game component currently being examined. [*][b]component_move[/b], [b]component_rotate[/b], [b]component_position[/b], [b]component_rotation[/b] - Apply movements to components. [*][b]eval[/b] - Evaluates an expression and stores it in a variable. [*][b]examine_position[/b], [b]examine_rotation[/b] - Return information on the currently examined component. [*][b]hidden_zone_showing_opacity[/b], [b]hidden_zone_hiding_opacity[/b] - Set visual opacity of hidden zones. [*][b]lua[/b] - Execute a lua statement. [*][b]music_add[/b], [b]music_mute[/b], [b]music_next[/b], [b]music_pause[/b], [b]music_play[/b], [b]music_prev[/b], [b]music_repeat[/b], [b]music_shuffle[/b], [b]music_timecode[/b] - Commands to control new music player. [*][b]spectator_restrict_view[/b] - Whether the spectator window shows your view, or that of a grey player. [*][b]spectator_show_grid[/b] - Whether the grid is rendered in the spectator window. [*][b]team[/b] - Stores / sets team you are currently on. [*][b]ui_anchor[/b] - Sets position UI elements are made relative to (default is 0,0 - the center of the screen) [*][b]ui_label[/b] - Add static text UI element. [*][b]ui_toggle[/b] - Add checkbox UI element. [*][b]vector_x[/b], [b]vector_y[/b], [b]vector_z[/b] - Return an individual axis from a vector variable. [*][b]vr_move_with_inertia[/b] - Whether you have inertia in VR. [*][b]vr_move_friction[/b] - When you have inertia, how quickly you slow down. [*][b]vr_scale_rotate_rate[/b] - How much smoothing is applied during scaling/rotating. [/list] [h1][b]Fixes[/b][/h1] [list] [*]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. [/list]