Changing How Ren'Py Parses "show"

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
dovedozen
Newbie
Posts: 6
Joined: Thu Mar 17, 2022 9:33 am
Contact:

Changing How Ren'Py Parses "show"

#1 Post by dovedozen » Sun Mar 27, 2022 1:20 am

Hi! In my hubris, I've been working on a creator-defined statement. I'd like it to work even if I type it directly after a "show" statement, on the same line, because show statements are short and the prospect of letting all that blank real estate go to waste bugs me.

Right now, what happens is that the "show" co-opts my CDS keyword as part of the show statement, because the parser for show statements looks for the end of a line as its cue that the statement is over.

Finding the cause of this my-code-skippage was very very very interesting, since I did not know what a parser was until, like, MAYBE 72 hours before that moment. However, being this much of a novice also means that I'm not entirely sure I'm on the right track as far as "using this information to solve my problem" goes.

If you're reading this and know things about how ren'py works internally: could you confirm/deny something for me? Is it possible to overwrite ren'py's inbuilt "show" parser with my own, extremely similar parser (which adds one "if" statement which checks for my keyword), without directly editing the source code?



I'll run through what I've tried (skip to the end and check out questions 1 and 4 if you're pretty sure the answer is "of course not??" and don't need to read what I've tried), but first: I'm not, like, vehemently opposed to editing the source code, I guess? I don't think? But also, it's easier to keep track of what's weirdo homebrew handle-with-care-type code if it's all inside my project folder, so I'd prefer to do that where possible. Just, like, instinctively.

(I'm also sensing that the answer to this question might possibly teach me something, which would be exciting.)



Anyway: details: I've gathered that ren'py's show parser is kept track of like this:

renpy.parser.statements is a ParseTrie object. It acts as the root of the trie that keeps track of parsers (and is presumably accessed when it's time to decide which parser to use for a given statement).

The show parser is added to renpy.parser.statements using statements.add("show", f), where f is the show_statement parser function itself(, I guess? I have never actually written a decorator; be nice to me. I'm PRETTY sure that f is what this decorator calls "self", and that "self" in this case would refer to the function being wrapped by the decorator. Probably).

This adds "show" to statements.words, which is a dictionary of strings and other stuff. Crucially, this SHOULD mean that "show" is a key contained directly in statements.words, and the other half of its dictionary entry (which... is... another ParseTrie which keeps the parser function as its "default" value?) should be directly tied to its presence, right?

What I've TRIED to do is:
  1. define my own show parser in a python early block
  2. del renpy.parser.statements.words["show"]
  3. renpy.parser.statements.add("show", my_show_parser)
...I didn't specify WHEN I told ren'py to execute steps 2 and 3 just now because I have tried a lot of different whens and none of them worked.

Possibly this is obvious to people who aren't me, but: okay: the "del" line doesn't break anything (which is what I'd expect if, say, I weren't allowed to directly access ren'py's stuff in this manner), BUT it also doesn't seem to do anything, because I gently placed a print() inside my custom parser so I'd know when it was being used, and it super isn't. But show statements still work, which wouldn't make sense if I HAD managed to divest the show parser from the thing that keeps track of where parsers are.

So I'm getting the feeling that either "del"-ing statements.words["show"] doesn't hide the inbuilt show statement parser in any meaningful way at all, or it would if I did it at exactly the right time but my timing is off... OR that I'm not even actually "del"-ing anything at all, and my attempts are so ineffectual that ren'py isn't bothering to warn me that what I'm trying to do won't work.



Having written this out, I feel like there are 3 layers of question here:

1. Can code written inside a project folder directly grab ren'py with its weird little hands and change stuff for which there isn't a config variable or something of that nature? In the general sense?

(Okay, so if the answer is "no" there's only ONE layer of question, but IF IT'S YES:)

2. WHEN does ren'py decide which parser to use for a given type of statement? My self-taught code-deciphering skills are at their limit here.

3. "Should" the "del" --> "statements.add" approach work? As in, assuming that I got the timing right and did this AFTER "show" had already been added, but BEFORE any of my script was actually parsed, would I be able to redirect the parsing of show statements in my script by going "okay now get rid of the key/value pair, in the "words" dictionary belonging to the "statements" object, whose key is "show". Okay, now ADD a thing to statements using the key "show"; here is the second argument, it is a function."........??



(......4. If I have to directly change the source code, I should only have to change renpy.parser.show_statement, right?)



If you're asking yourself why someone would use THIS MUCH energy just to avoid using more linebreaks in their script: 1. stubborn 2. got curious 3. incapable of learning unless sufficiently motivated by the prospect of future convenience; not convinced this information won't come in handy at some point even if I give up on this particular Dubious Idea.

Thank you for taking the time to read! If you can, please help me learn something practical from all this...

User avatar
Ocelot
Eileen-Class Veteran
Posts: 1882
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: Changing How Ren'Py Parses "show"

#2 Post by Ocelot » Sun Mar 27, 2022 2:11 am

1) Yes and No. A lot of RenPy is defined to work from outside of its enviroment (for example, all code designed to set up that enviroment). I have no Idea if default parser could be messed with reliably from within RenPy.

2) When generating rpyc files from rpy

3) Not exactly. You will need to extensively study the code to make sure that nothing related to the show statement elsewhere.

4) Like 3, no guarantee that this is all.

I must note that "conversing" lines is an extemely common behavior exibited by novice programmers.
< < insert Rick Cook quote here > >

dovedozen
Newbie
Posts: 6
Joined: Thu Mar 17, 2022 9:33 am
Contact:

Re: Changing How Ren'Py Parses "show"

#3 Post by dovedozen » Sun Mar 27, 2022 11:11 am

I'm novice programmers! :D
Ocelot wrote:
Sun Mar 27, 2022 2:11 am
2) When generating rpyc files from rpy
But thank you; all your answers are helping me orient myself a bit better and this especially has given me enough context to chill my brain out a little. I'll go ahead and give in on the new-line front for the time being, & if I decide I really want to play around with it sometime, I think this serves as a decent piece of evidence that it'd be a better use of my life minutes to just change parser.py itself and test that!

I appreciate the perspective a lot; thanks again.

Post Reply

Who is online

Users browsing this forum: No registered users