Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Controller Support Expansion for Ren'Py

Comprehensive set of features to improve controller support in Ren'Py. · By Feniks

Need Support? Post here! Sticky

A topic by Feniks created 74 days ago Views: 130 Replies: 11
Viewing posts 1 to 4
Developer (1 edit)

If you're having trouble or run into any bugs with the code, post a comment here! I will try to get back to you within a few days. Be sure to check the Controller Support Expansion section on my website too for documentation.

So I finally got around to testing this out! Unfortunately, I immediately ran into a crash:

I'm sorry, but an uncaught exception occurred.
While running game code:
  File "game/script/system/plugins/controller_support/controller_config.rpy", line 313, in script
    init 999 python in pad_config:
  File "game/script/system/plugins/controller_support/controller_config.rpy", line 313, in script
    init 999 python in pad_config:
  File "game/script/system/plugins/controller_support/controller_config.rpy", line 316, in <module>
    FOCUS_MANAGERS = [FocusManager(x) for x in RESTORE_FOCUS_SCREENS]
  File "game/script/system/plugins/controller_support/controller_config.rpy", line 316, in <lambda>
    FOCUS_MANAGERS = [FocusManager(x) for x in RESTORE_FOCUS_SCREENS]
  File "game/script/system/plugins/controller_support/controller_config.rpy", line 316, in <listcomp>
    FOCUS_MANAGERS = [FocusManager(x) for x in RESTORE_FOCUS_SCREENS]
  File "game/script/system/plugins/controller_support/controller_functions.rpy", line 339, in __init__
    self.is_showing = renpy.get_screen(self.screen)
Exception: Unknown layer 'game_menu'.

I'm using a custom layer for my in-game menus (including the main menu), and that seems to be causing a problem.

Developer

Ooh I see! Yes I had not accounted for that. For now, can you see if this change to the FocusManager class in controller_functions.rpy will fix it?

def __init__(self, screen, layer=None):
    if isinstance(screen, tuple):
        self.screen = screen[0]
        self.layer = screen[1]
    else:
        self.screen = screen
        self.layer = layer
    self.is_showing = renpy.get_screen(self.screen)
    self.displayable_lookup = dict()
    self.refresh_triggered = False
    super(FocusManager, self).__init__()

And then adjust `RESTORE_FOCUS_SCREENS` to be a list of pairs like ("game_menu", "MY_GAME_MENU_LAYER") e.g.

define pad_config.RESTORE_FOCUS_SCREENS = [ ("main_menu", "my_menu_layer"), ("game_menu", "my_menu_layer"), "controller_remap" ]

I'll run some more tests and such, but try that for now. That, or if you're not using a game_menu screen/standalone like the template does, just remove "game_menu" from RESTORE_FOCUS_SCREENS altogether.

(1 edit)

Sadly, that didn't change anything. It still throws the same error (just with different line numbers, due to the few that were added).

I can only get the game to boot up by removing the "main_menu" AND "game_menu" part from RESTORE_FOCUS_SCREENS.

It also works if I remove [layer "game_menu"] from my "main_menu" screen  and do:

define pad_config.RESTORE_FOCUS_SCREENS = [ ("main_menu", "game_menu"), "controller_remap" ]

So it seems like it doesn't really care what I put in the tuple?

Developer

If your layer is called `game_menu`, renpy.get_screen is interpreted first as a tag and then as a screen, so regardless it wouldn't work with a screen *and* a layer called game_menu. So, I recommend either changing the tag name or the screen name so they're different if you want to use the save-and-restore focus features for the in-game menu screen. Otherwise, it's fine to just not have that screen in the RESTORE_FOCUS_SCREENS.

Hmm, the crash still occurs even after renaming my "game_menu" layer to "menus". But I'll keep testing with just 

pad_config.RESTORE_FOCUS_SCREENS = [ "controller_remap" ] 

for now. Thank you!

Hi, was looking at the demo template. Turning on self voicing when any of the custom preference screens open gave this if it detects mouse currently being used. Didn't happen when using keyboard/roller though.

I'm sorry, but an uncaught exception occurred.
While running game code:
TypeError: 'dict_values' object is not subscriptable
Developer(+1)

Huh, I had not noticed this! You are correct. The solution is to update the visit method in 01_controller_cdsl.rpy:

def visit(self):
    return list(self.displayables.values())

to wrap the return value in a list. I'll add this to the next fix release. Thanks!

Hi, is there any way I can disable the reset-to-middle aspect of the virtual cursor?

Developer

What kind of functionality are you looking to replace it with? Are you referring to how the cursor begins in the center of the screen, or the snap-to-center feature?

I thought it'd be nice to have the cursor available during regular dialogue (to click buttons in the quick menu with the cursor), but every time you advance the dialogue, the cursor resets back to the center of the screen.

Not a huge deal at all, just something I'm curious about.

Developer

How have you declared the cursor/added it to the screen?