Quest Log

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.
Post Reply
Message
Author
jw2pfd
Regular
Posts: 87
Joined: Tue Sep 18, 2012 9:55 pm
Location: DFW, TX, USA
Contact:

Quest Log

#1 Post by jw2pfd » Fri Feb 14, 2014 2:04 am

I made this code for a Quest Log about six months ago for no specific project. It provides an organized way to do quests as well as quest tracking and display of the quest log. My code is not well-documented as of right now, but I can add more comments to my code and documentation in this thread if there is an interest in using my code. There are files for the class as well as a sample script that utilizes the class code. You can create a project and copy these four files into it and it can be launched.
  • script.rpy - main script file (example code)
  • quests.rpy - separate rpy file for the creation of the the quest log (example code)
  • questlog.rpy - class code (highly recommend not editing this code unless you are very certain of what you're doing)
  • qscreens.rpy - separate rpy file for the definition of screens that are necessary for the display of the quest log
There are four main objects in the class code to understand:
  • Quest Log - This contains quests as well as the names of the screens which will be used when handling the display of the quest log. Quests can be organized in tabs for display purposes. The 'qscreens.rpy' file contains example code for displaying the quest log. In my example code, the screen is named 'qlog'. This a good starting point and this can be altered as much as you want. There is important code though that handles switching between tabs and this will have to be preserved.
  • Quest - Quests contain goals which can be organized into stages. Quests are automatically marked completed once all of the goals are each marked completed in the script. If a quest has stages, then all goals in a stage need to be finished before moving on to the next stage. Quests can either be checkpoints or fetch quests where the goal is achieved by reaching a specific quantity.
  • Stage - Stages are a list of goals inside a quest. When a stage is completed by finishing all of the stage's goals, it will advance to the next stage. The next stage it will advance to can be manually set. This allows for branching quest lines.
  • Goal - A goal is a task waiting to be marked completed in the script when the user reaches a certain part of the code.
This is only scratching the surface to understanding the code. There is also other functionality I have included that I will explain and document at a later time perhaps. If you download all of the files and launch the project, then there are a total of four quest lines as example quests. In the 'quests.rpy' file, they are commented as Quest1, Quest2, Quest3, Quest4. In game, they are referred to as "Eileen's Quest", "Paul's Quest", "Mary's Quest", and "Peter's Quest".
  • Eileen's Quest is an example of having goals that are dependent upon other quests being completed.
  • Paul's Quest is testing an optional goal which allows for a branch in the quest line.
  • Mary's Quest is testing multiple stages with multiple goals.
  • Peter's Quest is for testing quantity/fetch quests.
I don't know if there is much interest for including a quest log like this in VNs. It's already achievable without a class, but would require using many variables as the log grows. This class mainly offers a more organized way to do it. It also offers a reasonable way to have multiple quest logs that are independent of each other which could be useful for a game that switches between the character you are playing. Each character could have their own line of quests.
Attachments
quests.rpy
example of creating a quest log
(3.71 KiB) Downloaded 983 times
questlog.rpy
class code
(21.67 KiB) Downloaded 888 times
qscreens.rpy
screen definitions for using the class
(3.57 KiB) Downloaded 857 times
script.rpy
main script file utilizing the class
(17.03 KiB) Downloaded 919 times

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Quest Log

#2 Post by xela » Sat Feb 15, 2014 8:41 pm

Looks really useful! Thanks for sharing :)
Like what we're doing? Support us at:
Image

User avatar
Karl_C
Veteran
Posts: 232
Joined: Sun Mar 31, 2013 6:18 am
Contact:

Re: Quest Log

#3 Post by Karl_C » Sun Feb 16, 2014 5:11 pm

jw2pfd wrote:
  • Eileen's Quest is an example of having goals that are dependent upon other quests being completed.
  • Paul's Quest is testing an optional goal which allows for a branch in the quest line.
  • Mary's Quest is testing multiple stages with multiple goals.
  • Peter's Quest is for testing quantity/fetch quests.
Very interesting & thanks for sharing the code!

User avatar
SBG_Eric
Regular
Posts: 65
Joined: Fri Feb 07, 2014 11:40 pm
Completed: Warhammer 40K (non-commercial MTG set), Tales of Symphonia (non-commercial MTG set)
Projects: Galactic Domain, Dragonfish Racers, *A Yet Unnamed Miniatures Wargame*
Organization: Sunbridge Games LLC
IRC Nick: SBG_Eric
Location: USA, East Coast
Contact:

Re: Quest Log

#4 Post by SBG_Eric » Mon Mar 03, 2014 7:15 pm

An interesting concept. I'm not on my own PC at the moment, so I can't check any of the .rpy files, but the idea has enough pull with me to warrent a bookmark on the topic for further investigation. Thanks for sharing this jw2pfd.
Sunbridge Games Projects
Visual Novel Project (Pre-Dev): http://lemmasoft.renai.us/forums/viewto ... 60&t=33087
- Seeking Writer (5% per scenario) [1 Scenarios Remaining]

Galactic Domain (Post-Dev/Testing) & Dragonfish Racers (In-Dev): Projects on Hold // Require Artist(s)

Other projects TBA: 2+

Fantasy/Play-or-Die Light Novel (Outline/Drafting)

Meiting_98
Regular
Posts: 35
Joined: Fri Jul 12, 2013 1:25 pm
Projects: Neutralizing You
Organization: Ninja Vault
Location: Indonesia
Contact:

Re: Quest Log

#5 Post by Meiting_98 » Mon Apr 14, 2014 11:42 am

Thank you so much for sharing, jw2pfd! :D

KarloPan
Newbie
Posts: 14
Joined: Thu Jun 22, 2017 8:16 pm
Contact:

Re: Quest Log

#6 Post by KarloPan » Thu Jul 20, 2017 11:28 am

hello there,
I don't know if this is still up to date and i can Post problems but i try it :3
I have include all files exept the "script.rpy" in my project to use it, also i added every command into my script.rpy
but if i start i get an error

EDIT: Everything alright, i am just new and dumb xD :P

Karlo

User avatar
BluesBoy
Newbie
Posts: 3
Joined: Tue Apr 17, 2018 4:16 pm
Contact:

Re: Quest Log

#7 Post by BluesBoy » Sat Jun 02, 2018 4:57 pm

Buddy, thank you for your work. This is a really useful article.
It is almost impossible to find a methodology for writing quests. Either everything is tied to some kind of specific platform, or it's just nonsense from the programming view point.

Your work was really useful without regard to the platform.
But on it I have questions. I'm not new to programming, but I'm new to Python. And many of the constructions are not very clear to me, since RenPy is a self-sufficient platform.

Please explain:

1. Do I understand correctly that the Link class can only save|restore itself, since it is inherited from renpy.store? It is right?
2. You accept the methods of changing the state of the quest from the main script. That is, by calling the variable "log" and using the appropriate methods. But the first thing that occurred to me, it was to write a "smart"quest class. That is, this class has a method that checks its conditions. For example, when there is an item in the bag, or the hero is in the desired location, etc. This would make the game scenario, for example, less linear. Yes, for each stage it would be necessary to write the start and end methods manually...

I sincerely want to know your opinion. What do you think about it?

LyannaCore
Newbie
Posts: 20
Joined: Wed Jun 21, 2017 1:45 pm
Contact:

Re: Quest Log

#8 Post by LyannaCore » Sun Jun 10, 2018 1:33 pm

This seems like a dead topic unfortunately, but in case it's not I could use some help modifying the example to use in my own project.
Currently, the buttons to switch between current and completed quests are generated automatically via a for loop, but I'd like to use my own, existing imagebuttons. What action(s) do I need to use to replicate their function? I just have 2 imagebuttons, one for current quests, and one for completed.

The current code on line 25 of qscreens.rpy:

Code: Select all

                hbox:
                    for i in log.displayedtabs():
                        textbutton i action [ SetField(log, "tvar", i), log.newtab ]

Palanto
Newbie
Posts: 10
Joined: Thu Nov 30, 2017 11:27 am
Projects: Wicked Choices
Contact:

Re: Quest Log

#9 Post by Palanto » Fri Jun 15, 2018 4:15 am

Hmmm, there are multiple ways, the easiest for not so great programmers (like I am) would be to manually set "i"
What I mean is, in quests.rpy the third string in quests.append(Quest("1st", "2nd", "this one" is the name for the tabs, so if you just have two like in my personal case (active and completed) you could try it like this:

Code: Select all

    hbox:
        imagebutton auto "path/to/file/active_%s.png" action [ SetField(log, "tvar", "Active"), log.newtab ]
        imagebutton auto "path/to/file/completed_%s.png" action [ SetField(log, "tvar", "Completed"), log.newtab ]
That's how I'd do it.... if that doesn't work (for whatever reasons) I'd create a seperate list in which I'd store the strings for the buttons filepaths... something like this:

Code: Select all

buttons = ("path/to/file/active_%s.png", "path/to/file/completed_%s.png")

hbox:
    for i,f in zip(log.displayedtabs(), buttons):
        imagebutton auto f action [ SetField(log, "tvar", i), log.newtab ]

In the latter case, please make sure to have a button for each "3rd string" you add to the quests, so if you do more than just "Active" ("Completed" is the standard for finished quests which should be named in questlog.rpy line 373: class Questlog(Link): completion="Completed"): <- ) you'll need to add another button to it...

I'm not sure how it reacts to when there's no active quest though.... you'd have to try it yourself :)

Good luck :)

LyannaCore
Newbie
Posts: 20
Joined: Wed Jun 21, 2017 1:45 pm
Contact:

Re: Quest Log

#10 Post by LyannaCore » Wed Jun 20, 2018 12:01 am

Thank you for the suggestions, but unfortunately the first doesn't work. With my imagebuttons like this:

Code: Select all

            hbox:
                xpos 90
                ypos 60
                imagebutton:
                    auto "gui/hud/Apps/Goals/old/current_%s.png"
                    focus_mask True
                    selected goal_app_currenttoggle == True
                    action [ SetField(log, "tvar", "Active"), log.newtab, SetScreenVariable("goal_app_currenttoggle", True)]
            hbox:
                xpos 90
                ypos 60
                imagebutton:
                    auto "gui/hud/Apps/Goals/old/completed_%s.png"
                    focus_mask True
                    selected goal_app_currenttoggle == False
                    action [ SetField(log, "tvar", "Completed"), log.newtab, SetScreenVariable("goal_app_currenttoggle", False)]

Code: Select all

  File "game/tabletUI.rpy", line 250, in script
    call screen tablet_test()
  File "renpy/common/000statements.rpy", line 519, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "game/questlog.rpy", line 438, in newtab
    list = self._quests[self.tvar]          #is highlighted
KeyError: u'Completed'
And due to the complexity of my buttons, your second option won't work either unfortunately.

Palanto
Newbie
Posts: 10
Joined: Thu Nov 30, 2017 11:27 am
Projects: Wicked Choices
Contact:

Re: Quest Log

#11 Post by Palanto » Thu Jun 21, 2018 6:44 pm

LyannaCore wrote:
Wed Jun 20, 2018 12:01 am
Thank you for the suggestions, but unfortunately the first doesn't work. With my imagebuttons like this:

Code: Select all

            hbox:
                xpos 90
                ypos 60
                imagebutton:
                    auto "gui/hud/Apps/Goals/old/current_%s.png"
                    focus_mask True
                    selected goal_app_currenttoggle == True
                    action [ SetField(log, "tvar", "Active"), log.newtab, SetScreenVariable("goal_app_currenttoggle", True)]
            hbox:
                xpos 90
                ypos 60
                imagebutton:
                    auto "gui/hud/Apps/Goals/old/completed_%s.png"
                    focus_mask True
                    selected goal_app_currenttoggle == False
                    action [ SetField(log, "tvar", "Completed"), log.newtab, SetScreenVariable("goal_app_currenttoggle", False)]

Code: Select all

  File "game/tabletUI.rpy", line 250, in script
    call screen tablet_test()
  File "renpy/common/000statements.rpy", line 519, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "game/questlog.rpy", line 438, in newtab
    list = self._quests[self.tvar]          #is highlighted
KeyError: u'Completed'
And due to the complexity of my buttons, your second option won't work either unfortunately.


Try it with:

Code: Select all

            hbox:
                xpos 90
                ypos 60
                if "Active" in qlog.displayedtabs():
                    imagebutton:
                        auto "gui/hud/Apps/Goals/old/current_%s.png"
                        focus_mask True
                        selected goal_app_currenttoggle == True
                        action [ SetField(log, "tvar", "Active"), log.newtab, SetScreenVariable("goal_app_currenttoggle", True)]
            hbox:
                xpos 90
                ypos 60
                if "Completed" in qlog.displayedtabs():
                    imagebutton:
                        auto "gui/hud/Apps/Goals/old/completed_%s.png"
                        focus_mask True
                        selected goal_app_currenttoggle == False
                        action [ SetField(log, "tvar", "Completed"), log.newtab, SetScreenVariable("goal_app_currenttoggle", False)]
because without the if statements it will try to display the button and SetField to Completed even though it doesn't exist like in your case (i.e. if you start a quest but didn't complete one yet, so obviously always until you finished the first quest)
This way it doesn't show the "Completed" tab until a quest is marked as completed.

xplosion
Newbie
Posts: 10
Joined: Sat Jul 21, 2018 3:49 pm
Contact:

Re: Quest Log

#12 Post by xplosion » Sat Aug 11, 2018 12:21 pm

Good stuff, one thing I found annoying is how your modifications on the quests file doesn't get updated until you restart the game from zero.

I'm trying to edit the notification text to be shown using renpy.notify but I can't seem to get it to work.

Post Reply

Who is online

Users browsing this forum: No registered users