CLI and API compatibility policy ================================ Human users and API users rely on the mpv/libmpv/scripting/IPC interface not breaking their use case. On the other hand, active development occasionally requires breaking things, such as removing old options or changing options in a way that may break. This document lists rules when, what, and how incompatible changes can be made. It's interesting both for mpv developers, who want to change user-visible parts, and mpv users, who want to know what is guaranteed to remain stable. Any of the rules below may be overridden by statements in more specific documentation (for example, if the manpage says that a particular option may be removed any time, it means that, and the option probably won't even go through deprecation). Additions --------- Additions are basically always allowed. API users etc. are supposed to deal with the possibility that for example new API functions are added. Some parts of the API may document how they are extended. Options, commands, properties, events, hooks (command interface) ---------------------------------------------------------------- All of these are important for interfacing both with end users and API users (which include Lua scripts, libmpv, and the JSON IPC). As such, they constitute a large part of the user interface and APIs. Certain options and commands may have documented default values. These default values are considered a part of the API since scripts may already rely on these documented behaviors. Changing these defaults are considered incompatible changes and must be documented. Undocumented default values do not subject to this requirement, and it is recommended to discourage such usage in the related documentations if there is a need to frequently change such defaults. All incompatible changes to this must be declared in interface-changes.rst, which include the types of changes, the impact of these changes, and suggested actions to address such impact so that the incompatibility is alleviated. (This may also list compatible additions, but it's not a requirement.) Degrees of importance and compatibility preservation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Critical and central parts of the command interface have the strictest requirements. It may not be reasonable to break them, and other means to achieve some change have to be found. For example, the "seek" command is a bit of a mess, but since changing it would likely affect almost every user, it may be impossible to break at least the commonly used syntax. If changed anyway, there should be a deprecation period of at least 1 year, during which the command still works, and possibly a warning should remain even after this. Important/often used parts must be deprecated for at least 2 releases before they can be broken. There must be at least 1 release where the deprecated functionality still works, and a replacement is available (if technically reasonable). For example, a feature deprecated in mpv 0.30.0 may be removed in mpv 0.32.0. Minor releases do not count towards this. Under extraordinary circumstances, such as missed incompatible changes that are already included in a release, critical security fixes, or a severe shortage of developer time to address the known incompatible changes, important/often used parts may be broken immediately, but the change must be extensively documented: all of the related documentations (including manpage, interface-changes.rst, etc., retrospectively modified if applicable) must clearly state the following: the fact that the change is a breaking change; the version when the breaking change happened; and the reason, impact, and suggested remedy actions. Less useful parts can be broken immediately, but must come with some sort of removal warning. Parts for debugging and testing may be removed any time, potentially even without any sort of documentation. Currently, the importance of a part is not documented and not even well-defined, which is probably a mistake. Renaming or removing options ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Typically, renaming an option can be done in a compatible way with OPT_REPLACED. You may need to check whether the corresponding properties still work (including messy details like observing properties for changes). OPT_REMOVED can be used to inform the user of alternatives or reasons for the removal, which is better than an option not found error. Likewise, m_option.deprecation_message should be set to something helpful. Both OPT_REPLACED and OPT_REMOVED can remain in the code for a long time, since they're unintrusive and hopefully make incompatible changes less painful for users. Scripting APIs -------------- This affects internal scripting APIs (currently Lua and JavaScript). Vaguely the same rules as with the command interface apply. Since there is a large number of scripts, an effort should be made to provide compatibility for old scripts, but it does not need to be stronger than that of the command interface. Undocumented parts of the scripting APIs are _not_ guaranteed for compatibility. This applies especially for internals. Languages like Lua do not have strict access control (nor does the mpv code try to emulate any), so if a script accesses private parts, and breaks on the next mpv release, it's not mpv's problem. JSON IPC -------- The JSON IPC is a thin protocol wrapping the libmpv API and the command interface. Compatibility-wise, it's about the same as the scripting APIs. The JSON protocol commands should remain as compatible as possible, and it should probably accept the current way commands are delimited (line breaks) forever. The protocol may accept non-standard JSON extensions, but only standard JSON (possibly with restrictions) is guaranteed for compatibility. Clients which want to remain compatible should not use any extensions. CLI --- Things such as default key bindings do not necessarily require compatibility. However, the release notes should be extremely clear on changes to "important" key bindings. Bindings which restore the old behavior should be added to restore-old-bindings.conf and restore-osc-bindings.conf. Some option parsing is CLI-only and not available from libmpv or scripting. No compatibility guarantees come with them. However, the rules which mpv uses to distinguish between options and filenames must remain consistent (if the non-deprecated options syntax is used). Terminal and log output ----------------------- There are no compatibility guarantees for the terminal output, or the text logged via ``MPV_EVENT_LOG_MESSAGE`` and similar APIs. In particular, scripts invoking mpv CLI are extremely discouraged from trying to parse text output, and should use other mechanisms such as the JSON IPC. Protocols, filters, demuxers, etc. ---------------------------------- Which of these are present is generally not guaranteed, and can even depend on compile time settings. The filter list and their sub-options are considered part of the command-interface. libmpv C API ------------ The libmpv client API (such as ````) mostly gives access to the command interface. The API itself (if looked at as a component separate from the command interface) is intended to be extremely stable. All API changes are documented in client-api-changes.rst. API compatibility ^^^^^^^^^^^^^^^^^ The API is *always* compatible. Incompatible changes are only allowed on major API version changes (see ``MPV_CLIENT_API_VERSION``). A major version change is an extremely rare event, which means usually no API symbols are ever removed. Essentially removing API functions by making them always return an error, or making it do nothing is allowed in cases where it is unlikely to break most clients, but requires a deprecation period of 2 releases. (This has happened to ``mpv_suspend()`` for example.) API symbols can be deprecated. This should be clearly marked in the doxygen with ``@deprecated``, and if possible, the affected API symbols should not be visible if the API user defines ``MPV_ENABLE_DEPRECATED`` to 0. ABI compatibility ^^^^^^^^^^^^^^^^^ The ABI must never be broken, except on major API version changes. For example, constants don't change their values. Structs are tricky. If a struct can be allocated by a user (such as ``mpv_node``), no fields can be added. (Unless it's an union, and the addition does not change the offset or alignment of any of the fields or the struct itself. This has happened to ``mpv_node`` in the past.) If a struct is allocated by libmpv only, new fields can be appended to the end (for example ``mpv_event``). The ABI is only backward compatible. This means if a host application is linked to an older libmpv, and libmpv is updated to a newer version, it will still work (as in not causing any undefined behavior). Forward compatibility (an application would work with an older libmpv than it was linked to) is not required.