Draft
Conversation
Contributor
Author
How to use the Graphite Merge QueueAdd the label graphite/merge to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
❌ 4 Tests Failed:
View the top 3 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
This was referenced Feb 3, 2026
initial move. more refactors incoming.
Draft
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

TL;DR
Not a rollup anymore, just a regular game server with snapshots.
API changes
Below are changes to the user-facing APIs.
Systems no longer return errors
Previously, systems that return errors will cause the world to shutdown. This means systems must always be correct, so returned error is practically useless. A void function is more accurate here.
Removed
BaseCommandandBaseEventThese were originally for extending user-defined commands by embedding an interface that we control, but in pratice they're unused and user-defined methods on the command/event type can conflict with the embedded interface.
Command
Persona()andPayload()methods are now struct fieldsWe're exposing them as public fields instead of getter methods, since the methods don't add anything useful. Removes the extra
callin case Go doesn't optimize getters.Changes to
cardinal.WorldOptionMore details on this in later sections.
EpochFrequencyis removed and theSnapshotFrequencyis renamed toSnapshotRate. Snapshot types are now imported frompkg/cardinal/snapshotinstead ofpkg/micro/.Environment variable changes
Added
CARDINAL_DEBUG, boolean, default:falseRenamed
SHARD_SNAPSHOT_STORAGE_TYPE->CARDINAL_SNAPSHOT_STORAGE_TYPESHARD_SNAPSHOT_FREQUENCY->CARDINAL_SNAPSHOT_RATESNAPSHOT_SNAPSHOT_STORAGE_MAX_BYTES->CARDINAL_SNAPSHOT_STORAGE_MAX_BYTESRemoved
SHARD_MODESHARD_DISABLE_PERSONASHARD_EPOCH_STREAM_MAX_BYTESArchitecture changes
This section explains the changes done in this PR.
Cardinal is no longer a rollup framework
We're removing all of the rollup-related functionaly (e.g. epochs/transactions, signed commands, follower mode/transaction replay) to simplify the architecture and improve the experience for us and for the users.
Data persistence is now the responsibility of snapshots. Nothing much has changed here.
Note
For reviewers:
The files
pkg/micro/shard_*are removed. Snapshots are moved topkg/cardinal/snapshot/.Consolidate command and event handling
Previously
cardinalandecseach have their own structures for collecting and processing commands and events. This PR removes the ECS layer in favor of doing all command/event handling in Cardinal. This also simplifies the system registration code, which is the ugliest part of the code by far.Note
For reviewers:
All command-related code are moved to:
pkg/cardinal/internal/command/.All event-related code are moved to
pkg/cardinal/internal/event/.Refactor system registration
Previously, system registration is done in the
ecspackage, andcardinalextends these with callback functions, e.g. to register the NATS command handlers when commands are registered.Now, the control is inverted and split, with
cardinalcallingecsto register certain fields. ECS only understands the concepts "components" and "system events", but systems can still use "commands" and "events" injected by Cardinal.Note
For reviewers:
Relevant files:
pkg/cardinal/system.goandpkg/cardinal/internal/ecs/system.go.New debug module
Basically a place to put all debug-related utilities. It embeds a connectrpc server that clients (e.g. World CLI, Cardinal editor) can connect to directly instead of going through NATS or a gateway. ATM it only has the introspect endpoint for getting the schema of the registered commands, events, and components.
Note
For reviewers:
Relevant files:
pkg/cardina/debug.go. It's in the same package asWorldso it can access the world fields directly.Refactor the
cardinal/servicemodule [In progress...]The
servicemodule will be merged into cardinal. It's the wrong abstraction layer as it requires a lot of fields fromWorld, so just like the debug module, I moved it to the same layer asWorld.Note
For reviewers:
Relevant files:
pkg/cardinal/service/*moved topkg/cardinal/service_*.Out of scope
Several things came up while refactoring, these are basically the next steps that I ignored in this PR so it doesn't get too large. These will be done in another PR:
Snapshotinterface leaks abstraction layers.