Skip to content

Controlify 2.0.0-beta.9 for MC 1.20.6

Pre-release
Pre-release
Compare
Choose a tag to compare
@isXander isXander released this 24 May 14:12
· 128 commits to 1.20.x/dev since this release

Controlify 2.0.0-beta.9

This version has the following builds - make sure you select the right one for your Minecraft version:

  • 1.20.1
  • 1.20.4
  • 1.20.6 (also supports 1.20.5)

Rewritten binding system

The way Controlify consumes inputs from the controller has been completely rewritten.
The aim of this rewrite was to make the system more data-driven and have a more robust API.

controller.bindings() is now completely gone. Instead, you access a static supplier for a bind
in ControlifyBindings and use that to get the instance of a bind for a controller.

if (ControlifyBindings.JUMP.on(controller).justPressed()) {
    // do something!
}

Here's an example of how you can create your own InputBinding:

public static InputBindingSupplier MY_CUSTOM_BINDING = ControlifyBindingApi.get().registerBinding(builder ->
        .id("my_mod", "my_custom_binding")
        .category(Component.literal("Cool category"))
        .allowedContexts(BindContexts.IN_GAME) // highly recommended - will suppress outputs like justPressed() if incorrect context
        .keyEmulation(options.keyJump) // example, optional
        .addKeyCorrelation(options.keyAttack) // example, optional
        .radialCandidate(RadialIcons.getEffect(MobEffect.JUMP_BOOST))); // example, optional

You should have this field in your Controlify entrypoint to ensure that the class is initialised before the
registry is locked.

Remember, defaults are now data-driven, see below for how to use that. For this example, the key would be
my_mod:my_custom_binding. If it is not set, your binding will be bound to empty. You can optionally hard-code a
default bind with .defaultBind (layered bottom-most) though this is highly recommended against and is only useful
when generating bindings on-the-fly.

What is a bind context?

Bind contexts is a new system that suppresses binding outputs if the current context doesn't match.
This prevents problems like binding the same input to, for example, Drop and Gui Back, as it could cause both to trigger.

It also lets Controlify know when binds will conflict, and display them in red in the options so the user knows when
they've done something wrong.

This is something I'd like to expand on in the future, like making some UI to easily filter between contexts.

What is a key correlation?

Currently, key correlations don't do anything. Their intended use is to display a button in the Key Bindings vanilla
menu to direct users to bind their controller instead. Calling keyEmulation implicitly calls addKeyCorrelation with
the same key mapping.

Controller types are now namespaced

Controller types are now namespaced to allow for more flexibility.

Instead of

"theme": "xbox_one"

you now write

"namespace": "controlify:xbox_one"

Nothing else has changed for the controller identification file format.

Data-driven defaults

Resource packs can now define the default input for any binding.

  • Can be specific to certain controller types using their namespaces.
  • Layered through packs and default namespace (controlify:default)

assets/controlify/controllers/default_bind/dualsense.json
Note: if using a custom namespace, make sure to change assets/controlify into your controller ID's namespace.

{
  "defaults": {
    "controlify:jump": {
      "button": "controlify:button/touchpad",
      // OR
      "axis": "controlify:axis/left_stick_up",
      // OR
      "hat": "controlify:hat/custom_hat",
      "target_state": "up",
      // OR
      "type": "empty",
      // ALL ABOVE HAVE AN IMPLICIT TYPE EQUAL TO ITS KEY, e.g. `type: button`
    }
  }
}

Here is an example of overriding the default jump binding, only for DualSense controllers.
All the other defaults not specified in this file will be taken from the default namespace.

These changes are safely loaded between reloading packs (applying packs in the resource pack screen without restart).

A side effect of these changes is that bindings that are set to the default are no longer serialized.
This allows packs that modify defaults to fully apply their changes without having to reset the binds individually.

Reloadable controller identification

Changes made in controller_identification.json5 are now properly reloaded.

Controllers which have already been added will be checked to see if their identification has changed
and automatically disconnect/reconnect in order to apply those changes.

Legacy Console Edition defaults

Using all of the new stuff above, Controlify now includes a built-in pack that applies the Legacy Console Edition
controller defaults to all controllers. This pack will be off by default. In the future, I hope to expand this pack
to add the old-style controller button glyphs.

You can use this by going to the resource packs screen and enabling the "Legacy Console" pack.

Controlify Event refactor

An effort is being made to port Controlify to architectury (NeoForge support). This means a slow
abstraction away from Fabric API throughout the mod. Controlify was previously using Fabric API's Event class
for custom events.

Starting from this version, Controlify Events use a custom API (behind the scenes it still uses the FAPI one!).
The side effect of this is that all events now consume a single record type, containing the old arguments for the callback.
This makes it simpler to abstract the existing forge event bus stuff when the time comes.