Ren'Py Issue when trying to simulate keypresses in a Creator Defined Displayable.

Lykanz

Engaged Member
Game Developer
May 2, 2017
2,762
7,450
I'm trying to simulate keypresses on a Creator Defined Displayable for a minigame in my project, but I've been running into an issue every time I try to implement it.

Here's the thing: In pygame, you simulate keypresses by posting a new event like this:

Python:
pygame.event.post(pygame.event.Event(pygame.locals.KEYDOWN, unicode="a", key=pygame.locals.K_a, mod=pygame.locals.KMOD_NONE))
or

Python:
pygame.event.post(pygame.event.Event(pygame.KEYDOWN, unicode="a", key=pygame.K_a, mod=pygame.locals.KMOD_NONE))
The problem is that this returns me an error in Ren'py like this whenever the event is posted to the queue:

Python:
EventType object has no attribute "repeat".
I tried looking for help on stackoverflow, but it seems that this is either an isolated issue to Ren'py or not something a lot of people tried before.

Any help or tips on this would be greatly appreciated.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,302
15,174
I tried looking for help on stackoverflow, but it seems that this is either an isolated issue to Ren'py or not something a lot of people tried before.
Ren'Py do not directly use PyGame, but a variation of it, what mean that PyGame isn't fully implemented. Not sure if it's the cause or not, but it have to be kept in mind.

This being said, why do you want to simulate a key press, and what do you expect from it ?
The only reason I can see without really thinking about it is to trigger a reaction from something else. But then why pass by PyGame input stack, when you can probably just trigger it by a function call ?
 

Lykanz

Engaged Member
Game Developer
May 2, 2017
2,762
7,450
Ren'Py do not directly use PyGame, but a variation of it, what mean that PyGame isn't fully implemented. Not sure if it's the cause or not, but it have to be kept in mind.

This being said, why do you want to simulate a key press, and what do you expect from it ?
The only reason I can see without really thinking about it is to trigger a reaction from something else. But then why pass by PyGame input stack, when you can probably just trigger it by a function call ?
I'm working on a rhythm minigame for my game, it's core mechanics are all finished.
The player has to press keys as they reach a time threshold.
It's based off Lynn Zheng's rhythm minigame framework and it's really just a big CDD.
It works pretty well so far.
The only thing left in my "cool things to implement" list is a autoplay feature.
And some visual cues on the screen are activated by the keys being pressed.

So I thought the best way to approach it would be to simulate key presses at a certain time threshold.

I dunno if I'm being clear enough tbh.
 

osanaiko

Engaged Member
Modder
Jul 4, 2017
2,248
3,853
This sounds really cool.

However as a developer it's easy to go down the wrong rabbit hole, and start trying to solve certain difficult specific problems when there is actually an easier path if you step back and think again about what you want to achieve. This is why AnneO is asking about what you are trying to do.

Re-using all your existing code by just injecting simulated keypresses is a good idea, but if the framework does not support it, then what other ways can you change your implementation to get the same (from players perspective) result? For example, can you have a "demo mode" switch in the CDD that is checked and causes every rhythm beat to be hit automatically when the time comes?
 
  • Like
Reactions: gojira667

Lykanz

Engaged Member
Game Developer
May 2, 2017
2,762
7,450
This sounds really cool.

However as a developer it's easy to go down the wrong rabbit hole, and start trying to solve certain difficult specific problems when there is actually an easier path if you step back and think again about what you want to achieve. This is why AnneO is asking about what you are trying to do.

Re-using all your existing code by just injecting simulated keypresses is a good idea, but if the framework does not support it, then what other ways can you change your implementation to get the same (from players perspective) result? For example, can you have a "demo mode" switch in the CDD that is checked and causes every rhythm beat to be hit automatically when the time comes?
Yeah, as I said, the thing is pretty much finished now and all the features I wanted to implement beside that one are done.

I even moved to the interface part of developing it cuz I didn't want to waste too much time implementing something I wasn't even sure it would work.

I created the thread mostly to make sure it was something I was doing wrong or a Ren'py limitation tbh.

The demo mode switch was actually part of how I tried implementing as right now beat hits are registered only by the key presses and I didn't want to create a whole new logic just for it.

I'll try another jab at it with a different approach when everything I need for my next update is done and if I have enough time, otherwise to the back burner of ideas it goes.
 
  • Red Heart
Reactions: osanaiko

crabsinthekitchen

Well-Known Member
Apr 28, 2020
1,549
8,732
based on what I found and quick test of simulating screenshot taking this works
Code:
init python:
    # This is the method we'll be calling to simulate the keypress
    def simulate_keypress(unicode_key, pygame_key):
        pygame_sdl2.event.post(pygame_sdl2.event.Event(
                pygame_sdl2.KEYDOWN,
                key=pygame_key,
                scancode=pygame_key,
                unicode=unicode_key, mod=0, repeat=False,
            ))
        pygame_sdl2.event.post(pygame_sdl2.event.Event(
                pygame_sdl2.KEYUP,
                key=pygame_key,
                scancode=pygame_key,
                unicode=unicode_key, mod=0, repeat=False,
            ))
 

Lykanz

Engaged Member
Game Developer
May 2, 2017
2,762
7,450
based on what I found and quick test of simulating screenshot taking this works
Code:
init python:
    # This is the method we'll be calling to simulate the keypress
    def simulate_keypress(unicode_key, pygame_key):
        pygame_sdl2.event.post(pygame_sdl2.event.Event(
                pygame_sdl2.KEYDOWN,
                key=pygame_key,
                scancode=pygame_key,
                unicode=unicode_key, mod=0, repeat=False,
            ))
        pygame_sdl2.event.post(pygame_sdl2.event.Event(
                pygame_sdl2.KEYUP,
                key=pygame_key,
                scancode=pygame_key,
                unicode=unicode_key, mod=0, repeat=False,
            ))
Oh yeah, that works like a charm. Thanks!
 
  • Like
Reactions: osanaiko