A better solution than nested if else statements

Diconica

Well-Known Member
Apr 25, 2020
1,101
1,150
This thread almost feels like you gents/ladies are planning to run RenPy on low-performance embedded systems :D

Any performance difference simply doesn't matter, because a big chuck of the processing time is taken up from the renderer anyway. You'd decide a bit faster about which image to show and still wait ages (comparatively) for said image to actually show.

(Honestly, for me .get()'s benefit over in is that you can return a default value in the case of a miss, something that would require an if/else in the case of in.)
If you are loading images off the drive as you go along yep that will be slower because you have drive access times to deal with.

You can however preload them. You could do that several ways. Preload a number of them at the start or write a prefetch to run in the background. That way while you are at say Scene 1 it is loading 2 and maybe 3. When you go to those it loads the next possible ones.

Most the lag I seen in the games is usually do to shitty programming. Almost every time I looked I find crap loads of nest if else statements. Also you can look at it source up on github renpy. There isn't anything its source to create the large amounts of lag I see on many of he games. I can count the number of times I seen lots of nested if else statements.

In C and C++ that's bad enough. It usually result in 2 to 3 jump statements per each one of them in the machine code.
It is usually is worse. If don't know why jumps are bad in machine code. Well part of what makes CPUs fast is the prefetch stuff they expect you to use. So if you have jump in the code it can't accuratly predict what to load next. So you get a cache miss. This means it then has to load data out of ram vs off the cache. If you have a bunch of them you are creating a nightmare for the CPU ad will kill the performance.
 

Paz

Active Member
Aug 9, 2016
913
1,453
You can however preload them. You could do that several ways. Preload a number of them at the start or write a prefetch to run in the background. That way while you are at say Scene 1 it is loading 2 and maybe 3. When you go to those it loads the next possible ones.
RenPy already does that for you, except in very specific cases. But in 99.9% of them, it does. But it's more than "this is the image, show it" that takes place, and that is arguably a big timesink.

In C and C++ that's bad enough. It usually result in 2 to 3 jump statements per each one of them in the machine code.
It is usually is worse. If don't know why jumps are bad in machine code. Well part of what makes CPUs fast is the prefetch stuff they expect you to use. So if you have jump in the code it can't accuratly predict what to load next. So you get a cache miss. This means it then has to load data out of ram vs off the cache. If you have a bunch of them you are creating a nightmare for the CPU ad will kill the performance.
I am very interested in seeing a game that was purely bogged down by nested if/else conditions, where if you clean them up it becomes playable, if you have an example.

And honestly, trying to argue against if/else by using CPU cache misses is....I don't even know. We're not talking nanosecond-critical apps here, and we assume that the CPU the game runs on was manufactured in this century.
 
  • Like
Reactions: anne O'nymous

peterppp

Active Member
Mar 5, 2020
583
963
Yep, sure have it's the excuse some programmers give when they don't know the language well enough to write the best code they could the first time through.

Usually it pans out like this.
Boss: Why isn't this code optimized?
Emp: I didn't want to try optimizing it till I knew it worked.
Boss: What you couldn't optimize while you wrote the code. WTF kept you from doing so.
Emp: but but but
Boss: Never mind I'm sick of your excuses pack your shit your fired.

My personal view is I don't like wasting time rewriting shit I could just written correctly the first time around.
Not to pick a fight or anything but just for fun reading your code it's more like this.
Boss: New guy, why aren't you follow naming conventions? It makes your code hard to read. Wait, is that why you're doing it, to be the only one able to maintain it?
Emp: No, that's just the way I code.
Boss: Not here you aren't. Pack your shit, you're fired.
 

Diconica

Well-Known Member
Apr 25, 2020
1,101
1,150
RenPy already does that for you, except in very specific cases. But in 99.9% of them, it does. But it's more than "this is the image, show it" that takes place, and that is arguably a big timesink.



I am very interested in seeing a game that was purely bogged down by nested if/else conditions, where if you clean them up it becomes playable, if you have an example.

And honestly, trying to argue against if/else by using CPU cache misses is....I don't even know. We're not talking nanosecond-critical apps here, and we assume that the CPU the game runs on was manufactured in this century.
I was talking more on the line of write your own loader and manager for them.
Treat it sort of like we do game consoles.
By that I mean use a certain amount of memory space or a certain number of image are uploaded when you are no longer going to use one remove it and upload a ones that are coming up.

A game someone cleaned up of all the if else statements.
I've never seen a developer actually do that.
Usually they keep piling more stuff on top till it gets so slow they have to do something.
Then when they realize the mess they made they give up.
That or they start a new part.

What I have seen is the code of a lot of the games. I've seen the way they perform in comparison to one another.
I guess we could drag a couple games on to this post and go through their code. Maybe, we should do some who have developers on this site. After all they are probably the only one's going to learn or maybe listen to this. The people who don't visit here sure as hell won't learn from it.
 

Paz

Active Member
Aug 9, 2016
913
1,453
I was talking more on the line of write your own loader and manager for them.
....
I am not entirely sure that you're preaching to the right audience here. Keep in mind that the vast, vast majority of creators are amateurs that are happy enough if their game doesn't crash.

Them learning how to shave off 2 milliseconds from the next screen showing is so out of scope that it's unreal. And it serves absolutely no purpose at all. I still fail to understand your fixation with such performance optimization. :/
 

Diconica

Well-Known Member
Apr 25, 2020
1,101
1,150
Not to pick a fight or anything but just for fun reading your code it's more like this.
Boss: New guy, why aren't you follow naming conventions? It makes your code hard to read. Wait, is that why you're doing it, to be the only one able to maintain it?
Emp: No, that's just the way I code.
Boss: Not here you aren't. Pack your shit, you're fired.
ROFL which one?
I'll assume you mean and not one of the other 50 plus ones in use.
It still violates PEP8 do you know why?

You don't have permission to view the spoiler content. Log in or register now.
 

xj47

Member
Nov 4, 2017
240
399
I agree that talking this much about performance is a waste of time.
Performance matters in some places. If you were writing some image-rendering thing it might matter. If you are writing a game-logic function that runs maybe 60 times a second these finer points don't fucking matter. Spend your mental energy on keeping the code clean and maintainable instead.
 

Diconica

Well-Known Member
Apr 25, 2020
1,101
1,150
I agree that talking this much about performance is a waste of time.
Performance matters in some places. If you were writing some image-rendering thing it might matter. If you are writing a game-logic function that runs maybe 60 times a second these finer points don't fucking matter. Spend your mental energy on keeping the code clean and maintainable instead.
Your main game loop can't run 60 fps if you bog it down with slow as code it has to process each loop.
The render is called at the end of that loop.

This below is a very simplified version of the game engine
That FPS count you see is actually not FPS it is the number of cycles the engine does each second
That means that update function shown below and everything else has to finish in <1/60th of a second for you to get 60FPS

I know this for a fact because this is my primary area of development.

C:
int update(){

    switch(gamestate){
        case gameState::menu:
            //main menu
            break;
        case gameState::option:
            //options
            break;
        case gameState::play:

            update_game_state();
            update_sound();
            update_AI();
            build_scene();
            break;

        case gameState::quit:
            run = false;
            cleanup();
            break;
    }
}

int render(){
    switch(gamestate){
        case gameState::menu:
            display_main_menu();
            break;
        case gameState::option:
            display_options();
            break;
        case gameState::play:

            display_scene();
            break;
        case gameState::quit:
            run = false;
            cleanup();
            break;
    }
}


int main(){
    bool run=true;
    initialize();//Where everything is setup.
   
    while(run){

        eventHandler();//Handles Keyboard, mouse and other events

        update();//This is were updates are handled

        render();//At the end of all that is when render is called.

    }
}
I didn't include anything like multi-threading because that's hard for even a lot of seasoned developers to get right.
What I will tell you is you won't get the maximum performance out of your game engine using something like async.
You need an actual threadpool and task system.

I could go into a full on tutorial on game development here. I'm not going to. I posted plenty of other times on here on different aspects of game development on this site. Not that hard to very I know my shit.

I suggest you actually do some of the tutorials on game development using opengl or directx so you learn how game engines actually work. There are plenty of good sites and forums that cover it. Check out gamedev.net and gamasutra.com

1/60th of a second:
That is 16.6 milliseconds. You know that stuff I was measuring up there.
It didn't take 10,000 of them to exceed that value thus it couldn't have gotten 60 fps.
It would be vastly worse if the same thing was done with if statements
Using the "if in" method would reduce that amount in half.
You can see how little if statements it takes to kill 16 milliseconds.
You can play with the following files and see how easy nested if statements kill performance in comparison.
They are more than 1/10th the speed of "if key in dictionary: and 1/20th the speed of dictionary.get(key)
You don't have permission to view the spoiler content. Log in or register now.
I used the following code to generate that.
You don't have permission to view the spoiler content. Log in or register now.
 
Last edited:

Diconica

Well-Known Member
Apr 25, 2020
1,101
1,150
I am not entirely sure that you're preaching to the right audience here. Keep in mind that the vast, vast majority of creators are amateurs that are happy enough if their game doesn't crash.

Them learning how to shave off 2 milliseconds from the next screen showing is so out of scope that it's unreal. And it serves absolutely no purpose at all. I still fail to understand your fixation with such performance optimization. :/
I understand your point of view its by far the most sensible one posted against. This but the problem is this doesn't simply end in milliseconds it becomes seconds relatively fast. So then the next time you play a game and wonder why it takes several seconds to load that next scene this is usually the case from the code I looked at when it comes to games on here.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,391
15,307
I was talking more on the line of write your own loader and manager for them.
Treat it sort of like we do game consoles.
By that I mean use a certain amount of memory space or a certain number of image are uploaded when you are no longer going to use one remove it and upload a ones that are coming up.
So you were talking about... what Ren'Py already do natively. Sure, it's something that is missing to Ren'py, no doubt.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,391
15,307
I understand your point of view its by far the most sensible one posted against. This but the problem is this doesn't simply end in milliseconds it becomes seconds relatively fast. So then the next time you play a game and wonder why it takes several seconds to load that next scene this is usually the case from the code I looked at when it comes to games on here.
Except that you forgot an important point: You're searching to gain microseconds, while achieving to only gain nanoseconds, in the parts that are absolutely not critical, and that are already capped by something that you have no control over.

What you present is an event system that isn't relying on supposed too slow algorithms, but at no time you questioned when this event system will be used.
The fact is that it will be used right after the player have read a dialog line, and right before he read another dialog line. This imply that you can not add the gains together. You'll gain few nanoseconds, then the player will have to read a dialog line, what will absorb your gain. Then again you'll gain few nanoseconds, that will again be absorbed by the time past reading the next dialog line.
You can do all the optimization you want, and you can turn the problem all the way you want, you'll never achieve to reach a significant enough gain during this part of the code. At no time the player will notice that the dialog line game up faster, unless you achieved to gain at least 0.2/0.3 second in a row ; what will never happen.

For memory (or as information since in fact you don't seem to know it), while the player read a dialog line, Ren'py is already doing this:
  • Analyze the code that can possibly be proceeded after this, for few instructions in the future ;
  • Ask all those instructions, and screens if there's, if they will use one or more images ;
  • Search if those images are already in its cache ;
  • Load the images that aren't in its cache ;
  • effectively proceed the Python code that come right after the dialog line, while holding the result for when the player have finished to read it.
This take way more times than a bunch of if.

Even if you add all the gains together, this for all the people who will play your game, the optimization you made will never reach the time you've lost thinking about a better approach than a bunch of if and coding it.


As for more critical parts, even them don't need optimization.
You talked about reaching 60fps, but you did it without even thinking. You're talking about Python, and therefore about Ren'py, a game engine designed for Visual Novels. Even if Ren'Py can do more than this, what exactly is the interest to reach 60 fps in a VN ? What is the interest to reach 60 fps in the features that you could possibly want to include in your VN ?
At worse, if you really need to have 60 fps for your game, the problem is not in the lack of optimization of your code, but in the lack of thinking when picking the game engine ; Ren'Py is clearly not the one you should have used in the first place.

Yet, if you really want do reach a high fps rating, it's totally possible with Ren'Py. It's fastest refresh rate is 0.015 second, therefore a little more than 66 fps is it's maximal outside of pure videos. And it's amazing what you can already do during those 0.015 second. By example, you can start from this:
You don't have permission to view the spoiler content. Log in or register now.
and four others related images to form a 5 frames animation, and obtain that :
You don't have permission to view the spoiler content. Log in or register now.

All this is done in real time, and displayed at 50fps.
And by "all this" I mean:
  • Turing the image into a blued version ;
  • Adding the alpha channel ;
  • Moving the ray beam ;
  • Switching the lines for the undulation ;
  • Advancing the undulation pattern ;
  • Deciding if there will be a glitch or not, and where it will happen ;
  • Switching the lines for the glitch if it happen.

The code is in Python, the result is handled by Ren'Py, and it's not really optimized. I past one day profiling every parts, testing variations and some optimizations, and there's no way to gain enough to even add 1 fps.

So, it's really not the use of nested if that will impact the speed in a Ren'Py game. It clearly hurt your mind that one can write so not optimized code, but trying to do better will lead to one, and only one, thing: You'll loose your time.
 

Paz

Active Member
Aug 9, 2016
913
1,453
I understand your point of view its by far the most sensible one posted against. This but the problem is this doesn't simply end in milliseconds it becomes seconds relatively fast. So then the next time you play a game and wonder why it takes several seconds to load that next scene this is usually the case from the code I looked at when it comes to games on here.
Except it's not, I'm sorry. I can guarantee you, there's is almost never a case in RenPy where you see noticeable lag and that would be caused by the code logic, unless you do it on purpose.
It will be the presentation layer that still takes up most of the cycles (image/screen prediction, screen redraws, image unpacking and rendering, etc, etc.). anne O'nymous 's example is pretty telling.

But let's assume this is actually the case anyway. Any creator will almost always opt for maintainable code over the absolute most performant one.
And by "maintainable" I mean, they want to know roughly how it works because it's themselves they'll have to use or change in the future. Having a bit of code that looks like arcane magic to them will bite them in the ass eventually, even if it supposedly allows them to show a screen 0.0001 seconds faster.
 
  • Like
Reactions: Fatalmasterpiece

Diconica

Well-Known Member
Apr 25, 2020
1,101
1,150
Except it's not, I'm sorry. I can guarantee you, there's is almost never a case in RenPy where you see noticeable lag and that would be caused by the code logic, unless you do it on purpose.
It will be the presentation layer that still takes up most of the cycles (image/screen prediction, screen redraws, image unpacking and rendering, etc, etc.). anne O'nymous 's example is pretty telling.

But let's assume this is actually the case anyway. Any creator will almost always opt for maintainable code over the absolute most performant one.
And by "maintainable" I mean, they want to know roughly how it works because it's themselves they'll have to use or change in the future. Having a bit of code that looks like arcane magic to them will bite them in the ass eventually, even if it supposedly allows them to show a screen 0.0001 seconds faster.
I had them on ignore for ages now.
I'll reply to him then reply to this after.
 

Diconica

Well-Known Member
Apr 25, 2020
1,101
1,150
But in the same time, his code is broke.

Firstly, and unlike you, he don't test if the key is present in the dictionary. And he'll discover the issue once he'll be effectively using his class in production. Unless he have an event for every single minute of every single day and for every single location, what I really doubt, his class will inevitably lead to a crash.
Actually, I'm taking advantage of how the code works.
See it returns a null if the key isn't in the dictionary. That's why I simply do the "if r:"
So if r exists then I run r()

Look for yourself at the code before you listen to this guy.
Python:
def find():
    n = 0
    s = len(AR)
    for x in range(0,lookup):
        r = random.randint(0,s)
        rs = LT.get(AR[r])
        if rs:                                #<-This right here is the shit he says doesn't exist. (Get returns NULL if the item doesn't exist)
            n+=1
If it doesn't exist it just doesn't try and run it.
So it doesn't matter if there is an entry for that hour or minute.
I tested the code against that issue.

Secondly, as designed, his class can not be used by more than an unique object. There's people who could decide, by example, to speed up the processing by splitting the events by location:
The primary reason was to separate event types.
It allowed separating event types.
The one demonstrated just allows storing any location day and time
Another one I am using uses location and an occupancy list
Another event type is single use events.
Then events that you can load in and remove
It allowed me to create different event types that I could treat differently.

This means I can create one shot events and use basically the same code I do for the other just with slightly different loader.
I can create events that are available for a period of time
I can even create events that are made different events combined in different ways.
I can create another instance of it in characters and create events per each character.

At the end of it all I have to do is create a single check function that runs the check for each of the event systems combined.
 
Last edited:

Diconica

Well-Known Member
Apr 25, 2020
1,101
1,150
Here, it's you trying to make your truth sound real, nothing more. At no time in need the value, and therefore at to time it is asking for it. This limit in to the search of the key, without even the need to know if it effectively have a value.
The effective pseudo-code for the two look more like this:
Code:
get(key)
found hash(key) ? value[hash(key)] : None

in(key)
found hash(key) ? 1 : 0
And suddenly the result goes against your approach and saying ; as demonstrated by the profiling.

Code:
if something in someDict: someDict[something]()
will always be a bit faster than:
Code:
var = someDict[something]
if var: var()
due to:
  • in being an operator while get is a method.
  • get needing an intermediary assignation to works.
Get does no such check. That proves you didn't even look at the source.

Your sudo code for the in is a laugh. We can tell they didn't do that the same way I can tell they didn't do what I posted below.
First, if they did either of them it would run vastly faster. The one below would be insanely close to the speed of the get().
It's not though. Lastly, we can look at the Source code. You know that shit I linked the hell here on that prior post.
C:
in (key){
return !(!ptr[key]);
}
There is another factor we can use to tell your code is pure bunk.
If what you posted was correct. The get function would be slower than the in() method
We can look at that by counting the machine instructions / ASM.
Also ternary operator in C must return the same data types in both. So your none vs a function pointer isn't even going to compile at all.
 

Diconica

Well-Known Member
Apr 25, 2020
1,101
1,150
Except it's not, I'm sorry. I can guarantee you, there's is almost never a case in RenPy where you see noticeable lag and that would be caused by the code logic, unless you do it on purpose.
It will be the presentation layer that still takes up most of the cycles (image/screen prediction, screen redraws, image unpacking and rendering, etc, etc.). anne O'nymous 's example is pretty telling.

But let's assume this is actually the case anyway. Any creator will almost always opt for maintainable code over the absolute most performant one.
And by "maintainable" I mean, they want to know roughly how it works because it's themselves they'll have to use or change in the future. Having a bit of code that looks like arcane magic to them will bite them in the ass eventually, even if it supposedly allows them to show a screen 0.0001 seconds faster.
Back to you. I just looked at anne O'nymous after I un-ignored him.
As usual that proved to be a waste of time.
He didn't even look at the source even though I linked to it. Beyond obvious.
The only thing I can give him credit for is posting actual renpy script that someone could use.
But it is massively limited in comparison to what I posted. I explained the advantages a bit more in the first of the two replies to him.

As for your statement.
Well I'll give you one example then list what I did to verify my hypothesis in regards to the games and performance.
JikageRising
3803 if statements not including those in dialog,
444 elif,
1355 else

I used this sites search system because you can actually limit down to various game types search for key words and include tags. A couple tools I had to make use of include
rpatool.py
unrpyc

The first tool is used to extract archives
The second is to convert rpyc files back to code that is readable

Keywords I used to search were laggy and slow
I had to make a determination if the lagg was caused by another issue or game code.
In most cases things like video playback issues I would attribute to other factors. In some cases of video playback it wasn't actual video they were doing but playing a list of images and depending on how that was done. That some times was a coding issue but not the type I was looking for.
The primary coding issues I was looking for was slow updates to scene loading.
Usually this came down to how dialog was being selected to placed on the screen.

You can run a performance profile renpies game flow. It's not hard. Use a line of python to write to the file at the start and end of each section of code. Include section name and time stamp in milliseconds or microseconds
You can use profile software or save a dime and use chrome browser to view it.
You just need to store the data in the same format chrome does for profiling web pages.

You can also do another little trick.
Remember that script I used to write the many if statements.
Well there is something quite the opposite.
You can write one to go through the file and sort nested if statements.
It then can combine them to create text to write all those tuple entries.
You can then create generic functions to act as a wrapper for the various code sections.
Yep, what I am talking about is a python script that can automatically replace all those nest if statements with a dictionary system.
That kind of thing can save a bit of work. Turn something that would take hours in to running a script.

I might normally say, "If someone asked nicely I might give them a copy of such a script."
Yea, I thinks nice is kind of passed this conversation by.
If someone wants it money is going to need to do the talking.

That or you could write the script yourself. It took maybe 30 minutes for me to do.

Now I didn't check all 3609 renpy games on here.
Hell I didn't check everyone that has a problem.
I even eliminated the ones I figured were related to other issues. (that's a long list) i had to look at more than one complaint per a game. To even determine the type of issue fit what i was looking for.
I found other stupid shit in the process. example: Using recursion to go through a list of characters to update.
I noticed a good bit of games in the abandoned area with lagg complaints had that commonality.
Anyway I looked at over 150 games I didn't get to 200 I pretty much was sure by that point. This was a factor.
It might not be every games issue it sure as hell is a lot of these games issues.

But, I'd like to hear how you came to your conclusion. Well I already know the part were you listened anne O'nymous
But you apparently didn't bother to really evaluate what he posted.
He made a false claim I didn't do a check. Then he went on to post bogus code regarding in and get and clearly didn't even look at the actual source code that I linked to renpy's compiler.


Example:
How many games did you check and how did you sort out the different issues?
Did you just run a profile or did you replace code?
Did you do any hard test beside profiling such as code replacements? Even if it was as simple as removing chunks of code to see if the problem was in that section. Maybe you commented out or actually deleted it.
Yep, I would love to know what you actually did.

I'm pretty certain you didn't use a script to replace code section with improved code and no one else on the site is currently or has shared such a script. So I think we can eliminate that.
 

Paz

Active Member
Aug 9, 2016
913
1,453
Back to you. I just looked at anne O'nymous after I un-ignored him.
As usual that proved to be a waste of time.
He didn't even look at the source even though I linked to it. Beyond obvious.
The only thing I can give him credit for is posting actual renpy script that someone could use.
But it is massively limited in comparison to what I posted. I explained the advantages a bit more in the first of the two replies to him.

...

The primary coding issues I was looking for was slow updates to scene loading.
Usually this came down to how dialog was being selected to placed on the screen.

...
All that text and no actual metrics which show that eliminating "bad practices" has an actual effect on apparent lag.
Since you like profiling stuff, maybe you'd be interested in profiling what percentage is used by game logic and evaluation and what percentage by the renderer etc.


But, I'd like to hear how you came to your conclusion. Well I already know the part were you listened anne O'nymous
But you apparently didn't bother to really evaluate what he posted.
He made a false claim I didn't do a check. Then he went on to post bogus code regarding in and get and clearly didn't even look at the actual source code that I linked to renpy's compiler.


Example:
How many games did you check and how did you sort out the different issues?
Did you just run a profile or did you replace code?
Did you do any hard test beside profiling such as code replacements? Even if it was as simple as removing chunks of code to see if the problem was in that section. Maybe you commented out or actually deleted it.
Yep, I would love to know what you actually did.
I was involved in actually coding about a dozen games and putting them out there instead of posting code snippets or trying to optimize things there is next to no need of optimizing. I hope that answers your question.

Look, I have a feeling we're running in circles here. You claim that your method shaves off precious tenths of a millisecond per check. This might even be true and I never argued against that anywhere.
What you apparently fail to understand is that it is entirely inconsequential when it comes to the bigger picture.
There's so much many things happening at the same time to show something on screen, things far more elaborate and heavy than an equality check or a basic lookup that those things simply don't matter.
 

Diconica

Well-Known Member
Apr 25, 2020
1,101
1,150
All that text and no actual metrics which show that eliminating "bad practices" has an actual effect on apparent lag.
Since you like profiling stuff, maybe you'd be interested in profiling what percentage is used by game logic and evaluation and what percentage by the renderer etc.

I was involved in actually coding about a dozen games and putting them out there instead of posting code snippets or trying to optimize things there is next to no need of optimizing. I hope that answers your question.

Look, I have a feeling we're running in circles here. You claim that your method shaves off precious tenths of a millisecond per check. This might even be true and I never argued against that anywhere.
What you apparently fail to understand is that it is entirely inconsequential when it comes to the bigger picture.
There's so much many things happening at the same time to show something on screen, things far more elaborate and heavy than an equality check or a basic lookup that those things simply don't matter.
Where to start?
Sorry.
So I spent the last day diving into Renpy source even deeper and wanted to see how much of a problem stuff was and how optimized it is and how much of what problems lie where.
If you want to know exactly how deep I went. Probably over board. This is a result of it.

I rebuilt one of my game engines using pygame as a base to see what level of performance I could get from it to compare to this and my own C++ version. Its a fairly heavily optimized.
I did however manage to get a 1000 balls bouncing across screen in 1080p at 60+ fps.
It's not the 40,000 I have on my C++ game but certainly enough power to do what we are on here.

Looking at python, pygame and Renpy. Renpy is the dog here. It can certainly be optimized a good deal more.
In my own current pyEngine I was worried how much nested functions would effect the performance.
So I tested with them in and out. No significant change was noted.

My conclusion at this point is:
If you are skilled enough that the issue doesn't rest with your code. Then its probably a good idea to push renpy to the side.
Given what I was able to do in the time I had last night and today I'd say it would just be worth while to do something like I did.
For that matter feel free to use what I posted up there.

I'm saying that because the amount of work it would take to make renpy perform to that level isn't going to be an over night task. Hell, I can't even write a script that would help enough to clean it up. Well I guess I could. If you counted replacing the render pipeline and update system ... making use of texture optimization...
One big issue is the rollback system.

I'd scrap the current system. There is a better method for doing it. You store the operation and value changes for each scene.
Each action has a path id. That way all you need is the path id to do the role back. It's something I came up with for an AI that would traverse terrain and then need to get back. In this case as the person hits the back it would look at the prior path node. Go back there and conduct the reverse operation to the values that changed. In short all you ever need is the current value stored.

I'm pretty amazed some of these games run as well as they do given the issues I found when comparing it.
So yep making those changes won't make near the amount of difference that optimizing Renpy could.
That said I don't think most the new people are at the skill level they can do a great deal more than worry about their own code and its effect. In the great view of things they just adding bricks to a fairly large pile to start with.

If you do run that demo:
F1 will switch you to full screen. You can also resize the screen and so on.
That most more of a pain to setup using pygame than c++.
 

Dark_Sytze

Newbie
Mar 22, 2021
39
242
I feel like this thread is missing a really really large point of why people use Renpy. Just look at the sheer amount of games here that are developed by either a single person, or maybe two people. Between doing artwork, telling the story and having to make it work in Renpy I think you will find that maybe like 75% won't get more advanced than an if/else statement (I certainly can't in python).
Sure having fancy code that makes it faster is nice, but if you don't understand a single thing it does it's not very useful at all. Judging by the amount of "failed/abandoned" projects here most people are already in over their heads. Having to spend another full week learning the ins and outs of python is just not realistic.
 

Paz

Active Member
Aug 9, 2016
913
1,453
Where to start?
Sorry.
So I spent the last day diving into Renpy source even deeper and wanted to see how much of a problem stuff was and how optimized it is and how much of what problems lie where.
If you want to know exactly how deep I went. Probably over board. This is a result of it.

I rebuilt one of my game engines using pygame as a base to see what level of performance I could get from it to compare to this and my own C++ version. Its a fairly heavily optimized.
I did however manage to get a 1000 balls bouncing across screen in 1080p at 60+ fps.
It's not the 40,000 I have on my C++ game but certainly enough power to do what we are on here.

Looking at python, pygame and Renpy. Renpy is the dog here. It can certainly be optimized a good deal more.
In my own current pyEngine I was worried how much nested functions would effect the performance.
So I tested with them in and out. No significant change was noted.
Interesting, I will probably have a look at some point.

My conclusion at this point is:
If you are skilled enough that the issue doesn't rest with your code. Then its probably a good idea to push renpy to the side.
Given what I was able to do in the time I had last night and today I'd say it would just be worth while to do something like I did.
For that matter feel free to use what I posted up there.

I'm pretty amazed some of these games run as well as they do given the issues I found when comparing it.
So yep making those changes won't make near the amount of difference that optimizing Renpy could.
That said I don't think most the new people are at the skill level they can do a great deal more than worry about their own code and its effect. In the great view of things they just adding bricks to a fairly large pile to start with.
Which is exactly the purpose of RenPy. To be as approachable as possible. Sure, if you can code your own engine you don't have to use RenPy, but hardly any creator out there can.
When you try to make something as streamlined as possible and with a very low entry barrier, you cut corners in raw performance, it's just how it is.

The whole point is for a framework that people with little/no coding background can use as easily as possible, not try to take UE head on in performance. And it just works for the kind of games that utilize it.
We're not talking about professional studios here, but hobbyists that try to make a game.