The Haunted Library Part 4: Custom Books, Inventories, and Trades

Step 1
Inventories for days

In this lesson, we will be learning how to add items to a block with an inventory, like a chest, as well as how to create a custom inventory and open it.

We will also make custom written books, with a title, author, and pages.

And finally, we will learn how to spawn custom villagers and make custom trades.

Step 2
Organizing your code

Now is a great time to reorganize your code. It will make it much easier to follow the lesson steps.

Read about the different sections below and cut and paste your variables and functions to be in the correct section.

Step 3
Create a custom book

Custom books work exactly like custom items, except instead of displayName, you have title and author.

Step 4
Make a function to see your book

We could create a custom crafting recipe to make our book the way we usually do with custom items, but we can also make an export function that uses world.dropItem() to give it to us instead.

Check Your Work
Step 5
Test out the diary

Save, deploy, reload, and call /js testBook()

Step 6
Add some pages to the book

Just like lore on custom items, the pages property should be an array ([ ]) of strings (" "). You can copy the code below, or write your own diary pages. Just make sure that you page that tells the reader that some pages are missing.

The \n stands for "new line" and is like pressing "enter" on your keyboard

diaryMeta.pages = [
    "My Diary \n\n\nby\n\n\nMelvil the Librarian",
    "Dear Diary,\n\nToday I found a strange secret passage in the library!\n\nWhen I went down in it, I found a secret room, furnished with everything a librarian like myself could need.",
    "But strangely, just as I entered this new room, the passage sealed behind me!\n\nOh well, time to do some reading!",
    "\n\n   [ Some pages are missing. . . ]",
    "Will I ever escape this room? \n\n I have read and alphabetized every book here!"
Check Your Work
Step 7
Test out your pages

Save, deploy, reload and call /js testBook() again to get a new copy of the diary, this time with pages!

Step 8
Make clicking the enchanting table give players the diary

We will add this code the the playerInteract event function. It checks if the block that was clicked is that same one as the block that is at the enchanting table's location, and then uses inventory.setItem to put the diary in the player's inventory.

Check Your Work
Step 9
Click the enchanting table

Save, deploy, reload, go down to the secret basement and click the enchanting table. You should get the diary in the first slot of your inventory.


You may need to uncomment the line in your exports.secretPassage function to be able to get to the basement.

Step 10
Make the missing pages!

Your challenge is to make another custom book! Here is the info you need:

  • Title: "The Missing Pages"
  • Author: "Melvil the Librarian"
  • The pages need to have the following infromation:
    1. Melvil is getting very hungry.
    2. He wishes he could get those cookies that are in a chest under his desk upstairs
    3. He has looked everywhere for a way out, except the darkest corner of the room, because it is full of cobwebs
Step 11
Give the player the missing pages

We will use a different event, entityDamageByEntity, to detect when the player hits the skeleton librarian. Make sure the custom name matches the one you gave the skeleton in the spawnLibrarianSkeleton function.

Check Your Work
Step 12
Test out the missing pages

Save, deploy, reload, and hit the skeleton in the basement. You should get "The Missing Pages" in your second item slot, and the skeleton should not take damage.

Step 13
Add a sound and message

To make sure the player notices that they have the missing pages now, add a sound and echo.

Step 14
Find a location for the hidden pressure plate

Next, we are going to hide a pressure plate in the cob webs that lets players back out of the secret basement.

Head into the cobwebs to find the darkest corner, and place a block there to find the location.

Step 15
Save the pressure plate location

Add a new property to library.secretRoom called pressurePlate, and make it an object with a property called loc, which is the location you found in the last step.

Step 16
Make a method to place the pressure plate
Step 17
Place the pressure plate when the player finds the missing pages
Check Your Work
Step 18
Check out the pressure plate.

After you save, deploy, and reload, hit the skeleton to make the pressure plate get placed.

I added a torch here to make sure you can see it, but we want it to be dark in the end.

Step 19
Make the pressure plate open the secret passage

Stepping on a pressure plate is slightly different from pressing a button or a lever. The event.action is called "PHYSICAL". Write an else if statement for this different type of action, and make it open the passage and spawn ghost Melvil.

Step 20
Find the location for the secret chest under the librarian's desk
Step 21
Save the chest location in the library object
Step 22
Make a method to fill the chest with cookies
Step 23
Test your cookie filling method
Check Your Work
Step 24
Call /js testInventory()
Step 25
Optional Challenge: Fill the chest in the secret room

The chest in the secret room is a decoy, and doesn't contain any real clues for the players. Use the same method that we did above to fill it with some random items.

  1. Save the location of the chest as a property of your library.secretRoom object.
  2. Make a method to fill the chest
  3. Define a variable called chestContents that is equal to the block at that location's state
  4. Add items to the inventory using setItem.


chestContents.setItem(13, items.rawFish(1))

Then, call your method in the testInventory export function to see items show up in the chest!

Step 26
Make a method to fill the filing cabinet with office supplies

Next we will create a method to fill the dropper that is our filing cabinet with office supplies.

This for loop goes through the array called officeSupplies and adds each item. The i%4 makes it start back at 0 each time it gets to 4.

Check Your Work
Step 27
Call /js testInventory()

Make sure you are calling your library.filingCabinet.fill() method in the testInventory export method. Then save, deploy, reload, and test it out.

Step 28
Create a custom inventory

Our Restricted Shelf is going to be a custom inventory, that does not open with a block with an inventory, like a chest or dropper, but instead by clicking a particular shelf.

Here, we use bukkit.createInventory, with three inputs:

  • null means that it does not belong to a particular player, so that anyone can access it.
  • 18 is the size. It has to be a multiple of 9. We picked 18 because a bookshelf block looks like it has two shelves, and 18 will make a two-row inventory.
  • "The Restricted Bookshelf" is the name of the inventory.
Step 29
Open the Restricted Shelf

We have already saved a location for the Restricted Section, so All we need to do now is add another if statement for when the player clicks that block that calls openInventory.

Check Your Work
Step 30
Save, deploy, reload, and click the Restricted Section bookshelf
Step 31
Add some items to the Restricted Shelf inventory

These items are just examples. You can add regular items, and create custom items without a crafting recipe.

Later, we will use a loop to fill the inventory with items just like we did with the office supplies.

Check Your Work
Step 32
Save, deploy, reload, and click the shelf to open the inventory again.
Step 33
Create another custom written book

Create a custom book called "The Secrets of the Library" to add to the Restricted Section.


You can copy the pages below, or write your own!

secretsMeta.pages = [
    "The Secrets of the Library\n\n\nby\n\nMelvil the Librarian",
    "This library holds many secrets, and as the head librarian, I have been able to uncover many of them.",
    "Some secrets, however, continue to elude me... I have heard tales of a secret passage in one of these bookcases",
    "But have never seen the evidence with my own eyes. The pursuit of knowledge is my only goal! And not know about this is driving me crazy",
    "An old colleague of mine suggested, once, that only the authors whose works are hidden away in the Restricted Section have been able to find this elusive passage",
    "So I have put pen to paper myself to write this very book, and enter it into the Restricted Shelves. Now we will see what this library reveals to me!"
Step 34
Fill the rest of the Restricted Bookshelf!

Just like with the filing cabinet, us a for loop to fill each slot in the inventory with items from an array. This time, instead of just going through the list, we will use Math.random() and Math.floor() to get a random decimal between 0 and 1, multiply it by the number of items in creepy items, and then round that down to a whole number with no decimals.


Make sure you add "The Secrets of the Library" to the inventory AFTER the loop, so that it replaces one of those items!

Check Your Work
Step 35
Test the Restricted Bookshelf
Step 36
Create a function to handle the Inventory Click Event

This event will fire each time someone clicks any inventory, including their own.

Step 37
Keep players from being able to take the items

We only want players to be able to take "The Secrets of the Library" out of the Restricted Section. So unless they are going for that slot, we will cancel the event, and make a horrible screaming noise like an injured ghast.

Check Your Work
Step 38
Try to take something out of the restricted section

Save, deploy, reload, open the Restricted Bookshelf, and try to take anything out besides The Secrets of the Library. You should hear a horrible noise and not be able to pick up the item.

Step 39
Make it possible to add a book back in

When you take an item out of an inventory, the event.currentItem is actually air. We will add two more conditions to our if statement so that we can pick up a written book and place it in the slot.

Step 40
Make writing a book reveal the lever.

The playerEditBook event fires whenever a player signs a book. We will use this event to make the lever show up once you have written a book. Players won't be forced to put that book in the Restricted Section, but they should be able to.

Check Your Work
Step 41
Test out the lever

Save, deploy, reload, and get out a book and quill. Give your book a brief message, a title, and sign it.

You should hear lightning striking, and see the lever for the secret passage revealed.

Step 42
Custom Villagers

We have seen Melvil's skeleton, but now we are going to make the ghost of Melvil the Librarian! We will learn how to:

  • spawn a villager
  • give a villager a custom profession (this decides what color their clothes will be)
  • create a custom villager trade
Step 43
Make a variable for the Professions module

All this really does is keep us from having to write org.bukkit.entity.Villager.Profession when we want to assign a profession to a villager.

Step 44
Make a function to spawn Melvil's Ghost

Note: Even though this is currently an export function, we will change that in the end, so put it under Helper Functions.

Check Your Work
Step 45
Spawn Melvil

Save, deploy, reload, and call /js spawnLibrarianGhost()

Step 46
Make Melvil ghostly

We are going to turn this villager into a ghost, by making it invisible, glowing, and floating two blocks above the ground.

Check Your Work
Step 47

Save, deploy, reload, and call /js spawnLibrarianGhost() again.

Step 48
Make a Trade variable
Step 49
Make a key to the library

Just like any custom item, we will make a key to the library. You can use a tripwire hook, or a different item.

Step 50
Create a custom trade

When you create a trade, you will use new Trade() with two inputs:

  • keyToTheLibrary is the item that the villager gives you
  • 1 is the number of times the villager can do this trade.

You use addIngredient to decide what a player has to give in the trade.

Finally, use setRecipes to make this the only trade the ghost has. You could list more trades in there if you wanted to make more of them.

Check Your Work
Step 51
Check out your trade

Save, deploy, reload, and spawn a new Ghost Melvil. He should have one trade, 10 cookies for the key to the library.

Step 52
Make Melvil spawn above his desk

Change the exports function back into a regular function, and create a location based on the desk's location.

Step 53
We finished all the custom books, trades, and inventories!

Congratulations, we have made all the elements that we will need for this Escape Room! In the final lesson, we will tie it all together, making these items, entities, and inventories appear as players solve the puzzle!

The Haunted Library Part 4: Custom Books, Inventories, and Trades Info


MVCode Clubs

Created By

Mandala2 slinkous


The Haunted Library

Access Level


For Teachers and Schools

Teach coding to your students with MVCode Teach

MVCode offers an integrated product designed to teach coding to students.

Learn more about MVCode Teach