It was inspired by my frustrations with Studio’s built-in diffing feature being slow and limited , and the tedious external workflow I needed to use whenever I wanted to compare arbitrary scripts My coding life is much easier now that I can use this plugin
Features
Compare arbitrary scripts against each other
View the diffs of any uncommitted drafts (when Drafts Mode is enabled in Game Settings)
Configurable UI scale, code size, and code tab width
Switch between split and combined layouts
Colored preview in the scroll bar
Option to show whitespace (spaces and tabs), and whitespace will also be shown in the hovered line
Filters to ignore noisy changes such as whitespace, indentation, and tabs vs spaces
Basic diff stats such as total added, deleted, and net LOC
Mouse pan scrolling
Copy selected region of text
Open selected region in the original script
Designed to be used efficiently with hotkeys
Light and dark theme
Tree Diff to quickly compare different libraries and instances that contain many scripts, such as the PlayerModule
(Coming Soon) Import/export diffs in text or instance formats
Known Issues
Performing a diff using a hotkey will not bring the Diffy widget to the foreground if it is docked and is not the currently selected tab. As far as I know this is impossible to fix and is a limitation with Studio’s plugin support, but if you have any suggestions please let me know! (Also, recreating the DockWidgetPluginGui instance whenever we want to bring it to the foreground is not a solution because it kicks the user out of any scripts they are editing which is bad UX)
If the Diffy widget is docked in the main viewport, it will not be reachable via Ctrl+Tab, and sometimes when using the Open Script feature the desired script will not be brought to foreground of the main viewport area either. Again these appear to be limitations of Studio’s plugin support
(Above: The homepage with three scripts selected.)
Using the source code
I am happy for people to use Diffy’s source code in their own projects so long as they have purchased the Diffy plugin from the Creator Store and respect the following license:
Diffy License
DIFFY LICENSE
Diffy is a plugin for diffing scripts in Roblox Studio, created by Roblox user
@EmeraldSlash and available on the Creator Store:
https://create.roblox.com/store/asset/16517895889/Diffy-compare-diff-scripts
Anyone is permitted to use Diffy's source for any purpose as long as the
following conditions are met:
1. They have purchased the plugin on the Roblox Creator Store.
2. The full text of this license is present alongside any substantial portions
of source code taken from Diffy (for example as a comment above the code).
This applies even if modifications are made to the code: the license text
must be present somewhere to indicate where the code originally came from.
3. The source is not used in a product that is a direct competitor to Diffy
(i.e. a plugin for diffing scripts in Roblox Studio). This condition can be
ignored in the case where more than a year has elapsed since Diffy was last
updated (which can be checked via the Creator Store), and if Diffy is
subsequently updated after one of these periods without updates, any source
code taken from it during (and only during) that period may continue to be
used indefinitely.
Giving credit by naming the plugin and/or giving a link to its Creator Store page in a user-facing part of your project (such as in an “about” / “help” / “settings” / “credits” page) would also be appreciated, but that is optional.
Obtaining the source code
On Windows, you can obtain the source files (.lua or .rbxm) of any installed plugin by going to C:\Users\<username>\AppData\Local\Roblox\<your-roblox-userid>\InstalledPlugins and looking for the plugin’s asset ID. So in this case you’d look for a directory with the name “16517895889” which is Diffy’s asset ID.
Change Log
Happy diffing!
Bug reports and suggestions are welcome in this thread
Buuuut they don’t work in Roblox Studio so they can’t diff uncommitted script changes and are annoying to use if you need to diff lots of script instances against one another. Hence why I made the plugin
If it works for you great, but there’s a lot of people who prefer doing everything in studio. So there’s no reason to contribute absolutely nothing to the discussion by stating the obvious instead of just applauding them for their work to provide a free resource some people will find helpful
Wait what? Completely agreed with Tyridge until I found out this plugin was 6 USD for something I can do with an (almost always) preinstalled command on every operating system that can run Roblox.
Didn’t notice that, but it’s not really even a valid criticism I don’t think. $6 usd for something that by the looks of it took hours to make and can help some people who don’t want to use roblox’s differ or external software/tools like git is fine. It’s $6. That’s a cup of coffee
I don’t understand all this hatred, even though it is paid, it is right that such a well-made tool should be shared. The important thing is to make those who buy it aware that they could use the command line.
Thanks It was many hours of work - you can see on the creator store that I first published the plugin nearly a year ago. Since then I’ve been heavily using it, slowly fixing problems and adding features. And there’s still plenty more work to be done haha!
(2025-02-16) Version 24: Added Tree Diff feature. So you can now quickly diff big libraries or game components with many scripts such as the PlayerModule. You will also see scripts that have been added/removed highlighted in green/red. Recommended hotkey Ctrl + >.
There are some complications with linking instances together across “old” and “new” versions of a tree, for example when there are instances that have the same name, or when an instance is moved or renamed. To help manage this, three attributes are now supported by Diffy: DiffyId (string), DiffyChildId (string), and DiffyChildOrder (number). These attributes can be applied to instances to control how they get linked together. For more information, see the Help & Settings menu in the plugin
Nice work on this, it seems to be a nice, time-saving plugin. And I like doing things in studio. Easy purchase.
The critique posts above seem to be from people who don’t understand market segmentation. As the original post stated, suggestions are welcome - but instead of articulating how they think it can be made more valuable for their taste, they simply left an unconstructive complaint. Try this instead: “For 6$ I would expect your plugin to at least/also [insert large demand here]”. Then you’ll be constructive instead of unconstructive.
Bug fix: Changing between views would sometimes reset state about whether a script is expanded in the viewport or not.
Bug fix: Sometimes padding lines (darker lines with ^) wouldn’t disappear when changing from Split Aligned to Split Compact layout.
Whole scripts that were fully added/deleted in a tree diff are now properly sorted so that they display in a consistent position relative to each other and to changed & unchanged scripts.
Such whole scripts are also no longer diffed against the empty string, which prevents any confusing matches/mismatches from showing up unexpectedly between the nonexistent and the existent versions of the script. Instead, old and new versions are kept strictly separate and have descriptive labels e.g. “this script has been deleted” or “this script didn’t exist before” or “this script has no content”.
When the Show Whitespace setting is enabled (or when a line is being hovered over), unrenderable ASCII characters (with byte value less than 32, or the byte 127) will be rendered as text codes in the usual Lua format \x where x is the value of the byte. So for example, the CR (carriage return) character will be rendered as \13.
Added a filter for ignoring such unrenderable ASCII characters. Example use case: a recent version of the PlayerModule had a CR character appended to the end of each line, which would make a basic diff with no filters think that the two versions of the PlayerModule were entirely different. This filter can be used to ignore this kind of noise.
Made the diff’s timestamp (shown in the info panel) correspond to when the source of the input scripts was originally read. So going forward this is the meaning of the timestamp, it will no longer change arbitrarily based on other actions such as Switch Old & New or changing filters. It will always just tell you “when did the plugin read the contents of the scripts.”
This is very useful for me. I have a lot of large legacy systems that are implemented in studio entirely. I played around with this for a little while comparing versions of my gun system, and can definitely see the power here. Thank you for the great plugin.
I agree with this yeah! I appreciate the work done by OP in maintaining this tool.
It’s one thing to be able to put together a tool and sell it, though it’s another to actively maintain it so that other developers can have a more tailored experience with diff-checking. Much appreciated!
Would you be willing to open source your creation? I’ve always wanted to add this feature into my RoCommit plugin, which tries to behave like GitHub tracking