Skip to content

Conversation

@wuke32767
Copy link
Contributor

@wuke32767 wuke32767 commented Nov 16, 2024

This PR aims to add flag support to the dream block.
In this case, activated and deactivated dream block can appears at the same time,
which vanilla Celeste, Everest and some of mods do not support.
What did vanilla do:

  • Dream block has playerHasDreamDash for only visual.
  • The actual activation state is Session.Inventory.DreamDash which is global.
  • When it's changed (only in 2A dream mirror), activate all dream block manually (visual).
  • In most cases, check Inventory.DreamDash and assume all dream block is activated or not actoivated, then happily read Tracker[DreamBlock] (mainly used in Collide method series).

To change this:

  • Add DreamBlock.Activated to represent the dream block's actual state (actually a property to read Inventory.DreamDash directly)
  • Change Player.DreamDashCheck Player.DashCoroutine Player.DreamDashUpdate to use that property.
    • Replace Collide method with ours and hope that it can work with all mods.
      • the most dangerous part.
    • Remove any Inventory.DreamDash.

What did Everest and mods do:

  • Most of custom dream block inherit from dream block so most of them should work.
    • The rest don't inherit from dream block.
    • Some use dream block dummy so can work.
    • The others reads Inventory.DreamDash so they can't get flag support automatically. (can work as before)
  • If a mod changes Inventory.DreamDash, it should work, as DreamBlock.Activated is a property that can read it.
  • If it then call DreamBlock.Activate series, it can in wrong visual state.

To change this:

  • Announce that DreamBlock.Activate series is Obsolete.
  • Make a new series that call Activate or Deactivate according to DreamBlock.Activated.
  • Require these modders to migrate.
  • DreamBlock.Activate series still works fine in old map, so we don't need to migrate them all/quickly.

Finally, we are prepared to add flag support.

  • Add DreamBlock.Flag.
  • Add flag controls to DreamBlock.Activated.
  • Make it NoInlining for hooks.
  • Notice that sometimes DreamBlock.Activated can be different from flag, so we need flagState to save current flag state. only when flagState is changed, we can try to update visuals to match state.
  • don't forget to check it every frame in Update.
  • Add ActivatedPlus for extensibility. It's designed for non-visual state.

For performance reason, add Level.HasNewDreamBlock.

  • If a dream block is flag-controlled, counter++.
  • If it's not controlled by flag, or is removed, counter--.
  • Restore removed Inventory.DreamDash. Ignore it when there's flag dream block.

Add DreamBlockPatch to indicate if this patch has been applied.

Info

  1. It's migrated from Reverse Helper. If you have questions to any part of it,
    • it's actually what did Reverse Helper do.
    • It's designed for the extensibility.
    • It's because of the compatibility.
    • This part can be improved. Thanks for your suggestion.
      feel free to ask me.
  2. As the branch name suggests, this patch does not have trackers.
    it's impossible to track if an field is changed.
    • the solution can be convert it to property somehow,
      • is it even possible?
    • or require everyone to broadcast the event.
      • this would break mod backward compatibility, and I'm not sure if it can improve performance, compared to Level.HasNewDreamBlock.

What should we do

  • Discussion / Review
  • Checking Backward Compatibility
    Tested CelesteTAS 100%.tas
    Checked 2A Cutscene and it looks good
    wrote a test map and it looks good
  • Checking Mod Compatibility
    Tested Mod List is the same as Ja's IL Hook Viewer
    - Communal Helper - crashed
    - More Lock Block - didn't work (apparently)
  • Then, solve the said issue

Main IL Changes And Mod Compatibility

  • DreamBlock.Added
    Added new method call after Inventory.DreamDash to replace it with correct state
    should be good in 95% cases

    it's not clean tbh

  • DreamBlock.Update
    Update flag state every frame
    should be good in 99.9% cases

  • Player.DreamDashCheck
    Replace all Collides with custom one
    Remove Inventory.DreamDash conditionally

    Should be good, because nobody loves to hook it.
    More Lock Block was broken.
    Tera Helper is not broken, but they should change their hook.

  • Player.DashCoroutine
    Replace one Collides with custom one
    Remove Inventory.DreamDash conditionally

    Communalhelper was broken.

  • Player.DreamDashUpdate
    Replace one Collides with custom one

    There's no Inventory.DreamDash.

    No mods was broken.

@maddie480
Copy link
Member

I don't think editing entities at the Everest level are a thing we do anymore 🤔

@maddie480 maddie480 added the discussion Needs input from others label Feb 2, 2025
@wuke32767
Copy link
Contributor Author

it's even worse to do this at the helper level

@maddie480
Copy link
Member

As the description highlights, we're talking of a change impacting anyone extending DreamBlock and hooking certain heavily-hooked methods like DashCoroutine, and the description confirms that some mods indeed were broken

If we do want this (@ Everest Team?) the issues with mod compatibility will definitely have to be addressed beforehand 🤔 and if the goal is adding flag support for all the modded dream blocks out there, their plugins should be updated as well

@maddie480 maddie480 added needs fixing and removed discussion Needs input from others labels Feb 14, 2025
@maddie480 maddie480 added review needed This PR needs 2 approvals to be merged (bot-managed) and removed needs fixing labels May 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review needed This PR needs 2 approvals to be merged (bot-managed)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants