Ren'Py Character 'n' Quest Manager for Ren'Py

rodrigosarri

Newbie
Sep 22, 2020
85
75
Hello everybody, How are you? At a time when I was making a suggestion for a game I've been following, one of the developers asked me if I could make a feature I suggested in Ren'Py.

After a month working and studying about Ren'Py (I'm a system analyst and I've worked with Python in the past) I decided to develop the resource and now I'm distributing this resource for free to anyone who wants to use it and help me improve either with suggestions or requests (but keep in mind that I do this feature in my spare time).

Video


More info


Download or clone the project


Wiki


That's it, hope you guys like it!
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,979
16,236
[...] anyone who wants to use it and help me improve either with suggestions or requests [...]
Ok, I found a moment and took a look at your code...


First thing first, I'm really not sure that Microsoft Arial font is free, therefore you should find a better font ; one that you have the right to distribute.

Then, well there's many things to say, some regarding Ren'Py, others regarding Python or the logical process.


Note: The code is wrote on the fly, there's perhaps some typo.

As said by Ren'Py documentation, statements like define and image are at init level, and create their own init context. Therefore, putting them in a label just break the label (but by chance not it's processing). They should all be at 0 indentation and outside of any labels or init block.


Regarding the Characters object:
You don't have permission to view the spoiler content. Log in or register now.


Regarding the MountCharacterObject object:
You don't have permission to view the spoiler content. Log in or register now.


Regarding the MountQuestObject object:
You don't have permission to view the spoiler content. Log in or register now.


Regarding the Panel object:
You don't have permission to view the spoiler content. Log in or register now.


Regarding the Quests object:
You don't have permission to view the spoiler content. Log in or register now.


Python:
label charactersLabel:
    [...]
    $ mountCharacter = Characters()
    [...]
    $ mountCharacter.addChar(
    [...]
No ! Use default (and design your code to be able to use it), when you create game significant variables. Never do this in a label, even less a dedicated one that will be called at start. It's how you avoid save incompatibilities and broken code.

Here, designing the code to be default compatible mean that Characters handle only one character, and that it's chars attribute become an external dict:
Python:
default allChars = { 
             "emma": Character( "Emma", "discription", "images/chars/emma_pict_idle.png", [...] ),
             "sarah": Character( "Sarah", "discription", "images/chars/sarah_pict_idle.png", [...] ),
             [...]
         }
This would not only ensure a better save compatibility, but also simplify the whole Characters class.


Same problem with the "questsLabel" label.


Python:
label panelLabel:
    [...]
    $ configPanel = Panel()
    [...]
    $ cqmAction = [
        ToggleScreen("showChars"),
        Hide("allChars"),
Again, same than above, except that all the actions should be defined... And anyway shouldn't exist at all. Make a correct use of the tag screen property to avoid the need to blindly hide screens.


Code:
screen filterCloseQuests(char = Null):
Null is a blank layout used by Ren'Py, do NOT use it in place of None. It will do something radically different and make the usual security test if not char fail to do its role.


And I'll not talk about the tons of screens that are way too numerous. Like by example the filters ones that could be:
Python:
screen filter(char, status="inProgress" ):

    tag "quest"

    frame:
        xysize(1344, 680)
        xpos 380
        ypos 310
        style "defaultFrame"

        area(0, 0, 1344, 680)
        viewport id "questList":
            draggable True
            mousewheel True

            hbox:
                box_wrap True

                for quests in mountQuest.filterQuest(char.getCode, statuts ):
                    frame style "questFrame":
                        add "bgQuest"
                        [...]

                showif not mountQuest.filterQuest(char.getCode, statuts ):
                    text "No quests with this status were found" style "noQuestTitle"
                    add "noQuests" ypos 0.5 xpos 0 xanchor 1.0 yanchor 0.0
And this apply even with the initial "one method by filter" approach:
Python:
screen filter(char, status="inProgress" ):

    if status == "done":
        $ filtered = mountQuest.getFilterDoneQuests(char.getCode )
    elif status = "inProgress":
        $ filtered = mountQuest.getFilterInProgressQuests(char.getCode )
    [...]

    frame:
        xysize(1344, 680)
        [...]

                for quests in filtered:
                    [...]
Anyway you should have only one screen for the quest, and rely on use screen statement for what have to be displayed at the given moment.


All this being said, there's perhaps issues regarding the code behavior, and many way to simplify the screens. But I'll not start to do a deep analyze of the code. This is what was obvious will taking a look at it, nothing more.
 
Sep 2, 2023
3
3
It looks great, thank you.

I've trying to implement it to my game, but ran into few problems. It seems quests can be made only under one character and in order number #0 quest #1 quest #3 quest, etc. In my game there is sandbox and quest can ruin the order. I think this could be better is quests have id-number. What I mean, I cannot change quest if it is #2 quest, but in game actually there was two other quest before that.

I don't know Python that much, so it's hard for me to change anything in code.