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.

Taking a paper back stops the copying

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.

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.