You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
So, I've been thinking hard about how we resolve contracts, and how that system interacts with plugins.
Current System
Controller#resolveContract(id: string) - resolves a contract by ID. The process for doing so performs the following steps, exiting early if any condition is satisfied:
Call the getMissionManifest hook - gives plugins the option to contribute contracts
Check if any of the contracts in the local contracts folder match
Check if our internal registry (Peacock's contract data) contains a contract
This system works, but it has a few limitations.
Goals
I've re-thought the system, attempting to account for the following goals:
Contracts can be different between game versions
Add gameVersion parameter
Removes hacks for SCPC Hawk (The Last Yardbird) and H1 Bull (Freedom Fighters)
Atampy needs this, HITMAPS may need this
All plugins should get an equal say in how a contract ends up
Right now, whichever plugin is first to return a contract wins
If a plugin wants to provide a custom contract, other plugins cannot make tweaks to that
If a plugin wants to override an existing contract, other plugins are helpless to make their own tweaks
Plugins need the ability to resolve a contract within a contract resolution request
Right now this could cause infinite recursion/stack overflow
Proposed Solution
The solution I've thought up of is splitting this into a two step process, inspired a bit by ModLauncher for Minecraft:
Initial resolution - this part works mostly how the current system works - first come, first served. No transformations to contracts should happen here, just providing a contract as-is.
Negotiation phase - this is the new part, which opens up a lot more flexibility.
The negotiation phase goes as follows (NP = function that implements this):
NPs are called with the contract that was retrieved from the first step and the game version.
NPs return a boolean that represents if it has made changes
NPs can make any changes to the contract they want.
If an NP makes changes to the contract, it must return true.
This process is repeated until all NPs are happy with the ending products (all return false).
An error will be thrown if the process is run more than X times to prevent deadlocking (open to discussion for X, I'm thinking 500 or 1000)
NPs are allowed to do nested resolution (a function will be passed in for this, where the only rule is that you cannot try to resolve the current contract ID).
Feedback
This is just a concept, so I'm open to any feedback as to how to improve this!
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
So, I've been thinking hard about how we resolve contracts, and how that system interacts with plugins.
Current System
Controller#resolveContract(id: string)
- resolves a contract by ID. The process for doing so performs the following steps, exiting early if any condition is satisfied:This system works, but it has a few limitations.
Goals
I've re-thought the system, attempting to account for the following goals:
gameVersion
parameterProposed Solution
The solution I've thought up of is splitting this into a two step process, inspired a bit by ModLauncher for Minecraft:
The negotiation phase goes as follows (NP = function that implements this):
true
.false
).NPs are allowed to do nested resolution (a function will be passed in for this, where the only rule is that you cannot try to resolve the current contract ID).
Feedback
This is just a concept, so I'm open to any feedback as to how to improve this!
Beta Was this translation helpful? Give feedback.
All reactions