Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: World Transactional API #2407

Open
gabizou opened this issue Jan 24, 2022 · 0 comments
Open

RFC: World Transactional API #2407

gabizou opened this issue Jan 24, 2022 · 0 comments

Comments

@gabizou
Copy link
Member

gabizou commented Jan 24, 2022

The basics

We enforce a transaction based system onto Minecraft, but we struggle to do so for plugins who want to go to a further level of "I want to know if the full set of changes succeeded"

Backstory

In Sponge, we implemented a transaction recording system for blocks/entities changes in the game to enable plugins better control over all sorts of side effects. The implementation of the system is powered by what most in the community know as the PhaseTracker. This handy bit of code isn't small, nor is it easy to break down into usable portions outside of the game. As the crude explanation, it's a series of hooks to push and pop labeled states of the game onto a stack, which determine with added context, what to populate in a Cause for every event thrown during that state.

Some current half-steps

We do enable plugin developers to operate on a near full transaction-like system by providing VolumeStream as an API, which does a pretty good job at keeping the full breadth of bulk changes in one fell swoop. We also have the one-offs change methods (setBlock, etc)

Goals

This API should expose a closed loop of bulk changes:

  • Block changes with BlockChangeFlag understanding
  • Single series of events being called (up to one ChangeBlock.All and up to one SpawnEntityEvent for spawns, etc.)
  • Validator callback to accept or cancel the entire transaction based on the results of above events (if anything was cancelled, can selectively ignore those cancelled changes, or cancel the entire transaction)
  • Offer a StackFrame to enable adding additional Cause/Context information for the events named above

Non-goals

This API looks like a transaction library, but by no means is it meant to fully expose the PhaseTracker as an API, nor states, nor anything under the hood. Similarly, we do not want to treat this as a SQL-like system.

Examples

Quite simply, I could see this as:

final boolean appliedSuccessfully = world.transact((CauseStackManager.StackFrame frame, ServerWorld serverWorld, Verifier verifier) -> { 
  // Do changes
  verifier.verifyBlocks((BlockTransaction transaction) -> transaction.isCancelled());
  verifier.verifyEntities((//...));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant