Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
de7e8f5
docs(plan): plan stage 4, a shared instance that repairs what it inhe…
TheMeinerLP Aug 2, 2026
342afec
docs(plan): record the owner's ruling on the generator setter
TheMeinerLP Aug 2, 2026
0fdf88f
feat(instance): add FalcoSharedInstance, a shared instance Minestom s…
TheMeinerLP Aug 2, 2026
625b236
test(instance): pin that a move into a shared instance sends no chunk…
TheMeinerLP Aug 2, 2026
bba1506
test(instance): count the chunk resend the fast path avoids
TheMeinerLP Aug 2, 2026
ffa3eb9
fix(instance): stop a shared instance from writing its generator into…
TheMeinerLP Aug 2, 2026
1c2253b
fix(instance): stop a shared instance from writing its chunk supplier…
TheMeinerLP Aug 2, 2026
f0d0408
fix(instance): give a shared instance its own auto chunk load decision
TheMeinerLP Aug 2, 2026
ed869ac
docs(instance): name the one direction in which a view outvotes its c…
TheMeinerLP Aug 2, 2026
4d93a11
docs(instance): name every caller a per-view auto chunk load can break
TheMeinerLP Aug 2, 2026
1cbb0b1
fix(instance): save the tags of the shared instance instead of the co…
TheMeinerLP Aug 2, 2026
a87d010
test(instance): cover the parallel and failing halves of a shared ins…
TheMeinerLP Aug 2, 2026
a6588fd
docs(instance): say that a view's save no longer writes the container…
TheMeinerLP Aug 2, 2026
9093c15
docs(instance): state that a shared world keeps the container's write…
TheMeinerLP Aug 2, 2026
7b1d9a4
docs(plan): record what stage 4 repaired and what it could not
TheMeinerLP Aug 2, 2026
4fbde6a
docs(readme): a shared view never wrote its tags through to the conta…
TheMeinerLP Aug 2, 2026
ae90246
docs(plan): name the plan claim that the sources did not carry
TheMeinerLP Aug 2, 2026
fea9ba8
test(archunit): guard the foreign write path the shared instance docu…
TheMeinerLP Aug 2, 2026
37a4e89
docs(plan): re-measure stage 4 at the head the follow-up left behind
TheMeinerLP Aug 2, 2026
937d4c0
docs(plan): correct the file set stage 4 claimed to have touched
TheMeinerLP Aug 2, 2026
9e4153c
docs(plan): count the ten files of stage 4 so the list carries its ow…
TheMeinerLP Aug 2, 2026
2b2f271
docs(instance): the container's off switch stops no view that already…
TheMeinerLP Aug 2, 2026
afb5a25
fix(instance): refuse a container that is registered nowhere
TheMeinerLP Aug 2, 2026
ddfb35e
docs(instance): name what saveInstance does with a failure, and to whom
TheMeinerLP Aug 2, 2026
58523a4
docs(plan): pull the stage 4 result level with the final review
TheMeinerLP Aug 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ nothing to do with speed — and it claims none.
| --- | --- |
| [`falco-anvil`](https://github.com/OneLiteFeatherNET/Falco/wiki/Anvil-Chunk-Loader) | A `ChunkLoader` for the Anvil region format. Genuinely parallel: reading, decompression and NBT parsing do not share one lock. A read failure throws instead of reporting the chunk as absent, so the server cannot overwrite real data with a freshly generated chunk. |
| [`falco-light`](https://github.com/OneLiteFeatherNET/Falco/wiki/Light-Engine) | A block and sky light engine. Thread-safe per call and tied to no chunk implementation, so it works with chunk types Minestom's own engine ignores. Call it yourself, or let a chunk keep its own light up to date. |
| [`falco-instance`](https://github.com/OneLiteFeatherNET/Falco/wiki/Rationale-Instances-And-Chunks) | An `Instance` and its `Chunk`. **No speed gain is claimed and none is measured** — ticking lives in the server's global `ThreadDispatcher`, not in the instance. What it buys is an unload path of its own, where `InstanceManager.unregisterInstance` leaks every chunk a foreign instance ever loaded. It cannot back a `SharedInstance`. |
| [`falco-instance`](https://github.com/OneLiteFeatherNET/Falco/wiki/Rationale-Instances-And-Chunks) | An `Instance` and its `Chunk`. **No speed gain is claimed and none is measured** — ticking lives in the server's global `ThreadDispatcher`, not in the instance. What it buys is an unload path of its own, where `InstanceManager.unregisterInstance` leaks every chunk a foreign instance ever loaded. It cannot back a `SharedInstance`; shared worlds are served by `FalcoSharedInstance` on a plain container instead. |

All three modules are **experimental**. Every public type carries `@ApiStatus.Experimental`;
signatures and behaviour may still change in a minor release.
Expand Down Expand Up @@ -135,6 +135,46 @@ flag — for a pre-lit world the engine is doing work nobody asked for. It earns
without stored light and after blocks change at runtime. Which case is which is spelled out in
[Light Engine](https://github.com/OneLiteFeatherNET/Falco/wiki/Light-Engine).

## Shared worlds

Shared worlds are the one case `FalcoInstance` cannot serve, because `SharedInstance` takes an
`InstanceContainer` and nothing else. `FalcoSharedInstance` accepts that and builds on the container
instead:

```java
InstanceManager manager = MinecraftServer.getInstanceManager();
InstanceContainer world = manager.createInstanceContainer();
world.setChunkSupplier(FalcoChunk::new);

// Not manager.createSharedInstance(world): that factory always builds Minestom's own type.
FalcoSharedInstance view = new FalcoSharedInstance(UUID.randomUUID(), world);
manager.registerSharedInstance(view);
```

The order in that example is not decoration. `createInstanceContainer` registers the container, and
the view's constructor refuses one that is not registered: `registerSharedInstance` performs no such
check, whereas the `createSharedInstance` this class cannot be built by does, and an unregistered
container is ticked by nobody.

The view keeps its own generator, chunk supplier and auto-load setting, where Minestom's writes all
three through to the container and lets one view reconfigure another. All three are read once, in the
constructor, which cuts the other way too: turning auto chunk loading off on the container no longer
stops a view that already exists, so that has to be said to each view. Its tags were always its own —
`Instance` gives every instance a `TagHandler` and `SharedInstance` does not override it — but
`saveInstance()` handed the loader the container, so they were never written; here the view's own
data is what the loader is given.

What none of that changes is who owns the blocks: `setBlock` reaches the container, and the container
serialises every write on its own monitor, because the method that performs the write is
`private synchronized` and is reached from three further places that an override cannot follow. A
world built this way keeps what the Falco chunk saves and keeps the container's write path; a world
that needs the write path uses `FalcoInstance` and gives up sharing.

The per-view generator and chunk supplier are a repair and not a capability: they stop one view from
reconfiguring another, and nothing inside Minestom reads them, because the container creates every
chunk from its own. The reasoning is in
[Rationale: Instances and Chunks](https://github.com/OneLiteFeatherNET/Falco/wiki/Rationale-Instances-And-Chunks).

## What "high-performance" means here

Measured, not asserted. Every figure comes from a JMH benchmark in this repository and is quoted
Expand Down
Loading
Loading