[Solved] Dynamic Key Specifier

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
Bev_
Newbie
Posts: 5
Joined: Thu Jun 23, 2022 12:39 pm
Contact:

[Solved] Dynamic Key Specifier

#1 Post by Bev_ »

Basically, I want the user to be able to pick his own key for certain action (in-game, without rummaging through files, even if that change would require restarting the game to take place).

I'm assigning the key like this:

Code: Select all

init python:
	config.underlay.append(renpy.Keymap(show_my_screen= ToggleScreen("my_screen")))
	config.keymap["show_my_screen"] = "p"
When I try to change it into something like:

Code: Select all

default persistent.custom_key = "p"
init python:
	config.underlay.append(renpy.Keymap(show_my_screen= ToggleScreen("my_screen")))
	config.keymap["show_my_screen"] = persistent.custom_key
It sadly doesn't work :) I've tried many different variations, googled for hours (maybe I just don't know the correct keywords) and no progress.
This particular way produces AttributeError: 'function' object has no attribute 'split', other ones mostly end up on Exception: Invalid key specifier

Is it possible? What's the best way of achieving it?

atm. My only idea is to provide preset of keys and allow the user to pick one, something like:

Code: Select all

default persistent.key_ID = 1
init python:
	config.underlay.append(renpy.Keymap(show_my_screen= ToggleScreen("my_screen")))
	if persistent.key_ID  == 1:
		config.keymap["show_my_screen"] = "p"
	elif persistent.key_ID == 2:
		config.keymap["show_my_screen"] = "q"
etc. but despite the fact that it works, it looks terrible (even for my standards :P) and is a lot less convenient.
Last edited by Bev_ on Thu Jul 07, 2022 3:46 pm, edited 1 time in total.

User avatar
zmook
Veteran
Posts: 421
Joined: Wed Aug 26, 2020 6:44 pm
Contact:

Re: Dynamic Key Specifier

#2 Post by zmook »

I think your problem is that 'config' variables are mostly (always?) only read during init, so later changes won't show up til you restart.

Try something like:

Code: Select all

screen keyreader:
    key persistent.my_keysym action Function(do_my_thing)
    
label start:
    show screen keyreader
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM

Bev_
Newbie
Posts: 5
Joined: Thu Jun 23, 2022 12:39 pm
Contact:

Re: Dynamic Key Specifier

#3 Post by Bev_ »

zmook wrote: Thu Jun 23, 2022 2:54 pm I think your problem is that 'config' variables are mostly (always?) only read during init, so later changes won't show up til you restart.

Try something like:

Code: Select all

screen keyreader:
    key persistent.my_keysym action Function(do_my_thing)
    
label start:
    show screen keyreader
The thing is: Reason why I'm using keybinds in a first place is that I'm working on a mod, not a game itself, and I want it to be universal, so I can't really modify any existing files/structures. I probably should've mention that :/

So unless I can somehow show that screen during init( Can I? )...
My first reflex is to do something dumb like binding showing that screen to mouse click :D I'm gonna give it some thought
Edit: Doesn't work TypeError: __init__() keywords must be strings

User avatar
zmook
Veteran
Posts: 421
Joined: Wed Aug 26, 2020 6:44 pm
Contact:

Re: Dynamic Key Specifier

#4 Post by zmook »

Bev_ wrote: Thu Jun 23, 2022 3:26 pm So unless I can somehow show that screen during init( Can I? )...
Ah, got it. Even if you can show a screen during init (which I think you cannot), it would probably get hidden when Start() is called anyway.

The config.underlay stuff seems to be undocumented, but one of us could dig around in the code and see if we can learn anything.

The other thing I notice, not sure if you've tried: config.keymap is supposed to map "from event names to lists of keysyms", and you're just giving it a string. Does

Code: Select all

	config.keymap["show_my_screen"] = ["p", ] 
work better?

The other thing I'd try is pushing your init block as late in the order as possible to make sure 'persistent' is initialized before you get to it: init 999 python
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM

Bev_
Newbie
Posts: 5
Joined: Thu Jun 23, 2022 12:39 pm
Contact:

Re: Dynamic Key Specifier

#5 Post by Bev_ »

zmook wrote: Thu Jun 23, 2022 4:02 pm The other thing I'd try is pushing your init block as late in the order as possible to make sure 'persistent' is initialized before you get to it: init 999 python

Code: Select all

init 500 python:
    persistent.my_key = "p"
init 998 python:
    config.keymap["my_thing"] = persistent.my_key
Worked.

I guess that means all init python blocks run before renpy's init no matter the priority.
I've tried

Code: Select all

init 500:
    default persistent.my_key = "p"
init 998 python:
    config.keymap["my_thing"] = persistent.my_key
and

Code: Select all

init 998 python:
    default persistent.my_key = "p" #Edit: I don't remember if I did this, but I've really used default here... Damn, so many hour wasted.
    config.keymap["my_thing"] = persistent.my_key
before and none of them worked. Is it really that big of a difference between those three? :D
Nevermind, thanks mate, I hope it won't break again :)
Last edited by Bev_ on Thu Jun 23, 2022 4:34 pm, edited 1 time in total.

User avatar
zmook
Veteran
Posts: 421
Joined: Wed Aug 26, 2020 6:44 pm
Contact:

Re: Dynamic Key Specifier

#6 Post by zmook »

Bev_ wrote: Thu Jun 23, 2022 4:20 pm Is it really that big of a difference between those three? :D
Well, default persistent.my_key = "p" is not a Python statement, so I'm not surprised the last one didn't work. And also, since 'default newvar' is syntactic sugar for:

Code: Select all

label start:
	if not hasattr(store, 'newvar'):
	    newvar = 10
label after_load:
	if not hasattr(store, 'newvar'):
	    newvar = 10
it doesn't run at init time and so neither of those are going to do what you want.
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM

Post Reply

Who is online

Users browsing this forum: No registered users