Vectrosity support as a package

I have completely transitioned Grid Framework to a Unity3D package now and moved Vectrosity support to a separate package. The Vectrosity package will be made available as a public Git repository under the MIT license, that should make it as simple as possible for users to add it to their project. While transitioning to packages has had many advantages there have also been some challenges to overcome and I would like to go over them in this post.

Documentation

I hold the opinion that every software should come with offline documentation, unless it is so trivial that it does not need any documentation to begin with. The manual and scripting reference consists of HTML pages with images, CSS files and a little bit of JavaScript, all generated by Doxygen.

The result is pretty good in my opinion, but Unity throws a wrench in my plans: it treats the Javascript as game scripts and the images as textures. Now your project won't compile and your textures library will be full of images which were never meant to be used as textures. My solution until now has been to run some automated text editing magic to rename the files and rewrite references to them. It works because the web browser does not care about file extensions when rendering a page, but you might have issues if you try to open the image on its own.

Packages solve this problem neatly: Any directory name which ends in a tilde (~) will be ignored. Unity already uses Documentation~ for documentation, so I simply output the generated files there. A README file points users in the right direction if they decide to poke around in the folder, and the documentation can be opened straight from Unity's help menu as well.

Samples

Examples are a good way to get a taste of an extension in action and try it out quickly, especially for a scripting extension. The examples have had a similar problem to the documentation in that you would have all those foreign textures and scripts in your project, but at least examples would not stop your project from compiling. Users who did not want all that stuff had to go and delete the examples by hand. We can do better than that.

Packages have a "samples" mechanism: you can mark certain directories of the package as samples and users can then import individual examples into their project. They can also throw the imported sample away or modify it without affecting the original sample. Samples are usually stored inside the Samples~ directory which is ignored by Unity.

That's great if you are a user, but it is horrible if you are developer. I do not want Unity to ignore my samples, I want it to compile my scripts, load my textures, generate meta files and so on. After trying out various solutions, one more convoluted than the other, I think I have found a dead simple and in hindsight obvious solution: use symbolic links (symlinks).

First I symlink the original samples directory to one that is not ignored: ln -s Samples~ Samples. This creates a directory which Unity will pick up, and changes to files inside the link directory are applied to the files inside the original directory (because they are the exact same files). All that is now left to do is to instruct Git to ignore the link by adding the link to the .gitignore file (or to .git/info/exclude). Obviously the link must not be shipped to end users.

A final word of caution: Unity warns against using symlinks because it is possible to seriously mess up your project. They do not discourage it, but you need to know what you are doing.

Packages/com.hiphish.grid-framework/Samples is a symbolic link. Using symlinks in Unity projects may cause your project to become corrupted if you create multiple references to the same asset, use recursive symlinks or use symlinks to share assets between projects used with different versions of Unity. Make sure you know what you are doing.

I think I'm going to be fine. What could possibly go wrong? (famous last words)

Vectrosity package

This is the big one. Including Vectrosity support in the main package would break compilation for anyone who does not have have Vectrosity installed, so I needed an ugly workaround involving preprocessor symbols. With packages it's simple: if you want Vectrosity support, install it as a separate package. The package will be available on launch as a public Git repository, no strings attached.

There are two ways to create a package: as a standalone package or embedded inside a project. Grid Framework is embedded because it is simpler to have the supporting Unity structure around it. The Vectrosity package on the other hand is standalone because it makes things easier for users.

However, in order to develop Vectrosity support I still need a Unity project to generate the meta files and provide me with tooling while programming. The solution is simple: First I have a copy of the Git repository on my local system, then I add it as a local package to my Grid Framework project. I can now work inside the Grid Framework project, make changes to the Vectrosity files and the original files inside the Vectrosity repository will be affected.

I also use the same trick for working on the samples as above.

Conclusion

Unity packages solve many of the issues of the past: files can be grouped properly according to their role, directories can be ignored, scripts can be compiled in separate assemblies, and packages can have metadata. They also introduce their own sets of challenges, but the new problems are far easier to solve and can be solved cleanly instead of hacking my way around them.