Thursday, February 10, 2022

Procedural Bookcases

Here's a sampling of some of the procedural bookcases I'm generating for 3DWorld's building interiors. These are placed in many of the rooms of houses, and libraries in office buildings. Each bookcase has a unique collection of books that can be individually removed by the player, carried around, put down, and opened up.

A bookcase has between three and five shelves containing books. Most books have the spine facing out, and a few have it facing in. Books are occasionally tilted to lean on another book or laid flat on a shelf. I've also mixed in some gaps and completely empty shelves. Here are some examples.


 


 

Books come in random widths, heights, thicknesses, and colors. Their titles are randomly chosen from a list of 5000 popular book titles. I haven't yet been able to come up with a way to generate realistically sounding titles. Some books have authors listed under their titles on the front cover. Author names consist of a male or female first name randomly selected from a list of around 1000 each, plus a last name I generate using a sort of Markov chain approach that includes a list of vowel and consonant word parts. In addition, some books have cover images that are randomly selected from one of my other procedural generated 3DWorld screenshots show on my GitHub project page. Books can be opened, showing pages randomly selected from various papers around my house that I captured with my phone camera. Here are some of the books I happened to find in this house.


Some books I took off the shelves and arrayed out on the floor. Huh, the two open books have the same page image.

12 comments:

  1. Random thoughts;
    - Spine should sometimes include author name, although I understand if you want to avoid that to keep font size readable.
    - Shelf heights could vary a little, some shelving units will have the lower shelves being taller.
    - Should allow for books laying down to be stacked, especially if they're too tall for the shelf.
    - Some books could be created as sets with identical or similar style (size colour etc), for example encyclopaedia's or a fantasy series.
    - Shelves are missing bookends and assorted knick-knacks that end up getting mixed in with the books.

    ReplyDelete
    Replies
    1. Great, thanks for your feedback! I'll see if I can make some of these changes.

      Delete
    2. I added the author to some book spines, though they can be small and a bit hard to read. I made 50% of bookcases have taller shelves at the bottom than the top. I added some sets of same size/color books, but the titles and authors don't always go together well. Stacked books are more complex because they don't fit the current add-book-then-shift algorithm. I'll work on those later. I'm not sure what to do with bookends etc. - those may be difficult.

      Delete
  2. Very cool! Have you already rejected the Dwarf Fortress method of generating book titles? For book sets, you could write a script to browse Wikipedia for related topics.

    ReplyDelete
    Replies
    1. I don't know how Dwarf Fortress generates book titles. Is there some article that describes this?

      I have no idea how to write a script that browses Wikipedia. Are you suggesting this as a one time step, or something that 3DWorld does when it starts up? I don't have any of that sort of networking code and it seems like that would be significant work to add.

      I suppose I would need another name/title for the book *set*, but maybe the books in the set could be numbered rather than having their own unique per-book titles. That's more difficult because there's currently no way to pass the name of the set into the generation code. Right now the bookcases and book covers are generated earlier and the titles are only generated when the player gets close. I guess I could do some trickery with a random seed to make the title shared, though it's not clear where I can store the volume number.

      Delete
  3. DF has a template file which it fills in from in-world scholars, events, placenames, and discoveries, but the underlying structure might be adaptable. Here is a forum thread about the generation technique: http://www.bay12forums.com/smf/index.php?topic=169968.msg7715883

    A one-time step was what I had in mind. Here's some Wikipedia browsing Python code I wrote, which could be a good starting point:
    https://github.com/dudecon/python/blob/main/Rand_Wiki_Text.py
    Probably just faster to manually compile topics though.

    Yeah, you'd need to revise your generation code to handle sets properly. If I was doing it, I'd make one big "book" for the whole set that breaks into individual named volumes when the player proximity LOD gets called.

    ReplyDelete
    Replies
    1. The developers of DF go out of their way to generate and simulate everything in as much detail as possible with very complex systems. I'm not sure I want to go through that much trouble. Thanks for the links, I'll check these out later.

      Making the set of books into its own object fits with the 3DWorld object hierarchy: bookcase => book set => book. Unfortunately, it doesn't seem to work when the player takes a book from the set. Now the player has one random book from the set, and the set has a missing book. I'm back to having to store the set name + title/volume number for the book the player is holding. I also have to handle books missing from the set by tracking them with a bit mask but including the original set elements when assigning names. I already do that with bookcases, so I'm sure it works, but it's more complexity.

      Delete
    2. Makes sense. You could always just make the book "set" a mini single-shelf frameless bookshelf and re-use all your old code.

      Delete
    3. Recursively nested bookshelves is how I did this bookshelf generator:
      https://blenderartists.org/t/crazy-procgen-bookshelf-script/1295629

      Delete
    4. I'm not sure if making a mini single shelf frameless bookshelf would actually be any easier than other approaches I've considered, since it requires special casing various blocks of code. I think I can use the object_id as a random seed for generating the name of the set if it's the same for all books in the set. Then I can use one of the other flag bytes for the volume index, which allows for 256 books in the set. That should work.

      Your recursively nested bookshelves look like some of my generated room layouts. The difference is that I don't have an explicit pinwheel option. It's not something I ever considered since that's not very common for rooms. But the recursive slicing plane structure can likely create something like this accidentally. It might be a good idea to use this for some other types of furniture, for example bookshelves containing various sized non-book items.

      Delete
    5. Alright, I'm now tracking the index of the set and the volume index of each book within the set. This allows me to do things like have the same author for each book in the set (when shown), and add Roman numeral volume numbers to some sets. Also, books can be missing and will leave gaps in the numbers.

      Delete
    6. You can not get a pinwheel with full depth slices, as none of the divisions go all the way across.
      Cool to hear about the book sets!

      Delete