Block / genes
Equine Research Shelf
A bookshelf that files research papers — one of each gene — and copies any of them onto blank books for as long as the original stays in it. It is what turns knowing a gene into owning it.
What it does
Recipe (shapeless): 1 bookshelf + 2 horse hair.
Right-click it and you get two tabs.
- Store — opens first, and it is a chest: six rows of nine slots for research papers. Put a paper in, take it out, whenever you like — nothing takes time and nothing is used up. Shift-clicking a paper from your inventory files it. A shelf holds one paper per gene, so a second paper for a gene that is already there will not go in.
- Copy — pick a gene from the papers on the shelf and put blank
books in. It works like a furnace: each book becomes a copy of that
gene’s paper in the result slot, one after another, whether or not you have the
shelf open - set it going and walk away. Copies of the same gene stack. The
shelf’s own paper is never used up.
A copy takes time — one iron ingot’s smelt per rarity tier, so about ten seconds for a common gene and about a minute for a mythic one. The arrow between the slots fills as it goes. Running out of books, picking a different gene, or taking the original off the shelf starts the clock again rather than pausing it.
The shelf opens on whichever tab you used last.
The Copy list is what is on the shelf, not your gene database. Take the original out of its slot and that gene leaves the list, and the shelf can no longer copy it. That is the whole point: a shelf you have filled is a collection that exists in the world, and it can be emptied.
Breaking it gives everything back — the block and every paper on it drop together, the way a chest does. Moving a shelf costs nothing.
Where the papers come from
The shelf makes papers plentiful; it does not make them appear. The ways in are on Research papers, and the one that pairs with this is a book on a horse: right-click a horse holding a book and you get a paper for one gene that horse carries, chosen at random. You cannot pick, which is what makes a paper something you found.
So the loop is: meet horses, take what they will tell you, file it, and copy it from then on. A gene you have filed is a gene you can hand to somebody else as often as you like — which is what makes knowledge shareable rather than hoardable.
Real slots, one paper per gene
EquineResearchShelfBlockEntity holds a 54-slot container
(SLOTS, a double chest) saved with ContainerHelper. It was a
Set<String> of gene keys fed through one filing slot and read back
through a clickable list; in play that read as a shelf that did nothing, and the owner
asked for it to be “just a UI like a chest” (2026-09-10). The one-per-gene
rule the set used to make structural is now a slot rule:
PaperSlot.mayPlace refuses a paper whose gene another slot already holds,
and every slot takes one item.
Breaking it drops the contents from the block entity’s
preRemoveSideEffects, where vanilla’s chests do it. The old
shelf dropped from the block’s affectNeighborsAfterRemoval, which
runs after the block entity is already gone — so as far as the code shows, breaking
a filled shelf used to lose the lot.
Two tabs, one set of slots each
ResearchShelfMenu has the 54 paper slots (Store) and a book slot and a
result slot (Copy). Which are live is the tab, through Slot.isActive()
rather than moving them: Slot.x and Slot.y are final, and
isActive() is what vanilla consults for drawing and hit-testing.
The tab is only known on the client, so on the server every slot is live — the
client never sends a click on a slot it is not drawing.
Because the papers are real slots the ordinary container sync carries them, and the
Copy list is read from those slots on both sides (genesIn). The only
packet left is ShelfActionPayload’s gene pick; the old
ShelfSyncPayload and the withdraw action are gone.
The copy runs on the block, like a furnace
The book slot, the result slot, the picked gene and the progress all live on
EquineResearchShelfBlockEntity, and its ticker advances them whoever is
looking. The menu only wraps them - its slots are the block’s containers and its
progress bar reads the block’s ContainerData, the furnace’s
dataAccess pattern. The copy used to live on the menu, which only exists
while a player has the screen open, so it stopped the moment they clicked off
(owner-reported 2026-09-10). A finished copy spends one book; the pick reaches the
client as an index into the Copy list (DATA_SELECTED), since a
ContainerData can only carry ints.
Its labels are window-relative. AbstractContainerScreen
translates to (leftPos, topPos) before calling extractLabels,
and the shelf used to add them again, which threw the title and the inventory label off
the window. The last tab is a static on the screen, so it holds for the session.