Phlarx / tm-ultimate-medals

An OpenPlanet plugin to show medal times in Trackmania games
GNU General Public License v3.0
12 stars 13 forks source link

Implement system to allow other plugins to register arbitrary medals. #53

Open Phlarx opened 4 weeks ago

Phlarx commented 4 weeks ago

This system would allow other plugins, such as Champion Medals, to list Ultimate Medals as an optional dependency, and then that plugin could, for each track that is loaded, define custom medals that should be listed.

Initial design notes:

  1. Ultimate Medals will export an interface similar to one of the following drafts. The interface should also include an API version identifier for plugins to check. i. Investigate: will this interface need additional information to handle the Stunt and Platform modes? ii. Note: unregistering a medal is intended for when the other plugin gets disabled/unloaded. In API draft A, it is important for protecting the callback function. It is not necessary for API draft B, but should be provided for completeness. ii. Enhancement: cache medal values for tracks played during the current session, rather than reverting to unset each time a map is loaded. A medal should be purged from the cache if it is ever unregistered, iii. Enhancement: verify that the plugin modifying a medal actually "owns" that medal.

    // API draft A
    namespace UltimateMedals {
    /**
     * Register a new medal row with the given medal color and label,
     * with the value provided by the return value of the callback.
     * Returns an ID which can be used to unregister the medal.
     */
    import uint registerMedal(const string &in color, const string &in label, MedalFunc@ callback) from "UltimateMedals";
    
    /**
     * Unregisters a medal matching the provided ID.
     * Returns true if the medal existed and was unregistered,
     * false otherwise.
     */
    import bool unregisterMedal(uint id) from "UltimateMedals";
    }
    // Shared API draft A
    namespace UltimateMedals {
    /**
     * The function definition for medal callbacks. Takes a string
     * argument, which is the current map id, and returns an int,
     * which is the medal's time. If the returned value is negative,
     * the medal is considered not set. This function will be called
     * approximately every 500ms while a map is being played.
     */
    shared funcdef int MedalFunc(const string &in);
    }

    Or this:

    // API draft B
    namespace UltimateMedals {
    /**
     * Register a new medal row with the given medal color and label.
     * Returns an ID which can be used to unregister the medal.
     */
    import uint registerMedal(const string &in color, const string &in label) from "UltimateMedals";
    
    /**
     * Update the time for medal matching the given ID. If the
     * provided time value is negative, the medal is considered
     * not set. Changes will appear in the UI approx every 500ms.
     * When a new map is loaded, all medals will become unset.
     * Returns true if the medal existed and was updated, false
     * otherwise.
     */
    import bool updateMedal(uint id, int time) from "UltimateMedals";
    
    /**
     * Unregisters a medal matching the provided ID.
     * Returns true if the medal existed and was unregistered,
     * false otherwise.
     */
    import bool unregisterMedal(uint id) from "UltimateMedals";
    }
  2. All 3rd-party medals will be rendered with a distinct text color, such as $d90. Medals will have a custom medal icon color, and custom medal name. i. Enhancement: allow user customization of medal names by storing a mapping from the plugin-provided name to the user-provided one. ii. Enhancement: allow medals to use the dual-color icons used for the Turbo super medals.
  3. By default, custom medals will be hidden from the UI until their time is provided by their plugin. The reason for this is that not all tracks will have every medal defined. However, a setting will be provided to show all medals even when not set. If the setting is selected, unset medals should be rendered in a dimmed or greyed out manner until their time is set to a positive value. This is useful for users that prefer the window to maintain a predictable height. i. Investigate: since ordering of unset custom medals is undefined, it might make sense to leave them in their most recent position, or to move them to the end of the list. Need to consider user experience and stability of ordering. ii. Enhancement: apply similar behavior to the Turbo super medals, providing a setting allowing them to be shown in a dimmed state.
  4. Custom medals may be disabled via settings in the same way as the built-in medals. This will require a scripted settings tab, either for only the custom medals, or for all medals (replacing the current settings tab).