A quick note from the team: We know it's been a long time since the last big update. Behind the scenes we've been doing a lot of groundwork on the engine and tools, and this patch is the first step to a renewed focus on regular updates and improvements to TTS. Thank you for your patience and for sticking with us ❤️
This is a huge engine and platform update, so we're rolling it out as a public beta first to shake out any remaining issues before it goes live for everyone.
Open your Steam Library.
Right-click Tabletop Simulator → Properties...
Go to the Betas tab.
Select the public beta branch for the Unity 6 update from the dropdown.
Close the window and let Steam download the update.
You can switch back to the live version at any time by setting the beta dropdown back to "None".
Please report bugs and suggestions on our Nolt board 👉 https://tabletopsimulator.nolt.io/
Include your OS, GPU, and logs (see Troubleshooting & Logs below) when reporting issues. It helps a lot.
Please use the "Public Beta" tag for feedback to do with this patch.
Windows: 64-bit Windows 10 21H1+ (Windows 11 supported) macOS: 11 Big Sur+ Linux: Ubuntu 22.04/24.04 (64-bit)
Engine upgrade to Unity 6 LTS: smoother performance, better stability, and faster loading in many cases.
Native Apple Silicon support on macOS with a universal app that runs on both Apple Silicon and Intel, using Metal by default on Apple Silicon.
New Vulkan graphics API option on Windows & Linux (experimental) for potentially better performance in heavy scenes.
New minimum system requirements:
Windows: 64-bit Windows 10 21H1+ (Windows 11 supported)
macOS: 11 Big Sur+
Linux: Ubuntu 22.04/24.04 (64-bit)
Win 32-bit builds are no longer supported.
Game & plugins updated to latest versions and now code-signed for fewer antivirus/security issues.
Big quality-of-life upgrades: camera movement, keybind behavior, music player overhaul, notepad improvements, grid tools, erase-all controls, Cloud Manager upgrades, new console options.
New Lua tools for drafting, hand selection, hand "stash" areas, rewind control, and more scripting power.
Gameplay, rules, and your saves are unchanged. This is primarily an engine and quality-of-life update.
Updated TTS to Unity 6 LTS.
Updated all plugins to their latest compatible versions.
The game executable is now code signed, improving trust with Windows and reducing false positives with antivirus.
Windows
64-bit only.
Minimum: Windows 10 version 21H1 (build 19043) or newer.
Windows 11 fully supported.
macOS
Minimum: macOS 11 Big Sur or newer.
Now ships as a universal app that runs on both Intel and Apple Silicon (M-series).
On Apple Silicon, TTS now runs natively (no Rosetta required).
Linux
Supported: Ubuntu 22.04 / 24.04, 64-bit.
Wayland and X11 supported (behavior may vary by distro/driver).
If you're on an older OS than the above, TTS may not launch after this update. Please update your system.
macOS (Apple Silicon):
Metal is now the default graphics API when running on Apple Silicon.
If you're not on Apple Silicon, the game uses OpenGLCore by default.
Windows & Linux:
Added Vulkan as a new experimental graphics API.
In very demanding scenes, Vulkan can offer better performance on supported hardware.
Because Vulkan is still experimental, if you hit visual glitches or stability problems, switch back to the default renderer.
Includes the latest Unity 6 security fixes, addressing known file-loading vulnerabilities in older engine versions.
Combined with code signing, this should reduce security prompts and exploit risk.
Greatly increased snappiness of WASD camera movement with less "floaty" gravity.
Keybinds now use physical key location instead of character, so bindings line up across different keyboard layouts.
Voice chat improvements:
Disabling voice chat in the configuration menu properly stops all voice chat processes.
This can fix audio issues with some Bluetooth headsets.
If you are the host and disable voice chat, it disables voice chat for all players.
Added an error message when trying to use voice chat when it isn't connected.
UI theme can now automatically follow your system theme if none is manually selected.
Greatly optimized network serialization on CPU via more efficient bitpacking.
Image loading improvements:
Loading new (uncached) images is now more performant.
Improved image quality in many cases.
Reduced likelihood of crashes when large or many new images are being loaded.
In the current public beta, post-processing is not active in VR. This means effects like LUT-based color grading and other post-processing visuals do not work in VR yet. We're planning to restore this in a future update.
Added search filter for playlists. (Nolt #2143)
Added Clear Playlist button.
Added Export Playlist and Import Playlist:
Save your current playlist to a file.
Add a playlist file into your current playlist.
Added Upload Music Folder:
TTS will now suggest a name for a song when you provide a URL or file.
Fix: Music player no longer breaks when loading a new mod. (Nolt #2038)
Fix: Music events no longer break when a song ends with no playlist active.
Fix: Music player no longer resets when loading a save file with no music saved on it.
On-screen notes region is now resizable.
New notepad settings for:
Font
Font size
Text justification
New console commands:
ui_notepad_edit
ui_notepad_left_align
ui_notepad_locked
ui_notepad_fixed_width_font
ui_notepad_font_size
ui_notepad_size
ui_notepad_text
While Grid settings are open, the grid now renders on top of everything, making adjustments easier.
ui_grid_highlight_when_editting (console / Misc setting).New anchor & gizmo mode:
Click the Gizmo button in the Grid window.
Select a component to center the grid on it.
Ctrl+click a second component to size the grid appropriately (using your snap settings). (Nolt #1871)
Applies to drawn lines, text, and decals.
Non-promoted players:
Promoted players:
Can erase everything.
Can erase just their own.
Can erase all content from a specific player.
Cloud folder dropdown now has a "Select Folder" button that opens the Cloud Manager folder browser. (Nolt #711)
Starred folders:
Folders can now be Starred (button next to folder name).
Starred folders show first in the folder browser dropdown. (Nolt #711)
Cloud search now restricts results to the current folder. (Nolt #1839)
Fix: Resolved several file browser issues and cleaned up its underlying code to improve stability.
Custom Figurine:
Added toggle to use a minimal collider on the card part. (Nolt #1929)
Added option to mirror the back texture. (Nolt #2107)
Added Reset Scale to an object's scale context menu. (Nolt #2078)
Hotseat player names are now remembered between sessions. (Nolt #2070)
Added vr_floor command / VR setting:
fog / "Floor Of Mist". (Nolt #2173)Server browser improvements:
Player names now show in the server browser.
Your name is hidden if you are offline, invisible, or you untick the "Show Name In Server Browser" option.
(The previously mentioned standalone external server browser tool has been removed and is no longer part of this update.)
New/updated commands:
component_hotkey_state_change
When enabled, press number keys while hovering an object to change its State.
Appears in Misc Settings.
ui_notebook
text_tool_default_font_size
autorun_lua
camera_reset_on_color_change
show_name_in_server_browser
Fixes:
Fixed help command not working on commands that have no arguments.
Removed old console commands related to global chat. (Nolt #2117)
You can now obtain the "Be Social" achievement using in-game chat. (Nolt #1895)
Fixed game crashing when trying to load a CMYK JPG.
Fixed line tool not converting to cm in component mode. (Nolt #1934)
Fixed "Showing Hand" button displaying incorrect color after seat swap.
Fixed on-screen hand blocking in-game UI. (Nolt #1757)
Fixed hotseat turn not being set to correct player on load. (Nolt #1960)
Fixed hotseat players being unable to drop cards in searched deck. (Nolt #1959)
Fixed hotseat turn incorrectly resetting when loading a Classic game.
When starting a hotseat game, the game now only picks larger tables, so all player colors are immediately selectable.
Fixed context menu not clamping to screen. (Nolt #1966)
Fixed context menu appearing in the wrong position when right-clicking a card in hand. (Nolt #2051)
Fixed unintuitive Text Tool placement behavior.
Fixed appearance of custom card aspect ratios when searching containers. (Nolt #2021)
Fixed cards merging incorrectly with a deck when the deck is on a snap point. (Nolt #2063)
Fixed left edge of search dialog not having a collider. (Nolt #2077)
Fixed Japanese language name in language select. (Nolt #2116)
Fixed shake detector triggering when the user spams Tap.
Fixed Random Domino/Card/Mahjong Tile not generating every possible object. (Nolt #2160, #2154)
Fixed rewind/forward (rwd/fwd) not working correctly. (Nolt #2161)
Fixed game breaking on first launch but working on subsequent launches.
Fixed cards getting cut off onscreen when scaling very large hands.
Fixed deleting a folder in Cloud Manager not deleting all contained files.
Fixed issues when uploading PDF files via "Upload All" in the Cloud Manager.
Fixed a bug where objects with multiple assets (primary/secondary AssetBundles) could think they finished loading too early, breaking on-screen hands, highlighting, and Lua load completion.
Fixed dice behavior when picking up and dropping instantly, so dice now roll correctly in that scenario.
Fixed VR floor setting being inverted for the vr_floor option.
New Lua functions and features for creators:
tryObjectStateChange(object, new_state_index, player_label) and object.tryStateChange(new_state_index, player_label). (Nolt #1822)These are called whenever a user uses the state change action on an object --- even if the object doesn't actually have extra states. That means:
You can hook into the "state change" action to drive similar custom behavior in your own scripts.
You should not use this as a generic "do anything" trigger; keep it semantically tied to state-change-like behavior so your mods remain intuitive.
**Wait.collect**Wait.collect(table expected_ids, on_finished, on_add = nil, on_error = nil) -> {table expected, table results, add(id, ...), reset()}.Wait.collect takes a list of expected ids and returns a collect_table:
When the task for a given id is complete, call: collect_table:add(id, ...).
The first time this happens for a given id:
collect_table.results[id] is set to the ... you passed in.
If you provided on_add to Wait.collect, it is called as: on_add(id, ...).
Error handling:
If you call add more than once for the same id and you provided on_error, it is called as: on_error(Wait.COLLECT_DUPLICATE, id, ...).
If you call add with an id that was not expected and you provided on_error, it is called as: on_error(Wait.COLLECT_UNKNOWN, id, ...).
When all expected ids have been added:
on_finished(results) is called with the final results table.You can call:
collect_table:reset() to zero out call counts and clear results so you can reuse the same collector.Rewind states are stored periodically. If a store happens in the middle of a complex scripted change, you can end up with bad intermediate states. These helpers let you control when rewinds are saved. (Nolt #617)
storeRewindState(closure andThen, block_further_stores)
Attempts to store a rewind state if there are unsaved changes, then calls: andThen(success, didSave).
success:
true → the call completed successfully.
false → a rewind state could not be stored. You should always check this before continuing.
didSave:
true → a new rewind state was actually written.
false → call succeeded but there was nothing new to save.
If block_further_stores is true and success is true, then no additional rewind states will be recorded until:
You call storeRewindState again, or
You call allowRewindStore(), or
60 seconds have passed.
If success == false, the safest simple strategy is to retry storeRewindState before proceeding with the critical part of your script.
allowRewindStore()
Clears the block on storing rewind states.
You should call this any time you previously used storeRewindState with block_further_stores = true, once your "don't interrupt me" work has finished.
Each player's primary hand zone now has a "stash":
player.getHandStash() → returns the stash object if it exists.
player.drawHandStash() → draws all cards from stash into hand.
player.setHandStashLocation(v3 position, int rotation) → set stash position & rotation.
card.moveToHandStash() → moves a card in hand into its stash.
Use cases: drafting mechanics, temporary hidden piles, etc.
Automate drafting & hand selection:
chooseInHand(label, minCount, maxCount, prompt, players) -> affectedPlayers
chooseInHandOrCancel(label, minCount, maxCount, prompt, players) -> affectedPlayers
clearChooseInHand(players) -> affectedPlayers
currentChooseInHand(player) -> label
onPlayerHandChoice(player_color, label, objects) → Callback triggered when a player confirms their selection.
Fixed JSON.encode not working correctly with Unicode. (Nolt #1263)
If you hit problems, attaching your Player.log helps us a lot:
Windows: C:\Users\<you>\AppData\LocalLow\Berserk Games\Tabletop Simulator\Player.log
macOS: ~/Library/Logs/Berserk Games/Tabletop Simulator/Player.log
Linux: ~/.config/unity3d/Berserk Games/Tabletop Simulator/Player.log
Enable logging with /log in chat or the -log launch option.
Your Mods and other user data live here (good for backups or clean caches):
Windows: %USERPROFILE%\Documents\My Games\Tabletop Simulator\Mods
macOS: ~/Library/Tabletop Simulator/
Linux: ~/.local/share/Tabletop Simulator/
Engine upgrades are big and tie in to every platform and a ton of unique hardware configurations. If you run into issues, please include with your report:
OS version
GPU + driver version
Player.log
Workshop link (if it's mod-related)
And again, thank you for your patience during the long gap of silence. This engine work sets us up for faster, more frequent updates going forward --- and your feedback in the public beta will help us get there.