godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.17k stars 98 forks source link

Add License Management to the AssetLib #7734

Open HolonProduction opened 1 year ago

HolonProduction commented 1 year ago

Describe the project you are working on

Prototypes

Describe the problem or limitation you are having in your project

In theory the possibility to use plugins which provide useful solutions to a project is a huge advantage for projects. However in Godot I often decide against using plugins. One reason for that is the workflow of handling plugin licenses. There is license information in the AssetLib database, but due to the way Godot plugins are structured the installed plugin won't contain a license in most cases. License files are most often placed in the root directory of a project. Since a plugin that is setup correctly will only install the content of addons/*plugin* the project license is not included in the download.

Handling licenses correctly would therefore require creating and maintaining an own text file in which licenses are copied from the repositories. This is a lot of work and does not handle license updates well.

In comparison here is how license management works in Flutter. Packages are installed via the package manager. They contain license information, that the user does not have to interact with. The developer can then call one function to open a complete license explorer for the user. It includes the project license, licenses of installed packages and the core licenses of flutter.

Godot needs usability improvements in this field.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

This proposal aims to describe a more complete License Management API for Godot that does not require work from the developer.

Taking inspiration from Flutters License Management, we can split License Management up in two integral parts:

  1. Keeping track of used licenses
  2. Displaying them to the user through an UI

This proposal will focus on the first point because it lays the foundation for further work. The second point could be implemented at a later time, potentially through a plugin.

The new API will include three kinds of licenses:

  1. Godot Licenses: The licenses of Godot and its dependencies. Those licenses are already available through Engine.get_copyright_info, Engine.get_license_info and Engine.get_license_text. To keep things consistent they should also be available through the new API.
  2. Plugin Licenses: This are the licenses of plugins that were installed through the AssetLib. There is currently no simple way to obtain these.
  3. Project License: The final game will be under some sort of License or Eula as well. The developer should have a way of injecting this license into the API as well, to bundle all license info in one unified place.

This different kinds of licenses will be available through a unified interface and will all be available in the same data format. In this way it is easy to build UI on top of it.

The information will be accessible via a new singleton. In the following I will call it Licenses however I'm not quite sure about the name.

Licenses will provide the following methods:

The last three methods will be needed internally because the aggregation of the different license types will differ. I'm not sure on whether these should be exposed though.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Data Format

The only license data that is currently exposed through the engine is structured in two parts.

This format works well with the builtin license view of the Godot Editor. However it is not suited for the new API because of the following reasons:

Therefor the data format boils down to:

class LicenseData:
    var name: String # e.g. Godot Engine
    var license: String # e.g Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md).
...
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Engine Licenses

Since the new data format is a subset of the already available license information, it is possible to call the available API and convert the results.

Project License

The developer can configure the project license through the new project setting application/config/license. It will only be visible in advanced mode so that users who only want to experiment with the engine don't need to bother with it. It will default to an empty string. If it is empty Licenses.get_project_licenses will return an empty array.

Plugin Licenses

There is currently no license information provided by the plugin. In the future a plugin can declare its license in plugin.cfg by putting it under the key plugin/license. The engine will not enforce this field to keep backwards compatibility. If it is not present the license text will default to Copyright $author.

Since the plugin.cfg gets not bundled in the final export the engine needs to extract this information on export time and cache it some were in the .godot folder.

Migration

While the engine will not enforce the field it should be enforced for new uploads or updates to the AssetLib through the review process. As explained above most plugins already have license information in their plugin. However due to the plugin structure it is impossible to include in the install. Therefor having duplicated license information is inevitable for this proposal. This is additional work for plugin developers, therefor it needs to be enforced to find adaption.

Plugin Creation dialog

When creating a new plugin the developer does not need to provide a full license text. He gets to choose from a dropdown with common open source licenses like MIT, BSD, GPL3,... and the option All Rights Reserved. The default selection will be MIT. On creation the full license text will be generated from this dropdown, the Author field and the current year.

For subsequent edits, the license text will be available as full size text field.

If this enhancement will not be used often, can it be worked around with a few lines of script?

Parts of this could be solved with an editor plugin. The UI part is not part of this proposal for this reason.

The minimum that cannot be a plugin is an officially enforced way for plugin license information.

Collecting the license information and providing it to the developer could also be a plugin, but it would require some hacks on the plugin side to keep the .cfg files or cache their content. An official solution with access to .godot seems better in place here.

Is there a reason why this should be core and not an add-on in the asset library?

See above

Self critical area

This is my first bigger proposal so feedback is appreciated.

While writing this the following critique points came to mind:

Calinou commented 1 year ago

This seems like a lot of complexity for something that most casual users will not spend much effort on. (In my experience, a lot of people publishing games already don't follow advice from the the Complying with licenses page. If anything, we should prevent that page from getting more complex.)

There are still ways to improve the existing situation, but I would refrain from adding too many things at once to avoid feature creep. For now, I would just add a SPDX license field to plugin.cfg (and expose it in the plugin creation dialog) and be done with it :slightly_smiling_face: The plugin creation dialog can display a warning if you enter a name that isn't a valid SPDX license name.

Handling existing assets will be an issue regardless. This will likely require someone to open a lot of pull requests against assets, then having the asset authors create a patch release.

YuriSizov commented 1 year ago

For now, I would just add a SPDX license field to plugin.cfg (and expose it in the plugin creation dialog) and be done with it 🙂

I think we can add a field that links to a license file, similar to how we link to the main script file. The file is almost guaranteed to be there in the asset folder of all well-maintained assets. And then EditorPlugin can expose some API that returns the contents of that file as a text, and Engine method can hook into it.

HolonProduction commented 1 year ago

This seems like a lot of complexity for something that most casual users will not spend much effort on. (In my experience, a lot of people publishing games already don't follow advice from the the Complying with licenses page. If anything, we should prevent that page from getting more complex.)

Yeah a lot of users don't fully understand licenses and don't care about them. But I think that it is no excuse to ignore the DX for license compliance because it should matter to a lot of games. The current page does only talk about the engine licenses and does not mention the asset lib at all so if we were to include it it would be bound the become more complex anyway.

Furthermore this API is not aimed at most regular users so I see no need to add it to the compliance docs. It is meant as way for plugins, like Simple License, to provide a minimum effort license UI like Flutter has one. So in the end complying with licenses for most users is meant to be easier.

That said, the API part of the proposal could be implemented as plugin itself so if it adds too much complexity on the development side, I am fine with it being a plugin. (I would still prefer the engine to handle the collection of license info but an enforced and documented way for plugins to specify their license definitely has priority.)

There are still ways to improve the existing situation, but I would refrain from adding too many things at once to avoid feature creep. For now, I would just add a SPDX license field to plugin.cfg (and expose it in the plugin creation dialog) and be done with it 🙂 The plugin creation dialog can display a warning if you enter a name that isn't a valid SPDX license name.

I think to keep the whole thing future prove, there has to be a way to allow for custom licenses. So the idea of allowing to link a file makes sense to me.

Handling existing assets will be an issue regardless. This will likely require someone to open a lot of pull requests against assets, then having the asset authors create a patch release.

That's why I wanted to keep the engine backwards compatible but enforce this through the asset lib.

I think we can add a field that links to a license file, similar to how we link to the main script file. The file is almost guaranteed to be there in the asset folder of all well-maintained assets. And then EditorPlugin can expose some API that returns the contents of that file as a text, and Engine method can hook into it.

As said above I support this idea but I wanted to also point out the technical difficulty with it. When exporting neither the config file nor the license file will be included (as of now). So either Godot needs to include those files every time or some cache in .godot will be necessary.