Book Creator & Shelf Area Filling Module + Library [Open Sourced] FREE

I would like to share this library of books I assembled to procedurally fill a book shelf area with books, for my furniture library.
image


image
To do this the books are organized into 3 categories, groups of books, stacks of books and individual books…
Individual books are labeled with a title and an attribute string called Author. and book synopsis called “examine”.
image
image
image
Included in this example is my implementation of a wikipedia lookup system to interact with the books this is the complete source code that formats the books and organizes the book shelves.

local book = {}

local BookLibrary=script.BookLibrary.Value
local BookDirectory=workspace
local BookTypes=BookLibrary:GetChildren()
local BooksLib={}
for i,Bookdir in BookTypes do 
	BooksLib[i]=Bookdir:GetChildren()
end
BookTypes=BooksLib
local Bookarray = {}
for i, Bookdir in pairs(BookTypes) do
	for t, Book in pairs(Bookdir) do 
		table.insert(Bookarray, Book) -- book is guaranteed to be a MeshPart instance 
	end
end
--local Bookarray=BookLibrary.Books:GetChildren()
local BookGuide={["BlankShelf"]={math.rad(-180),"X","Z"},["Books"]={math.rad(-90),"Z","X"},["BlankStack"]={math.rad(-180),"X","Z"}}

function book.GetBook(size)
	-- Create a table to hold books of equal or lesser size
	local suitableBooks = {}

	-- Iterate through the Bookarray to find suitable books
	
	for _, book in ipairs(Bookarray) do
		
		if BookGuide[book.Parent.Name] and book.Size[BookGuide[book.Parent.Name][2]]<= size.X and book.Size.Y <= size.Y then
			table.insert(suitableBooks, book)
		end
	end

	-- If there are no suitable books, return nil
	if #suitableBooks == 0 then
		return nil
	end

	-- Return a random book from the suitableBooks table
	return suitableBooks[math.random(#suitableBooks)]
end
function book.shelf(platform)
	local limit = platform.Size.X
	local start = platform.CFrame:ToWorldSpace( CFrame.new(-limit / 2, -platform.Size.Y / 2, platform.Size.Z / 2) )-- back top of platform
	local currentX = 0

	while currentX < limit do
		local v = book.GetBook(Vector3.new(limit - currentX,platform.Size.Y,0))
		local slot
		if not v then
			break -- No suitable book found, exit the loop
		else 
			slot=BookGuide[v.Parent.Name]
			v=v:Clone()
		
		end

		-- Position the book on the shelf
		
		currentX = currentX + v.Size[slot[2]]/2
		
		v.CFrame = start :ToWorldSpace(CFrame.new(currentX, v.Size.Y / 2, -v.Size[slot[3]] / 2)) * CFrame.Angles(0, slot[1], 0) -- align books with back top of platform
		currentX = currentX + v.Size[slot[2]]/2

		-- Update the current position on the shelf
		-- Parent the book to the platform
		v.Parent = BookDirectory
	end
end


function book.VerticalText(frame, referenceLabel, text)
	-- Clear any existing children in the frame
	frame:ClearAllChildren()

	-- Calculate the spacing between each character
	local spacing = 1 / #text
	local labelYscale=spacing
	

	-- Loop through each character in the text
	for i = 1, #text do
		-- Clone the reference text label
		local newLabel = referenceLabel:Clone()

		-- Set the text of the new label to the current character
		newLabel.Text = text:sub(i, i)
		newLabel.Size = UDim2.new(1, 0, spacing, 0)
		-- Position the new label vertically within the frame
		newLabel.Position = UDim2.new(0, 0, (i - 1) * spacing, 0)

		-- Parent the new label to the frame
		newLabel.Parent = frame
	end
end


function book.Render(object)
		local cover=object:FindFirstChild("Cover") or script.Cover:Clone()
		local spine=object:FindFirstChild("Spine") or script.Spine:Clone()
		local back=object:FindFirstChild("Back") or script.Back:Clone()
		
		cover.Author.Text=object:GetAttribute("Author") or ""		
		cover.Title.Text=object.Name
		--spine.Title.Text=object.Name
		book.VerticalText(spine.Frame, cover.Title, object.Name)
		back.Description.Text=object:GetAttribute("examine") or ""
		back.Author.Text=cover.Author.Text
		
		back.Parent=object
		back.Adornee=object
		
		cover.Parent=object
		cover.Adornee=object
		
		spine.Parent=object
		spine.Adornee=object		
end
function book.Reset(object)
		local cover=object:FindFirstChild("Cover")-- or script.Cover:Clone()
		local spine=object:FindFirstChild("Spine")-- or script.Spine:Clone()
		local back=object:FindFirstChild("Back")
		if cover and spine and back then
			cover:Destroy() spine:Destroy() back:Destroy()
		end

end
function book.Format(Library)
	for i,object in Library:GetChildren() do 
		book.Render(object)
	end
end

return book

This is a model that features the module and the book library as well as an example book shelf, the instructions are to put the Module in ReplicatedStorage to run the example. configure to your liking. Let me know what you think of this and leave a like if you enjoy this resource.
Book Library - Creator Store (roblox.com)

Some of the features are:

  1. You can create your own book model with a cover, spine and back. By using the book.Render function you can render your preconfigured book model with a generated template.
  2. Using the book.shelf function you can fill a bookshelf with books. This does this by taking a part and occupying the space of the shelf then the algorithm generates a random book shelf every time! This is demonstrated in the Furniture model featuring the bookshelf. Notice how the book shelf front orientation is the same as a standard part instance so respect orientation when placing book shelves!

An idea is that perhaps you want to add more things to shelves? Why does it have to be books? It can be anything!

If you like this you can check out my other open source projects at these links!
Day Night Weather Cycle - Lighting & Terrain Shader Algorithm + Artificial Sun - Clean Efficient [Open-Source] - Resources / Community Resources - Developer Forum | Roblox

19 Likes

back with another banger i see, great job on this one, I think I have an immediate use case for it

3 Likes

Thanks! I’m glad you like it. I appreciate the feedback!

1 Like

Roblox library of babel moment.

1 Like

Oh for sure! You could definitely make a library of babel. The titles I selected are all ancient texts on things relating to magic, paganism and ancient medicine, it’s for a medieval style RPG I’m working on. With the bot processor I just query wikipedia for the book summary and present it as a message. An api such an open book could be used to dynamically create a library of titles or search for a certain title.

1 Like