vrchat-community / UdonSharp

A compiler for compiling C# to Udon assembly
https://udonsharp.docs.vrchat.com
MIT License
470 stars 50 forks source link

Change/Remove `serializedUdonProgramAsset`'s guid to be source control friendly #65

Open JanSharp opened 2 years ago

JanSharp commented 2 years ago

First of all a disclaimer, I'm still using v0.20.3 because that's the latest release on github and to my knowledge the latest one that isn't using the VRChat Creator Companion. However I don't believe this has changed in later versions, but if it has let me know.

Feature Description: When one has an UdonSharp script with an asset file along side it and said files have just been copied into the project through some method, the file reference guid in serializedUdonProgramAsset should remain unchanged, which means the guid in the meta file for a file in SerializedUdonPrograms should be set to the same guid as storedd in serializedUdonProgramAsset instead of making a new one. I don't know if this is possible with unity, it's outside of my editor scripting knowledge, so if it isn't possible then the other option I can think of is removing serializedUdonProgramAsset from the asset file for UdonSharp entirely. I believe this would then require some other editor script which when initialized figures out the references from UdonSharp asset files to files in SerializedUdonPrograms, which would require those references to either be stored in SerializedUdonPrograms or another file that just stores references maybe in the Library folder. Once again, I don't know enough to say which works or is better or worse.

Additional context: However to help you better asses the issue, here's why - in my opinion - this is a serious issue:

serializedUdonProgramAsset changes between projects for the same scripts (copies) because the files in SerializedUdonPrograms aren't copied over. This is a big problem when trying to use UdonSharp in a project with version control, because every time you check out the changes someone else made all of your guids get changed, but they then change again once you go back to unity since those guids weren't your guids. In version control systems with file locking this means that basically every asset file needs to be locked whenever you're working on something potentially preventing any other person working on the same project as you are at the same time (if my understanding of those systems is correct) and the files will always appear as changed even though nothing really changed, just the guid. In version control systems without file locking all asset files also constantly change, but there's a very good chance of merge conficts for every asset file once multiple people start working at the same time or on different branches which at some point get merged. Including SerializedUdonPrograms in version control is first of all simply wrong because those files are 100% generated and secondly not even an option if you aren't version controlling the root of the project. For example if you have Assets/MyScripts as the root of the repository, SerializedUdonPrograms is entirely outside of the repo.

I've thought about workarounds, specifically when using git and gitlfs, and I won't explain all of the thoughts I had on it already but even just a workaround requires dozends of hours of work and still has preformance concerns.

If there's any other solution to this problem that doesn't involve changing how serializedUdonProgramAsset works I'd also be happy to know.

MerlinVR commented 2 years ago

I'm aware of this issue and how it's not great, but it's an Udon construct that enforces the linkage to serialized programs currently. Typically messing with things like the GUIDs that Unity handles for internal file tracking is liable to corrupt projects or cause other issues so I avoid it.

Eventually I want to remove the dependence on serialized programs, but that is a breaking change for the SDK at least. For now you can commit the serialized programs and then tell git to ignore changes to them via --assume-unchanged or you can keep them out of version control and deal with the scenes/U# assets being modified.

JanSharp commented 2 years ago

I'm glad to hear that you're already aware of the issue :+1: Makes sense that it's a Udon thing so also makes sense that you can't just change it, and yea messing with internal guids isn't smart, you're definitely right.

I'm also glad to hear that you have an idea for how to resolve the issue.

Regarding what to do in the meantime, --assume-unchanged is definitely the best solution, I'll just have to write a script to make it less tedious, which is fine. However since not all projects actually have the SerializedUdonPrograms folder inside them I can't do it for all of them. So this got me curious if marking the UdonSharp asset files themselves as --assume-unchanged would work without breaking anything. I tested it by checking out an old version of an asset file without checking out the script file for it and it definitely isn't smooth (the inspector for that UdonBehaviour continuously errors), but it seems like once the scripts have been recompiled and reimported (which seems to require entering playmode once) the asset file fixes itself (actually back to the exact same state before checking out the old version) and the scene seems to be unmodified. So basically I'm asking if this is safe or not. It seems fine at least. The scene's serializedProgramAsset would still differ, but only the scenes changing is much better than all asset files

MerlinVR commented 2 years ago

It should be fine since the U# program assets only contain intermediate data excluding the script reference which shouldn't change after you create the asset. It will take a compile to rebuild that data though as you've seen.

JanSharp commented 2 years ago

Wonderful, thank you