Strap yourself in, this is a big one! --- OVERHAULS --- Overhauled pulses! This is on the scale of the particle rework from 1.2 to 1.3, so it's difficult to summarise the changes. Quick feature list: - Pulses can now use sprite sheets as stencils! These can be easily generated from GIFs, so, basically: GIF support is now a thing! - All animations are now controlled using 2-axis blends, and are properly organised - Pulses can move their Y-position over time; with careful tuning these can match notes travelling up or down to lock a pulse to a notes Overhauled default presets and particle templates! We now have 13 default presets + 1 exposed "default" plain preset for each of the graphics presets, and 14 particle templates. It is highly recommended to either fully reset Keysight using the "reset" command in Advanced System > enter console command, or reload default presets by clicking the desired graphics preset in Graphics Menu style has been updated! Sub-headings, buttons and text now are much more visually distinct, which should aid in legibility of larger menus with lots of sub-headings. Large menus have been split into further sub-tabs, such as in the case of Impact Lights which now have 4 sub-tabs to break up that giant wall of sliders, and these subtabs are kept at the top of the tab to reduce the amount of scrolling up and down switching between sections. Additionally, text and buttons are using much more robust inherited styling to achieve this, which allows for easy global tweaks to menu style down the line if need be, and easier tooltip-ing! Which, speaking of, every single item in the menu now has a tooltip explaining its function. In the case of sliders and graphs, hovering over the title for the UI element will give a general explanation for what that element controls Overhauled the way the menu switches between basic and advanced modes. The menu should now cleanly transition to the correct submenu in the other menu style, making it pretty seamless to play around in Basic mode, decide "I need to look at advanced options for a second", and click the button to quickly have a look, and then transition back without having to re-open any menus. The only menu that does not transition cleanly is Basic Colour, as this has no unambiguous equivalent in Advanced mode Overhauled menu layout and "expose" behaviour for particle systems! Particle system editing now has a hiercharchical tab view to avoid being yeeted into the void when you open a giant tab, scroll down, and then opening a smaller tab below it (closing the first one). Particle behaviour sub-tabs are roughly organised by "importance of influence", with more-important options towards the top left of the block of tabs. "Expose" flags are also present per-tab, and control the entire tab. This means a basic user might see more options than previously, but it is also much more consistent and universal in terms of which tabs are visible in what mode Overhauled particle randomization! This ties into the "expose" rework listed above, but the randomizer now randomizes each section of particle systems based on the "expose" flag for that section (if it choses to do randomize at all, based on the chance branch to randomize template particle systems). Previous behaviour simply randomized a handful of known-important values like path stretching and particle size, but notably did not touch things like particle shape as it was conceivable that particle shape is core to the template's function, and it should not be changed (as in the instance of the Steam template). Randomization operates within ranges of the original template value, and clamps to the graph min/max for each variable. This means that the randomizer will now more thoroughly and intelligently generate cool particle system modifications, and do so based off human-set value bounds so it doesn't go too crazy. If making your own particle templates, this means it is extra important to set good graph ranges even for things that are not used, along with deciding which sections should be exposed and therefore randomizable, and which ones should not Overhauled the graphical editor and slider UI modules! This is getting its own separate entry in the Overhauls section because holy heck it took a lot of painstaking work to update. In the graph editor: big bulky buttons have been replaced with simple icon buttons, the layout has been tightened and tidied, graph bounds editing now auto-greys-out when the buttons will not do anything, and "use flat value" no longer changes the graph values and just uses the graph 'max' effect value (so you can switch between flat/dynamic response much smoother). In the slider: changed appearance of icon buttons, and fixed the bounds to properly update when trying to map to a value that sits outside the default min/max range. Snapping has been reworked from percentage based to a set snap amount that gets larger as the range increases, and the bounds for sliders and graphs can be re-written with finer control by clicking on the display and typing a new desired value. Additionally, very large values with many zeroes switch to using K (and M), such as 10,000 > 10K (and text entry respects this, so you can type in 20k and it works) Overhauled impact lights! Candle flickering now uses 2-axis graphs for flicker speed and brightness deviation, as well as having a new property of "displacement by note activity"! This allows impact lights to subtly (or not so subtly) move around as they flicker, giving that classic candlelight dancing-shadows look. Vertical axis displacement is now also a 2-axis response with velocity, which allows for converting static on-piano impact lights to floating orbs that shoot up and down the backdrop in response to velocity! (Make sure to enable affect-backdrop for this, and you may need to tweak simulation values to get a good animation feel since these affect how impact lights react to note-offs) Overhauled note object shapes and scaling behaviour! Note objects are now much more consistent between shape versions, with each shape always being the same Z-height of 0.5cm and having identical border widths for narrow/wide borders. Black notes are also slightly wider across the board. On top of this, the way note objects scale to their minimum scale size and width scaling has changed significantly. Minimum scale is now relative to the size of two end caps, so 1.00 minimum size always gives a square/round note profile if released quickly. Cap size also scales with width, so the note object proportion is consistent across different sizes. Note scale can also be a dynamic response against note strength, bring on the chonky notes! You better be confident in your voicing, though Overhauled colour modes! Added two new modes: "notes-per-second" and "activity", allowed "random" mode on all objects (err, do be careful with that), and changed "ramping" to "response curve" and changing the range to be more consistent with other options. The menu is also rebuilt with our new modern tooltips, styling and UI elements for ease of understanding too - "Notes-per-second" colour mode generates a 0.0-1.0 factor using the given min/max range, applies the response curve bias, and then blends through the given colour slots similar to velocity mode. NPS colour works well with change-over-time enabled, and can be really nice for pieces with wild pacing fluctuations - "Activity" colour mode does almost the same thing, but adds up the activity across all notes rather than uses notes per second. This allows it to show when the same number of notes per second are getting louder, but tends to respond very heavily to sustain pedalling. Nice for pieces with a constant pacing but varying dynamics - As a reminder, now that it is not just locked to particles: "Random" colour mode picks a new random colour slot *every single frame*. This can be a flickery mess, OR it can be a cool candle-like flicker previously inaccessible to everything outside of impact lights. Use at your own risk, this could very easily triger seizures! Overhauled basic particle menu from 1.3 behaviour! Basic particle menu now has zero control over actual system parameters, but contains toggles for every single template. This allows multiple particle slots in basic mode, and also avoids displaying potentially overwhelming (and often useless) information about controlling just the first particle slot as was previously the case. Also contains a "clear" button, which should be used prior to editing any preset with non-template-named particle slots (although this would involve editing particles in the Advanced menu, and then switching back to Basic menu to edit further which is... weird? Nevertheless, it's there now) Overhauled the preset bar! And completely removed "Preset Management" in the process. Preset tabs are now arranged horizontally until wrapping vertically, so the scroll box is now vertically scrolling rather than horizontally. Clicking on a preset shows all preset actions previously tucked away in Preset Management as icons on the slot itself, and the preset can be renamed by just typing in over the top of the name while selected on that preset. Reordering can be done by the arrow buttons at the top of the preset tab. Also introduced a shiny new confirmation box for certain actions which can be re-used in other menus later if needed, complete with the first ever Keysight UI animation! Overhauled the Randomizer menu! This is now the same menu between both basic and advanced menu modes, and the underlying data architecture has been changed to have a hard-coded, graphics-preset-relevant "safe" randomizer to optionally switch to. Randomizer menu now has two primary modes: full and safe. "Full" is configurable and has all the usual craziness, "safe" will keep everything cohesive and a little less crazy at the cost of not seeing wild, cool stuff. This switch is also used by the ctrl+R hotkey and websocket trigger for randomization, so set it accordingly if these are things you use! Additionally, a refresh button has been added to each randomizer sub-category tab to allow re-rolling of this specific category. This should assist in refining a preset solely using the randomizer, without having to understand any other menu options! Overhauled particle vector field influences! First up, the way vector fields shift over time to give dynamic wiggles to particle paths is now straight-offset based rather than sin-based, meaning that wiggle variation should have less sharp "bumps". Second: there is a new option exposed in the vector options tab called "Vector style", with Default / Curl / Double currently available with the potential for more down the line - Default: standard high frequency perlin noise used since 1.3 - Curl: engine-baked-in simplex curl noise. This does not allow for X/Y influence control as the force is applied as a float rather than a vector (but global stretch still works) - Double: uses both of these at once for M-M-M-MEGA WIGGLES These changes mean that the exact nature of particle paths has changed quite drastically if you're comparing old versus new directly, but to the average end user this change should be somewhat invisible and simply allow for cooler particle templates down the line! Overhauled graphics options! Some options have been removed due to be completely unnecessary or straight up worse than default behaviour, and more familiar granular control has been exposed for shadows and anti-aliasing. T-AA has been removed (although I suppose you could force this via a System command if you really wanted it) as it is always a straight downgrade to FXAA for particle clarity. Sharpening has also been removed, it got added as a "hey, look what I can do" but err, it looks like garbage and nobody should use it. V-syncing, thread syncing and some other engine behaviour has also been improved and locked down and should give smoother capture in OBS Overhauled (*clears throat*) translucent material domain sort priorities. Layman's terms: the layering of rings and pulses! Before, this was left up to the engine, and this worked just fine under most normal circumstances, but completely fell apart and gave weird "slow Z-fighting" if you layered a ton of fully opaque semi-transparency-supporting objects like pulses. Now, the sorting priority is manually set based on the Z-height above backdrop of pulses and particles, along with the order that they were spawned. Sort order is descending and goes in order of pulses > particles, so higher pulse slots and particles render underneath lower pulse slots/particles, but *ascending* with time. This means at each height, each new object is guaranteed to render on top of the last. The only limitation is that the accuracy of Z-height is limited to 0.01 thanks to int16 sort priority storage space. This opens up really exciting preset opportunities relating to deliberately overlaying TONS of stuff and letting it all bleed together, as this no longer flickers like crazy! Err, reading that back to myself: just go try out the Candy preset! You'll see what I mean --- SMALL ADDITIONS --- Added brightness slider for white key material and backdrop self-lighting to the Basic Effects > Backdrop menu. These two sliders should vastly simplify the common desire to have an always-visible backdrop, or brighter white keys Added local cull horizontal and cull vertical rendering options to pulses and particles. This means that allowing or disabling pulses and particles clipping outside the active area is now controlled per pulse/particle, although both have both culling options enabled by default. Psst, some particle systems look great when falling below the keyboard dividing line, like "sandstorm"! Repurposed the Core > Viewport culling toggles for horizontal and vertical axes. These now exclusively act on the backdrop, and are found under Scene > Backdrop. Enabling "extend backdrop bounds horizontally/vertically" will turn the backdrop into more of a "canvas" for advanced, not-specifically-piano visualisations. (I mention the repurposing because if you had culling disabled prior to this update, it will essentially turn ON these new extend-bounds options) Added tooltip fade-in delay slider to System > Interface. This allows you to set a longer or shorter time period that you need to hover over something for it to show the tooltip Added secondary side display for tooltips that appears instantly on-hover, and controls to set opacity of this display Added support for transparent piano key materials. You probably still shouldn't use these, but it was simpler to allow them than to check and block transparent material pasting Added rename functionality to pulse and particle slot titles (just click on the text and edit it), and removed the rename field from the pulse picker Added "force release after set time" function to particles. This overrides their usual release-when-note-is-released behaviour, and causes them to release a set amount of time after they spawn. This can create "bursts" of particles with a short release time and a high spawn count. Note that dynamic velocity response is disabled for this mode Added time offset functionality to particle systems using force-release-after-set-time mode. This functions the same way as pulses, but is rather more niche in its utility Added debug functionality to arrow keys. Left arrow pauses and unpauses Keysight, up/down changes time-stepping, right arrow increments time by specific amount. This is for... no kind of planned functionality relating to fixed time stepping, no sir... ;) Added ability to have greater than 1.0 normal map strength on Advanced materials, and added ability to have negative normal map strengths. Large values increase the perceived geometry distortion, negative values "flip" the Z-direction of distortion Added texture panning over time to note objects, backdrop and overlay materials! This allows texture unwrapping to change over time, adding another layer of complexity to visuals if desired. Speed is measured in the same speed units as notes, or 1.0 = 10cm/s Added "flip mask" option to materials, and removed "- (inverted)" default masks for advanced materials with an alpha mask, or blended materials Added "geometry normal strength" slider to note object behaviour. This is a complex one to explain, perhaps, but: setting geometry normal strength to 0.00 causes all pixels from a note object to believe they are pointing "upwards", and then modified by the normal map from the material (if using one). Functionally, this allows you to control the amount of reflection warping given by the note geometry without actually changing the geometry itself, which is useful for making flat-looking notes with a specific outline shape without having that shape's reflection warping (so, round notes without round reflections) Added a metric to the information tab of the particle system menu to display the approximate GPU cost of the current system. This is calculated fairly lazily by taking the max time, size, spawn rate and lowest speed and multiplying them together, as the primary cost for high-intensity systems like Steam is the translucent shader render cost on all the overlaid particles. Higher = worse, and typically anything over 100.00 enters frame-drop territory on weaker systems. Be aware that particle systems have plenty of other costs associated with them, not just pixel translucency cost, such as: CPU cost to pass in dynamic variables to the particle system, GPU cost to simulate particles, and GPU memory cost to store particle data. So don't take this as the be-all and end-all of performance metrics for your particles! Added culling to midi events that violate basic midi rules. This is to account for midi files that give weird, illegal messages like midi channels of 226 (when it should be 0-15), or velocities of >127. Any incoming events with either channel outside range of 0-15 (or 1-16 when offset) / control ID outside of 0-127 / velocity outside of 0-127 will be immediately culled Added some additional websocket response data to the inbound socket. Just in case anyone other than me is listening for response messages over the inbound websocket: the response JSON now contains "display", which informs the server what the current preset or seed is (including edge cases like looping randomize and FMU) Added texture rotation function. This applies AFTER texture offsetting, and rotates around the 0,0 coordinate Added random rotation option for note objects Added random horizontal pan direction option for note objects Added 4 noise-based masks: Spots, Scorched, Fluid, Whorl Added "Wood" material Added "Streaks" material (inspired by textures breaking in an incredibly pretty way on Eagle's Mac!) Added allowed-hue-range preview bar to randomizer Colour sub-menu to better understand which colours are currently allowed by the randomizer Added "aliases" to some inputs such as turbo-note-testing to also work with Ctrl or Cmd Added glow strength slider to note object body, border and keypress controls in the basic menu. These will set the min emissive strength to half the given value, clamped to a minimum of 1.0 Added a "super randomize" branch to the particle randomizer, with a default chance of 5%. This overrides the "exposed" flags on a particle template and randomizes every category as if it were exposed, resulting in extremely weird particle systems. This is applied after "particles are enabled", and "templates are randomized", giving in-practice a chance of around 2% under default settings Added a chance branch to note object randomization to allow for dynamic note size. By default, full randomization has a 5% of triggering this, and it gives a 0.5 to 2.5 size with -1.0 curve to note objects (and forces them to be uniformly white key shaped) Added value +/- buttons to slider UI elements next to the text entry point. These increment by the base snapping amount multiplied by the number of times bigger (rounded down to nearest integer) the current graph range is versus default Added two refresh buttons to particle system tabs in Advanced menus. Large refresh button will randomize this particle system with standard exposed-flag-respecting randomizer settings. Small refresh button will do the same but forcing every module to be randomized independent of exposed flags. Should be cool for discovering new, weird particle systems without needing to randomize the entire preset, or digging into particle settings! --- CHANGES --- Moved menu theme buttons from Advanced System > Menu styling to just System > Interface. This means they're accessible in basic mode, and not in a menu nobody in their right mind ever needs to enter Changed tooltips to be left-aligned rather than centre-aligned, and added a thin border with the current selected button colour around the tooltip to make it more visible. Thanks to Kyrazell for the excellent suggestion! Changed "Menu styling" to "Advanced menu styling" in System (only visible in advanced mode) Changed the websocket query function to return the name of the current slot if the current preset was not generated using a random seed, and give a special message if automatic preset randomization is in effect Changed basic mode note object border "glowing" button to use a value of 3.0 to 7.0 rather than 1.0 to 2.0 Changed menu to only update its state when the menu is actually open, and otherwise just cache a pending menu update to be triggered when the menu is opened. This should drastically reduce the overhead for a rapid looping randomizer mode while the menu is closed Changed variable note speed to be a 2-axis graph. This does not auto-convert from old variable max speed + ramping, as I think only a single person has ever used this option, but a 2-axis response gives much better opportunity for cool things like max velocity notes suddenly being way faster Changed the default "custom angle" to be an offset, perspective angle. Hopefully this can show off the 3D-ness of Keysight to curious button-clickers! Changed keypress fade out animation curve to be a 2-axis graph. This gives a visual representation of how the keypress will fade without having to actually test it Changed tooltip default fade-in delay time to 0.75 seconds, and sped up the fade-in animation from 1.0 seconds to 0.5 seconds Changed note light brightness by velocity to be a 2-axis graph Changed the name text on pulse and particle system tabs to be an editable text box, to allow for easy and rapid re-naming without going into submenus Changed note light width slightly (wider for black keys, just a touch wider for white keys) and changed the way the lighting attentuation radius behaves. This should be indistinguishable from older note light behaviour under standard circumstances, but with excessively low concentration or high note height above backdrop, there may be discrepencies Changed note light concentration slider bounds to be 0.5 to 1.0, although these can be edited down. This is to push users away from using really low note light concentrations, as it has a performance impact and isn't visually consistent in 100% of circumstances Changed octave lines to always and only use backdrop lighting channel, instead of silently inheriting the overlay lighting channels Changed particle velocity randomness to use gaussian distribution rather than the default distribution. This fixes the issue of seeing the "range" of paths a particle could take with a high enough spawn rate, as gaussian distribution means that at a randomness of 1.0, ~65% of random values fall within 0.0 to 1.0, 95% of random values fall within -1.0 to 2.0, 99.7% of values fall within -2.0 to 3.0. This means that randomness is now "more random" for the same input value for initial velocity, but the random range is far more natural and you do not see a hard edge at the bounds of particle paths. In testing, old randomness values appear approx 2x more random, so these values have been automatically multiplied down as part of 1.4 preset importing Changed "Circle (outline)" pulse stencil to be half as thick Changed "Fade (with speck)" to have a significantly larger centre in proportion to the fade, allowing smaller particles that use this stencil. Particle sizes have been auto-adjusted to compensate by multiplying size by 0.33 Changed impact light fade-out behaviour when in non-sustained-brightness mode. Impact lights now fade out with the given fade-in time, removing the harsh cut while keeping it controllable without additional variables Changed minimum time dilation to 0.05, down from 0.1 Changed non-sustained note force behaviour to smoothly interpolate down to 0.0 force upon key release, rather than snapping to 0.0 (avoids instant responsiveness on particles, which looked a little odd) Changed damper block lighting channel from "piano" to "backdrop" (as it looks nicer if they pick up note lights. Impact lights are usually blocked by the keybed divider) Changed piano key texture unwrapping to use regular top-down mapping rather than custom UV mapping. When textured, the sides of notes might look a little strange, but this gives much greater flexibility in controlling the appearance of textured keys from a normal camera angle Changed the user-controllable defaults to save to Defaults.sav rather than as part of SystemStruct.sav. This was primarily to avoid struct infrastructure breakdown (hah.) when editing certain low-level structs, but it has the benefit of defaulting everyone's default preset to reflect new 1.4 values too! (As a reminder: this default preset is very important as it is the baseline preset randomized from when using the randomizer) Changed polygonal material's colour map to also be slightly polygonal Changed setup wizard wording, removed a lot of fluff and tried to make it as simple and fast as possible Changed texture mapping to always force a 50% horizontal offset internally. This means when images are used, they unwrap with the centre of the image in the centre of the Keysight scene, rather than their bottom left corner at the centre, simplifying using image textures Changed DPI scaling curve (that is, the way the menu scales up and down with rendering resolution) to be more aggressive at smaller resolutions to allow side tooltip display to still be visible, and uniform above 1080p such that 1440p or 4k rendering does not give you a tiny menu in the top left corner and a comically wide side tooltip window Changed damper visualization to not inherit piano length, allowing zero-length keys to still show dampers (which may be a common usecase straight from the setup wizard for users who just want the visuals with no piano) Changed vector field parameters in Sandstorm, String and Dry Ice to better utilize new features Changed graphics preset names to "Ultra / High / Low" to, err, not be quite so insulting to lower-end systems. Plus, this highlights the small quality drop from Ultra to High and the much larger drop from High to Low Changed some graph ranges in particle options to give easier and more useful snapping Changed vector field detail scale to also change vector field movement. Makes detail scale changes significantly more intuitive Changed stats menu to have horizontal tabs, with identical layouts for current/all sessions to easily switch between tabs to compare distributions Changed backdrop horizontal canvas mode to hide the piano frame sides Changed Advanced pulse menu and particle menu to use 2-wide stacking for slot tabs. Having more than 2 pulse slots no longer results in a sideways scroll bar (which captures your mouse cursor while scrolling in an annoying fashion) Changed the way midi devices are detected, bound and error-out. Due to plugin limitations for binding to live midi devices, once a live midi device is bound it still cannot be unbound and rebound (Keysight will need to be restarted for this). However, the midi device menu now reflects this lack of bindability by removing the option, and generally is a little more robust Changed "always show mouse cursor" default to true under System > Interface. This may not update on existing save files, but a fresh Keysight will now not capture your cursor by default Changed overdriven randomization to use the FMU randomizer struct rather than internal multiplication of the normal randomizer struct. Not sure what this means? Ssshhh, it's a secret. If you know, you know Changed console command field to wipe text after executing a command Deprecated "remember menu state after re-opening menu" under System > Interface, this is now always true Deprecated "close any open sub-menus opening opening a sub-menu tab" under System > Interface, this is now always true Deprecated "pulse is expanding" randomizer branch, pulses will always expand but sometimes have a little bit of contraction at the end Removed debug pitch bend editing using scroll wheel Removed message telling you to press enter if typing into the console command field, and then moving away or closing the menu Removed the "view full documentation in browser" button from the Changelog menu. This was not only wildly outdated, but also tooltips on all buttons within Keysight makes digging through a giant document for information redundant Removed "key lighting" option. It is far better to use self-emissive materials for keys than to have a directional light on the "piano" light channel blasting at them, and this can now be done via the Basic menu Removed "cull horizontal" and "cull vertical" global options from Core > Viewport. These are now activated per-particle and per-pulse, for greater flexibility Removed ability to have CPU-simulated particles. There was never any reason to do this other than if, somehow, GPU particles were not supported on some specific hardware. After gathering some more data in that respect, it seems like not a single computer running Keysight has failed to run GPU particles Removed some backend internal switching between no-note-wind and note-wind particle system versions based on parameters. The original idea was to have optimised systems based on what is needed, but in practice, the switching is more costly than simply running the un-needed particle modules with 0.00 values Optimised some internal particle system code. Probably to no perceivable effect, but still! Optimised texture displacement with notes. As a side effect, global texture displacement with dynamic note speed now makes all notes have the correct texture displacement speed over time (they just all spawn with the same starting offset). Additionally, this fixes a bizarre edge case relating to floating point precision leading to texture displacement speed "desyncing" randomly from notes when Keysight has been open for a long time and/or has a very low time dilation Optimised material and colour assignment across the program. CPU usage should now be significantly lower unless using dynamic, over-time colours Optimised piano key simulation and animation. There is now no CPU cost associated with piano keys not actually doing anything Optimised sustain pedal event handling --- BUG FIXES --- Fixed notes that are forcibly released by another note spawning from "jumping" one frame's worth of displacement. Rapid notes now look significantly smoother at their origin point as a result Fixed the no-texture-displacement mode in note object materials. Using non-random mapping and no texture displacement will now properly make notes "reveal" an underlying image Fixed issue where changing basic mode colour options could set note border colour away from black, if border material is set to blank Fixed particles and pulses velocity-based activation not functioning Fixed overlapping pulses and particle slots with translucent material mode from Z-fighting Fixed new slider UI element doing silly things when being updated to a value greater than the default slider max, or less than the default slider min Fixed "note light change brightness over time" not working at all in top-down mode. Now, note lights will fade out with note activity once the note reaches it's target location. If you see any bugs with this, let me know, since I get the feeling it's gonna be buggy under some specific circumstances but I couldn't find anything on my end Fixed toggling frame lighting channels causing white piano plane to appear underneath the piano keys and not go away until a full preset switch is called (SUPER important bug to fix. I expect my Nobel prize nomination in the coming weeks) Fixed colour hex code display occasionally showing silly things like "#000" instead of the intended "#0F0F0F" when dragging sliders Fixed note lights having a random black or white key driven width if note objects were disabled Fixed particle systems not having a new random position within their vector field on repeat note presses, leading to identical particle pathing Fixed repeat notes causing first impact light to one-frame-flash to its target brightness before being destroyed by the second impact light (highly visible on slow-build impact light setups) Fixed randomizer not altering default emissive min/max values when randomizing to a transparent material Fixed normal maps being ever so slightly inaccurate to their intended effect Fixed note objects with >1 scale from Z-fighting with each other (achieved via a small Z-height offset based on note position. Higher notes now are "on top" of lower notes) Fixed note lights having a variable brightness when note object scale is changed, and made note light widths exactly the same as note objects Fixed having large numbers of preset slots potentially tanking CPU performance on weaker systems (for no reason) Fixed some edge case websocket messages having invalid JSON styling (forgot to escape some characters and crashed my server with it. Whoops! Sorry Adam) Fixed transparent materials being able to receive <1.00 emissive strength values. Now, transparent materials always are at least 1.00 brightness (as they're black with no emissiveness, and that reduces randomizer output variety as it would commonly randomize to 0.00 emissive strength) Fixed texture rotation breaking normal map direction. A rotation of 180 degrees no longer pushes the normal map inside out Fixed resolution dropdown showing the last applied resolution upon a resolution being applied, and then the apply button applying this previous resolution if clicked again (RIP resolution bug. You lasted more than a full year, I think...) Fixed reset-to-custom-camera-angle not updating key length display in Core > Visual layout Fixed refreshing textures on pulse picker clearing the selected stencil Fixed refreshing available particle templates showing removed templates with broken borders if the refresh was to remove templates rather than add them Fixed rapid repeat notes that force-release each other from having one frame of overlap at the boundary. This introduces one frame of unintentional gap to rapid notes spawned with Q (debug note input), but er... I really don't know why, and it works for the main Keysight usecase so I've given up worrying about this Fixed local texture displacement mode, this now unwraps the texture from the same vertical starting position relative to the note as was originally intended (to give guaranteed texture unwrap start points for each note, if you want the top of each note to look a specific way every time) Fixed first change not contributing to the undo queue, resulting in "nothing more to undo" error if trying to undo the first change you have made Fixed panic button not clearing soft pedal in top-down mode Fixed panic button not resetting damper displacement Fixed 0.00s soft pedal bloom/exposure blending time breaking the effect entirely. Don't divide by 0, kids! Prospective fix for certain timings of note-on/note-off events causing some effects to become "stuck on" when they shouldn't be