Node-based Non-linear Navigation 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.
Post Reply
Message
Author
User avatar
powerofvoid
Newbie
Posts: 16
Joined: Thu Feb 27, 2014 3:56 pm
Contact:

Node-based Non-linear Navigation Framework

#1 Post by powerofvoid »

I was inspired by the screenshot here.

It doesn't support transitions, but other than that, I think I got all the bugs ironed out.

Basic code:

Code: Select all

label show_room_screen:
    call screen room_screen 
    pause
    jump show_room_screen

screen room_screen:
    add places[current_room]["background"]:
        xalign 0.5
        yalign 0.5
    add "player normal":
        xalign 0.5
        yalign 1.0
    frame:
        xpadding 10
        ypadding 10
        xalign 0.0
        yalign 1.0
        
        vbox:
            text "Locations:"
            for this_place in sorted(places[current_room]["connections"]):
                if eval(places[current_room]["connections"][this_place]["requirements"]):
                    textbutton places[current_room]["connections"][this_place]["name"] action [ 
                        SetVariable("previous_room", current_room), 
                        Jump(places[current_room]["connections"][this_place]["label"]),
                    ]
    frame:
        xpadding 10
        ypadding 10
        xalign 0.0
        yalign 0.0
        
        vbox:
            text "Location:"
            text places[current_room]["name"]
            text ""
            text "Actions:"
            for this_action in sorted(places[current_room]["actions"]):
                if eval(places[current_room]["actions"][this_action]["requirements"]):
                    textbutton places[current_room]["actions"][this_action]["name"] action Jump(places[current_room]["actions"][this_action]["label"])
    frame:
        xpadding 10
        ypadding 10
        xalign 1.0
        yalign 1.0
        
        vbox:
            text "People:"
            for this_person in sorted(people):
                if people[this_person]["location"] == current_room :
                    textbutton people[this_person]["name"] action Jump(people[this_person]["label"])
Attachments
room_screen.rpy
script file (screen)
(7.53 KiB) Downloaded 329 times
room_screen readme.txt
readme
(4.78 KiB) Downloaded 332 times
Node Framework Demo.zip
Demo game
(204.25 KiB) Downloaded 336 times

User avatar
powerofvoid
Newbie
Posts: 16
Joined: Thu Feb 27, 2014 3:56 pm
Contact:

Re: Node-based Non-linear Navigation Framework

#2 Post by powerofvoid »

Update: Modified version of the screen to make the buttons fill the available space, and to center the other text: (it still uses the same data structures)

Note the "xfill True", "xmaximum 0.3", and "xalign 0.5" lines

Code: Select all

label show_room_screen:
    call screen room_screen 
    pause
    jump show_room_screen

screen room_screen:
    add places[current_room]["background"]:
        xalign 0.5
        yalign 0.5
    add "player normal":
        xalign 0.5
        yalign 1.0
    frame:
        xpadding 10
        ypadding 10
        xalign 0.0
        yalign 1.0
        xmaximum 0.3
        
        vbox:
            
            text "Move To:" xalign 0.5
            for this_place in sorted(places[current_room]["connections"]):
                if eval(places[current_room]["connections"][this_place]["requirements"]):
                    textbutton places[current_room]["connections"][this_place]["name"] :
                        xfill True
                        action [ 
                            SetVariable("previous_room", current_room), 
                            Jump(places[current_room]["connections"][this_place]["label"]),
                        ]
    frame:
        xpadding 10
        ypadding 10
        xalign 0.0
        yalign 0.0
        xmaximum 0.3
        
        vbox:
            text "Location:" xalign 0.5
            text places[current_room]["name"] xalign 0.5
            text "" xalign 0.5
            text "Actions:" xalign 0.5
            for this_action in sorted(places[current_room]["actions"]):
                if eval(places[current_room]["actions"][this_action]["requirements"]):
                    textbutton places[current_room]["actions"][this_action]["name"] : 
                        xfill True
                        action [
                            Jump(places[current_room]["actions"][this_action]["label"]),
                        ]
    frame:
        xpadding 10
        ypadding 10
        xalign 1.0
        yalign 1.0
        xmaximum 0.3
        
        vbox:
            text "People:" xalign 0.5
            for this_person in sorted(people):
                if people[this_person]["location"] == current_room :
                    textbutton people[this_person]["name"] :
                        xfill True
                        action [
                            Jump(people[this_person]["label"]),
                        ]

User avatar
powerofvoid
Newbie
Posts: 16
Joined: Thu Feb 27, 2014 3:56 pm
Contact:

Re: Node-based Non-linear Navigation Framework

#3 Post by powerofvoid »

I made a template for a room. It's designed to be easily changed into a usable room:
  1. "s/template_room/${new_id}/g"
  2. replace "bg placeholder" with your chosen background
  3. make connections and actions
  4. customize to taste
Attachments
template_room.rpy
Room template
(1.29 KiB) Downloaded 282 times

User avatar
Watsonia
Newbie
Posts: 10
Joined: Sat Feb 22, 2014 10:02 am
Skype: watsoniaaenor
Location: EU
Contact:

Re: Node-based Non-linear Navigation Framework

#4 Post by Watsonia »

This is awesome! I can't wait to play around with this, especially since I was trying to solve this problem in my own way, and you've very kindly created a out-of-the-box solution. Thanks so much indeed.

The template is very handy also! :)

User avatar
Donmai
Eileen-Class Veteran
Posts: 1960
Joined: Sun Jun 10, 2012 1:45 am
Completed: Toire No Hanako, Li'l Red [NaNoRenO 2013], The One in LOVE [NaNoRenO 2014], Running Blade [NaNoRenO 2016], The Other Question, To The Girl With Sunflowers
Projects: Slumberland
Location: Brazil
Contact:

Re: Node-based Non-linear Navigation Framework

#5 Post by Donmai »

Lately the example code started throwing an eval error. Thanks to jack_norton and PyTom I could fix it (http://lemmasoft.renai.us/forums/viewto ... =8&t=34338).
powerofvoid wrote:I made a template for a room. It's designed to be easily changed into a usable room:
  1. "s/template_room/${new_id}/g"
  2. replace "bg placeholder" with your chosen background
  3. make connections and actions
  4. customize to taste
Well... easily? It could only be me and my dumbness, but I'm still trying (and failing miserably) to create another room. In my dreams, the demonstration code would come with more than one room, so I could check and see what I'm doing wrong. Can someone give me an idiot's proof explanation?
Node-based Non-linear Navigation Framework for Dummies
Node-based Non-linear Navigation Framework for Dummies
images.jpg (6.34 KiB) Viewed 5840 times
Image
No, sorry! You must be mistaking me for someone else.
TOIRE NO HANAKO (A Story About Fear)

GiPSyFiSH
Newbie
Posts: 2
Joined: Sat Sep 03, 2016 1:13 pm
Contact:

Re: Node-based Non-linear Navigation Framework

#6 Post by GiPSyFiSH »

Sorry to bump a year old thread but I figure since it's in the cookbook and this is the only post about node-based navigation it would be ok.

I can't get this to work (as remarked above). I get an error running the demo.

Could someone please update this or show an alternative? Getting navigation working is the only thing holding me back from making my game.

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/ui/room_screen.rpy", line 137, in script
    call screen room_screen
  File "renpy/common/000statements.rpy", line 463, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "game/ui/room_screen.rpy", line 178, in <module>
    if eval(places[current_room]["actions"][this_action]["requirements"]):
TypeError: eval() arg 1 must be a string or code object

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/ui/room_screen.rpy", line 137, in script
    call screen room_screen
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\ast.py", line 1697, in execute
    self.call("execute")
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\ast.py", line 1715, in call
    return renpy.statements.call(method, parsed, *args, **kwargs)
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\statements.py", line 144, in call
    return method(parsed, *args, **kwargs)
  File "renpy/common/000statements.rpy", line 463, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\exports.py", line 2475, in call_screen
    rv = renpy.ui.interact(mouse="screen", type="screen", roll_forward=roll_forward)
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\ui.py", line 277, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\display\core.py", line 2437, in interact
    scene_lists.replace_transient()
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\display\core.py", line 727, in replace_transient
    self.remove(layer, tag)
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\display\core.py", line 1014, in remove
    self.hide_or_replace(layer, remove_index, "hide")
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\display\core.py", line 938, in hide_or_replace
    d = oldsle.displayable._hide(now - st, now - at, prefix)
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\display\screen.py", line 430, in _hide
    self.update()
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\display\screen.py", line 565, in update
    self.screen.function(**self.scope)
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\screenlang.py", line 1251, in __call__
    renpy.python.py_exec_bytecode(self.code.bytecode, locals=scope)
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\python.py", line 1577, in py_exec_bytecode
    exec bytecode in globals, locals
  File "game/ui/room_screen.rpy", line 178, in <module>
    if eval(places[current_room]["actions"][this_action]["requirements"]):
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\python.py", line 1606, in py_eval
    return py_eval_bytecode(code, globals, locals)
  File "H:\Game Engines\renpy-6.99.10-sdk\renpy\python.py", line 1601, in py_eval_bytecode
    return eval(bytecode, globals, locals)
TypeError: eval() arg 1 must be a string or code object

Windows-8-6.2.9200
Ren'Py 6.99.10.1227
Node Framework Demo 0.0

User avatar
Donmai
Eileen-Class Veteran
Posts: 1960
Joined: Sun Jun 10, 2012 1:45 am
Completed: Toire No Hanako, Li'l Red [NaNoRenO 2013], The One in LOVE [NaNoRenO 2014], Running Blade [NaNoRenO 2016], The Other Question, To The Girl With Sunflowers
Projects: Slumberland
Location: Brazil
Contact:

Re: Node-based Non-linear Navigation Framework

#7 Post by Donmai »

Image
No, sorry! You must be mistaking me for someone else.
TOIRE NO HANAKO (A Story About Fear)

GiPSyFiSH
Newbie
Posts: 2
Joined: Sat Sep 03, 2016 1:13 pm
Contact:

Re: Node-based Non-linear Navigation Framework

#8 Post by GiPSyFiSH »

Thank you, I had already looked at this and don't know how/where to adapt the code... Also did you ever figure out how to add more rooms?

I'm still learning all of this and mostly trough reading and trying to understand code, but having to change stuff right off the bat is confusing me.

User avatar
Donmai
Eileen-Class Veteran
Posts: 1960
Joined: Sun Jun 10, 2012 1:45 am
Completed: Toire No Hanako, Li'l Red [NaNoRenO 2013], The One in LOVE [NaNoRenO 2014], Running Blade [NaNoRenO 2016], The Other Question, To The Girl With Sunflowers
Projects: Slumberland
Location: Brazil
Contact:

Re: Node-based Non-linear Navigation Framework

#9 Post by Donmai »

That was a long long time ago, but I believe all I did was follow Jack Norton's suggestion to bypass that eval error. I changed the start of room_screen.rpy this way:

Code: Select all

init python:
    
    def evalFixed(expression):
        if not isinstance(expression, basestring):
            expression = repr(expression)
    
        return eval(expression)
        
    """
        ###################################################
        # Step 1: Initialize
        ###################################################
The error was gone, but then I discovered I wasn't able to create another room using the instructions provided. So, I quit. I'm not a programmer.
Image
No, sorry! You must be mistaking me for someone else.
TOIRE NO HANAKO (A Story About Fear)

Post Reply

Who is online

Users browsing this forum: No registered users