Encyclopaedia / Bestiary Framework

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Message
Author
Human Bolt Diary
Regular
Posts: 97
Joined: Fri Oct 11, 2013 12:46 am
Contact:

Encyclopaedia / Bestiary Framework

#1 Post by Human Bolt Diary » Tue Feb 11, 2014 8:37 pm

Update: 11/25/2017

In response to a lot of the difficulties people were having, I've been working on a version 2 of the Encyclopaedia Framework. I've kept most of the core concepts similar, but this is a hard break for quite a bit of the behaviour. Overall, it should be much more user-friendly and easier to customize.

The beta for v2 is available at:
https://github.com/jsfehler/renpy-encyc ... a/releases

and documentation at:
http://renpy-encyclopaedia.readthedocs. ... index.html

Getting v2 out of beta is going to take a lot more manual testing (I've tested it a lot, but I'm sure there's things I've missed.), more work on the documentation, and more unit tests.

The information below is outdated, but kept for archival purposes:

The following is a prototype for an Encyclopaedia and/or Bestiary. I've done my best to split up the data management and screens, but using and customizing this will still require a tiny bit of python knowledge. My knowledge of screen language isn't that advanced, but nothing in the layout outright explodes.

While I've tried to be rigorous in finding outright bugs, a lot of the logic I've used to get everything working may not ultimately be the best way to go about it, or just simply sort of clunky. I hope that posting it here will invite people to try it out, break it apart, and report on their results.

That said, everything's working fine on my end and I hope it works on yours.

Features:
-Sorting entries by Entry Number, A to Z, Z to A, or by Subject
-Entries can have multiple pages
-An Image can be displayed next to an entry, or not
-Lock entries, then Unlock them over the course of the game
-Unread Entries are tagged.
-Locked entries can be displayed as "???" or outright hidden
-Access from the main menu or during gameplay

Update 10/26/2014:
-Major code refactoring under the hood.
-Flags for status can be generated dynamically.

Update 3/13/2014:
-Bug Fix: Can now start an Encyclopaedia in Z to A sorting
-Screens simplified and rearranged a bit
-An Entry/Sub-Entry's Text can now be single string or list of strings. (Useful to make paragraphs.)
-Tweaks in how entry_text variable is processed to support paragraphs
-Encyclopaedia "showLocked" variable renamed "showLockedButtons"
-Encyclopaedia "showLockedEntry" variable added. Determines if locked entry pages can be viewed or not.
(showLockedButtons and showLockedEntry are independent and compatible, but personally, the user experience will be weird if showLockedEntry but not showLockedButtons)
-Viewable Locked entry page shows generic name and text. Can be modified (Default is "???" in both cases)
-Viewable Locked entry page shows tinted image. Tint amount can be changed or the locked image can be an entirely different image.
-Demo project and attached files below updated

Update 2/20/2014:
-Multiple encyclopaedias can now be created in the same project
-Refactored code, fixed notes, should be more user friendly now
-Fixed bug involving sub-page number not resetting
-Fixed bug involving entries not sorting into the correct subject when hiding locked entries
-"new!" status is restored when an entry gets a new sub-entry
-Added show/hide locked entries button
-Percentage of the Encyclopaedia unlocked can be displayed now
-Demo project and attached files below updated

I've included a demo game to show everything in action. The user experience suffers a bit to show off everything, but this also helps ensure no feature bugs out another when used. The Encyclopaedia can be accessed from the Main Menu or via button in-game.

To use the Encyclopaedia in your project, drop encyclopaedia.rpy into your project's game folder. Refer to the included enc_data.rpy and script.rpy to see how entries and the screens are created.

Limitations:
-The Encyclopaedia uses Persistent Data to save the Unread and Locked flags. Regardless of save game, once it's open and read, that's it.
-Read entries only save their status after exiting the Encyclopaedia. If the program is closed before exiting, the Unread status returns.
-Exiting the Encyclopaedia sets the sorting to by number. This is necessary to make sure the Unread flags save correctly.

Basic Usage example:

Code: Select all

init python:
 e = Encyclopaedia()
 e.addSubjects("Subject 1", "Subject 2", "Etc")
 
 entry1 = EncEntry (number=1, name="Title", text="Entry Text", subject="Subject 1", status=False, locked=False, image= "directory/image.jpg")

 e.addEntry(entry1)
Classes:
Encyclopaedia(sortingMode = "Number", showLockedButtons=False, showLockedEntry=False)
Holds entry objects and organizes how they're displayed.
sortingMode - Determines which type of sorting is used when an Encyclopaedia is first opened. Can be "Number", "A to Z", "Z to A", "Subject".
showLockedButtons - If True, the buttons for locked entries will be visible in the entry list.
showLockedEntry - if True, locked entries will be viewable. Locked entries, even when viewed, hide data from the player.

EncEntry(number=0, name="Entry Name", text="Entry Text", subject=None, status=None, locked=False, image=None, locked_image=None)
Holds the data for an individual entry.
number - The entry's number in an Encyclopaedia's list. Used for sorting.
name - The title of an entry. Must be a string.
text - The text of an entry. Can be a string or a list of strings.
subject - An entry's subject. Used for sorting by subject.
status - If None or False, Entry is considered to have not been viewed. If viewed/unviewed status is shown to player, must be persistent variable that is a Boolean or status will reset every time the project is started.
locked - If not False, must be a persistent variable that is a Boolean or else entry will lock every time the project is started.
image - Image associated with entry.
locked_image - Image to be displayed if entry is locked and locked entries are viewable. If None, will be a tinted version of image.
Last edited by Human Bolt Diary on Sat Nov 25, 2017 9:18 pm, edited 4 times in total.

Coyotl
Regular
Posts: 27
Joined: Wed Jan 29, 2014 5:36 pm
Contact:

Re: Encyclopaedia / Bestiary Framework (Functional Prototype

#2 Post by Coyotl » Mon Mar 03, 2014 6:00 am

Thanks for working on this! It's something I was putting off until much later in development. I'm sure this will help tremendously, and I'll be following your work closely.

Human Bolt Diary
Regular
Posts: 97
Joined: Fri Oct 11, 2013 12:46 am
Contact:

Re: Encyclopaedia / Bestiary Framework

#3 Post by Human Bolt Diary » Fri Mar 14, 2014 1:30 pm

Coyotl wrote:Thanks for working on this! It's something I was putting off until much later in development. I'm sure this will help tremendously, and I'll be following your work closely.
Thanks, I hope you find it useful.

The latest version is "feature complete" since I can't think of much more to add, but if there's any options not included that you're interested in I can look into adding it.

Human Bolt Diary
Regular
Posts: 97
Joined: Fri Oct 11, 2013 12:46 am
Contact:

Re: Encyclopaedia / Bestiary Framework

#4 Post by Human Bolt Diary » Sun Oct 26, 2014 6:21 pm

I've updated the files to a new version. The code's been rewritten a bit but should retain full compatibility with the older versions. It's mostly just cleaning up based on my increased Python knowledge. The biggest change is that the flags for the "New!" status can be generated dynamically.

The older version used a pretty gross way to make those flags:

Code: Select all

try:
  persistent.enc00_new = persistent.new_dict["new_00"]
  persistent.enc01_new = persistent.new_dict["new_01"]
  persistent.enc02_new = persistent.new_dict["new_02"]
  persistent.enc03_new = persistent.new_dict["new_03"]
  persistent.enc04_new = persistent.new_dict["new_04"]
  persistent.enc05_new = persistent.new_dict["new_05"]
  persistent.enc06_new = persistent.new_dict["new_06"]
  persistent.enc07_new = persistent.new_dict["new_07"]
 except TypeError:
  pass
 
 #The keys must all have a prefix+number. "new_0" and "number" in this case.
 persistent.new_dict = {
 "new_00" : persistent.enc00_new,
 "new_01" : persistent.enc01_new,
 "new_02" : persistent.enc02_new,
 "new_03" : persistent.enc03_new,
 "new_04" : persistent.enc04_new,
 "new_05" : persistent.enc05_new,
 "new_06" : persistent.enc06_new,
 "new_07" : persistent.enc07_new
 }
Exploiting persistent data is still the way it works, but having to declare each flag is going to be painful if an Encyclopaedia has dozens or hundreds of entries. Now, that's all been stuck under the hood. All you need to do is state how many entries there will be:

Code: Select all

encyclopaedia.setPersistentStatus(entries_total=7, master_key="new", name="new")

User avatar
yon
Regular
Posts: 79
Joined: Tue Sep 09, 2014 5:09 pm
Projects: YDSP
Organization: Acid Sugar Games
Skype: You'll have to ask me privately.
Location: California, United States
Contact:

Re: Encyclopaedia / Bestiary Framework

#5 Post by yon » Mon Oct 27, 2014 3:56 pm

I just checked out the new .rpy file, and wow. You really reworked this whole thing. I'll probably need a little while to re-familiarize myself with it, but I've got a good feeling about this update.

User avatar
yon
Regular
Posts: 79
Joined: Tue Sep 09, 2014 5:09 pm
Projects: YDSP
Organization: Acid Sugar Games
Skype: You'll have to ask me privately.
Location: California, United States
Contact:

Re: Encyclopaedia / Bestiary Framework

#6 Post by yon » Sun Nov 02, 2014 6:49 pm

Could you post a zip file with the whole thing, actually? I remember there being one before, for 1.3 and 1.4, but I don't seen anything like that now. Am I missing something?
I tried to make a copy of one of the previous projects and overwrite the old files with the new attachments, but it doesn't seem to work if I try that.

User avatar
Meinos Kaen
Regular
Posts: 104
Joined: Wed Jan 04, 2012 1:01 pm
Skype: therealmeinoskaen
Location: Somewhere in Italy...
Contact:

Re: Encyclopaedia / Bestiary Framework

#7 Post by Meinos Kaen » Tue Feb 10, 2015 2:11 pm

Oh my god, thank you thank you thank you for this. Not only does it work wonderfully and can add more dept to games rich of lore, but it also solved another unrelated problem for me.

User avatar
Luxliev
Veteran
Posts: 242
Joined: Sat Feb 07, 2015 11:01 am
Soundcloud: Luxliev
Contact:

Re: Encyclopaedia / Bestiary Framework

#8 Post by Luxliev » Wed Feb 18, 2015 7:56 am

That's great piece of code thanks for it. Please keep it updated I also have one question can you update already read entries? fe.

entry one = You met this guy at park.

later in game you get update

entry one (updated) = This guy name is John I met him at park first.

User avatar
Laiska
Veteran
Posts: 323
Joined: Sat Jan 11, 2014 1:14 am
Completed: Queen At Arms, Cerulean, The Shadows That Run Alongside Our Car, Vicarwissen
Projects: Caramel Mokaccino
Tumblr: minesweeperaddict
Deviantart: koyoba
Contact:

Re: Encyclopaedia / Bestiary Framework

#9 Post by Laiska » Sat Apr 18, 2015 12:40 pm

Luxliev wrote:That's great piece of code thanks for it. Please keep it updated I also have one question can you update already read entries? fe.

entry one = You met this guy at park.

later in game you get update

entry one (updated) = This guy name is John I met him at park first.
I'm curious about this as well - anyone?

Also the demo script doesn't run properly because it doesn't include the images =P

Human Bolt Diary
Regular
Posts: 97
Joined: Fri Oct 11, 2013 12:46 am
Contact:

Re: Encyclopaedia / Bestiary Framework

#10 Post by Human Bolt Diary » Tue Apr 21, 2015 10:08 pm

Off the top of my head, if you create the entry data in an init block, it'll get set each time the game starts. If you create the entry data outside, it should save if you update it. So you could do something like:

Code: Select all


a_entry = "Blah blah blah"

a "Hamburgers? Love 'em."

python:
    a_entry = "Blah blah blah. Loves hamburgers."


However, creating the entry data outside an init block may cause bugs if you want to be able to open the encyclopaedia from the main menu. Now that I think about it, I haven't tested what happens if you try to open an Encyclopaedia that has zero entries. If it crashes, I could probably fix it over a weekend.
Laiska wrote:
Luxliev wrote:That's great piece of code thanks for it. Please keep it updated I also have one question can you update already read entries? fe.

entry one = You met this guy at park.

later in game you get update

entry one (updated) = This guy name is John I met him at park first.
I'm curious about this as well - anyone?

Also the demo script doesn't run properly because it doesn't include the images =P

LabaroDD
Regular
Posts: 34
Joined: Thu Apr 14, 2016 7:47 am
Contact:

Re: Encyclopaedia / Bestiary Framework

#11 Post by LabaroDD » Wed May 11, 2016 6:28 pm

Hello there!
I have a question about using this awesome encyclopaedia - how can I customize it? I'm pretty newbie in coding and I just can't get how I should to change the text style, I mean, size, color, etc. I tried to use init python to create a style of encyclopaedia_list, but there were no changes. Sorry, I'm so stupid ><
I really, really need help.

User avatar
Otoke_Neko
Regular
Posts: 27
Joined: Mon May 09, 2016 8:08 pm
Projects: Memories Reborn, Hetalia Otome
Tumblr: OTOJANG!, Otoke Neko
Deviantart: OtomeNekos
Contact:

Re: Encyclopaedia / Bestiary Framework

#12 Post by Otoke_Neko » Thu Jun 16, 2016 12:27 pm

LabaroDD wrote:Hello there!
I have a question about using this awesome encyclopaedia - how can I customize it? I'm pretty newbie in coding and I just can't get how I should to change the text style, I mean, size, color, etc. I tried to use init python to create a style of encyclopaedia_list, but there were no changes. Sorry, I'm so stupid ><
I really, really need help.
Try doing this: "{color=hexcode} text {/color}
Of course, I didn't use the encyclopedia in this topic, but it'll probably still work.
I'm currently working on:
Eterna: Memories Reborn(HIATUS)
Hetalia Memoirs
Visit the group website! https://otojang.weebly.com/

tictactofu
Newbie
Posts: 1
Joined: Fri Sep 02, 2016 3:16 pm
Contact:

Re: Encyclopaedia / Bestiary Framework

#13 Post by tictactofu » Fri Sep 02, 2016 3:48 pm

This is exactly what I was looking for - thank you!

Is there a way to make dialogue function as a button to pull up the encyclopaedia? Like, to make it so that if a character says "Hi, my name is John," you can press John to open his entry. Been fussing with it for a while, but I know nothing and have gotten nowhere :?

User avatar
noeinan
Eileen-Class Veteran
Posts: 1080
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: daikiraikimi
Github: daikiraikimi
Location: Washington State, USA
Contact:

Re: Encyclopaedia / Bestiary Framework

#14 Post by noeinan » Fri Jan 27, 2017 4:58 am

tictactofu wrote:This is exactly what I was looking for - thank you!

Is there a way to make dialogue function as a button to pull up the encyclopaedia? Like, to make it so that if a character says "Hi, my name is John," you can press John to open his entry. Been fussing with it for a while, but I know nothing and have gotten nowhere :?
I do not know much about this, but I would guess maybe making a post in the main questions section of the forum, and ask like... "how to turn a word in dialogue into a button"

On a separate note, I really appreciate this code and have been keeping a copy in my resources file in case I ever needed it. Recently, I started making a game where I have need of an encyclopedia, but I wanted to make it so that sub-entries could have a slightly different picture.

I am having a really hard time finding in the code why the image doesn't change when you click to the next sub-entry page. I added an image to where I've defined the sub-entry:

Code: Select all

    #When creating sub-entries, the main entry is considered page 1, always start at 2
    en1_2 = EncEntry(2,"Crown Flower",lorem2,"Herb Identification", locked=False, image=en1_2_image)
But when you click for the next page, the image stays the same. I haven't been able to figure out how to make it change. I can find where the image appears on the screen:

Code: Select all

if encyclopaedia.getEntryData()[1].hasImage: #If the entry or sub-entry has an image, add it to the screen  
But the image changes for regular entries and not sub-entries. I tried copying parts of the ChangeEntryAction into the ChangePageAction, but even if I changed the variable names to match sub-entry, all that did is make the Next Page button change the entry instead...

Code: Select all

    class ChangeEntryAction(EncyclopaediaEntryAction):
        """  
        Scroll through the current entry being viewed. 
        Used by Encyclopaedia's PreviousEntry and NextEntry functions
        """    
        def __init__(self, encyclopaedia, direction, block,*args,**kwargs):  
            self.enc = encyclopaedia
            self.block = block #If the button is active or not
            self.dir = direction  #Determines if it's going to the previous or next entry 
  
        def __call__(self):
            if self.block == False:
                self.enc.setEntryData(self.enc.current_position+self.dir)
 
                if self.enc.showLockedEntry == False:
                    self.enc.unlocked_entries[self.enc.current_position+self.dir][1].status = True 
                    given_text = self.enc.unlocked_entries[self.enc.current_position + self.dir][1].getText()
    
                else: 
                    self.enc.all_entries[self.enc.current_position+self.dir][1].status = True   
                    given_text = self.enc.all_entries[self.enc.current_position + self.dir][1].getText()
 
                self.enc.entry_text = self.string_to_list(given_text)
    
                self.enc.current_position += self.dir
      
                self.enc.sub_current_position = 1 #When changing an entry, the sub-entry page number is set back to 1
                renpy.restart_interaction()
    
        def get_sensitive(self):
            if self.block:
                return False
            return True 
 

    class ChangePageAction(ChangeEntryAction):
        """Change the current sub-entry being viewed."""        
        def __init__(self, encyclopaedia, direction, direction2, block,*args,**kwargs):
            super(ChangePageAction,self).__init__(encyclopaedia, direction, block,*args,**kwargs)

            self.dir1 = direction
            self.dir2 = direction2

        def __call__(self):
            if self.block == False: 
                given_text = self.enc.getUnlockedEntry(self.enc.current_position).getSubEntry(self.enc.sub_current_position + self.dir1)
   
                self.enc.entry_text = self.string_to_list(given_text)
                
                self.enc.sub_current_position += self.dir2
    
                renpy.restart_interaction()
As far as I can tell, both entries and sub-entries fall under the class EncEntry, so there shouldn't be any difference between how they are displayed/which ones show a picture and which don't. Or at least I can't find the code that controls this. Any advice on this would be much appreciated!
Image

Image
Image

LabaroDD
Regular
Posts: 34
Joined: Thu Apr 14, 2016 7:47 am
Contact:

Re: Encyclopaedia / Bestiary Framework

#15 Post by LabaroDD » Sun Jan 29, 2017 7:34 pm

Here is the way to disable sorting?

UPD
Ah, I found it myself! ^^"
Last edited by LabaroDD on Sun Jan 29, 2017 9:24 pm, edited 1 time in total.

Post Reply

Who is online

Users browsing this forum: No registered users