Affogado

Newbie
Game Developer
Jun 12, 2021
86
144
Oni also said in a comment that he's considering taking time to optimize the game. I'm considering asking to lend a hand... Like , let alone running renpy on top of it. But doing straight loops for event checking will make that a lot slower.
Introduce Oni to state machines, see what happens
 

sleepingkirby

Active Member
Aug 8, 2017
655
966
Introduce Oni to state machines, see what happens
Technically, that's what he's using now. The problem with an infinite number of states is that humans can't account for the infinite combinations. And, in programming, you still need to check the states to know which state(s) goes to which event. And honestly, that's what Zelda: BOTW and TOTK is using and that's the reason why Nintendo desperately tries but can't get bugs out of the game. Like, that's the reason why you can't shield surf off of enemies' heads any more.

I was thinking more of a event registration system that queues events on variable change. Which is naturally what renpy does anyways whenever you run setvariable().
 

sleepingkirby

Active Member
Aug 8, 2017
655
966
Python is easy to code, easy to read and easy to debug.
We'll agree to disagree there. Python's inclination to rename common data structures and types can makes things hard to read and that's ignoring the python 2 vs python 3 split and/or lack of backwards compatibility. Also, if you're 5+ layers deep (or if the block is really long), the advantage of the whitespace block enclosures gets lost pretty easily.

Like, I've heard all of those before and that's what people say, but practically, it's not that different than most popular languages these days. Hell, the *nix version of the cheat injector for this game was jammed out in, like, 20 minutes as compared to the windows version that runs on a .py file that takes a while just to troubleshoot.

So I suggest changing the architecture of the code before switching the language:
No one is talking about changing languages. My statement is simply that python is a pretty slow language. It's best to not put slower/more burdenson algorithm on an already slow language/framework. The slower the language, the more the need to have better and/or faster algorithms.

Renpy is easy to use and easy to pick up. It would be nice if it was faster or didn't run an interpretive layer to run python code when it itself is running python, but that's the reality as it currently stands. It's popular for a reason. It's like a fischer-price bigwheel. It's easy to get into, to start using. But you can't strap an engine to it and send it down the highway at 50 mph without some serious and considerable re-enforcing and re-designing.
 
Sep 21, 2019
165
121
We'll agree to disagree there. Python's inclination to rename common data structures and types can makes things hard to read and that's ignoring the python 2 vs python 3 split and/or lack of backwards compatibility. Also, if you're 5+ layers deep (or if the block is really long), the advantage of the whitespace block enclosures gets lost pretty easily.

Like, I've heard all of those before and that's what people say, but practically, it's not that different than most popular languages these days. Hell, the *nix version of the cheat injector for this game was jammed out in, like, 20 minutes as compared to the windows version that runs on a .py file that takes a while just to troubleshoot.
Actually, I agree with your points! :D
I don't think this project requires super complicated data structures or code though, as far as I saw I felt like many of the long series of nested if/else are unnecessary, but yeah we can agree to disagree. My intuition may be clearly wrong about what this project requires: I may end up agreeing with you if I look deeper.

No one is talking about changing languages. My statement is simply that python is a pretty slow language. It's best to not put slower/more burdenson algorithm on an already slow language/framework. The slower the language, the more the need to have better and/or faster algorithms.

Renpy is easy to use and easy to pick up. It would be nice if it was faster or didn't run an interpretive layer to run python code when it itself is running python, but that's the reality as it currently stands. It's popular for a reason. It's like a fischer-price bigwheel. It's easy to get into, to start using. But you can't strap an engine to it and send it down the highway at 50 mph without some serious and considerable re-enforcing and re-designing.
Oops I misunderstood you then! My bad! Then I think we agree here. No point to expect super fast code, but I feel like faster code is definitely possible: maybe enough that players won't notice.
 
  • Like
Reactions: sleepingkirby

sleepingkirby

Active Member
Aug 8, 2017
655
966
I don't think this project requires super complicated data structures or code though, as far as I saw I felt like many of the long series of nested if/else are unnecessary, but yeah we can agree to disagree. My intuition may be clearly wrong about what this project requires: I may end up agreeing with you if I look deeper.
Well, complexity is relative, right? Basically, my idea is to have a queue (or many) of events to run. That queue is checked at certain key points. That queue is only added to if, after variable changes, that certain conditions are met. So, like, let's say when you wake up in your bedroom, checks are needed. Rather than checking for all the events, you're just running through the queue and running the first event in that queue. The event itself can also have conditions like time checks or character checks.

Basically, if you think about it, it's distributing all the event checks from one or two points in the game to all through out the game. Theoretically, you can also create a tree for each character and each variable change too to minimize the checks for adding to the queue. So Laura only adds her events. And if love was the last thing to be increased, you'd only need to check to queue Laura love events.

I mean, if I REALLY wanted to complicate things, I made a binary tree data structure that can do ranged checks a while back. And that can be compiled from a flat list then cached on game compile. But I think that'd be overkill.
 
  • Wow
Reactions: RandomFapinator
Sep 21, 2019
165
121
Well, complexity is relative, right? Basically, my idea is to have a queue (or many) of events to run. That queue is checked at certain key points. That queue is only added to if, after variable changes, that certain conditions are met. So, like, let's say when you wake up in your bedroom, checks are needed. Rather than checking for all the events, you're just running through the queue and running the first event in that queue. The event itself can also have conditions like time checks or character checks.

Basically, if you think about it, it's distributing all the event checks from one or two points in the game to all through out the game. Theoretically, you can also create a tree for each character and each variable change too to minimize the checks for adding to the queue. So Laura only adds her events. And if love was the last thing to be increased, you'd only need to check to queue Laura love events.

I mean, if I REALLY wanted to complicate things, I made a binary tree data structure that can do ranged checks a while back. And that can be compiled from a flat list then cached on game compile. But I think that'd be overkill.
Ok maybe I am a bit stupid but does a FIFO queue per timeslot do what you wish? Or a priority queue instead to account for more than a week? You can fix the max number of events per FIFO queue for internal optimization too.


I've never done Renpy, but can you use python libraries in Renpy? If you can't then my suggestion is useless anyway. I agree that hand-coding your own binary tree clearly seems overkill. You must truly be a dedicated fan :)
 

sleepingkirby

Active Member
Aug 8, 2017
655
966
Ok maybe I am a bit stupid but does a FIFO queue per timeslot do what you wish? Or a priority queue instead to account for more than a week? You can fix the max number of events per FIFO queue for internal optimization too.
Not really. You're kind of thinking of it backwards. You're trying to match the problem to the data structure instead of the data structure to the problem. No matter what happens, that game has to know what to run at a certain point. That might be timeslot, but that might also be location (entering the classroom, for example). But also consider that some events should take priority over others to prevent continuity errors or skip events altogether. So FIFO queues can work, but really, all you need is an array (they call that a list in python, right?). Most modern and/or interpreted languages should have the capability to push, pop, shift and unshift to an array. So you push an object to the array. The object can be like:
charname: "Laura",
priority: 5,
check: "Love>900"

And since it's an array, you can sort the array by priority at the time of pushing it into the array. So when the queue is read from, it can automatically find the first event to run which has the highest priority. There are other ways of doing this, but that is just an example off the top of my head.

And yes, when using a language, you should lean on the parts of the language that it has optimized. But remember, if you're using something just to use it, often times any benefits from the language optimization is lost. Basically, if I can give you any programming advice to you, it's that you (try to) make the solution to the problem, not change the problem to match your solution.

I've never done Renpy, but can you use python libraries in Renpy? If you can't then my suggestion is useless anyway. I agree that hand-coding your own binary tree clearly seems overkill.
Honestly, I'm not sure either, but I think you can. If you look in <game>/lib/ you'll see the actual python binary and the libraries it comes with. I imagine it wouldn't be too hard to include custom libraries in there.

You must truly be a dedicated fan :)
No, not really. This is my job (or rather, has been my job. Looking for a new job atm). I just happen to like my job. This is like asking your professional chef friend what he thought of your pasta sauce and he suddenly starts hand-making ravioli to pair with your sauce. For you, that's a big deal. For him, it's Tuesday.
 
Last edited:
  • Like
Reactions: RandomFapinator
Sep 21, 2019
165
121
Not really. You're kind of thinking of it backwards. You're trying to match the problem to the data structure instead of the data structure to the problem. No matter what happens, that game has to know what to run at a certain point. That might be timeslot, but that might also be location (entering the classroom, for example). But also consider that some events should take priority over others to prevent continuity errors or skip events altogether. So FIFO queues can work, but really, all you need is an array (they call that a list in python, right?). Most modern and/or interpreted languages should have the capability to push, pop, shift and unshift to an array. So you push an object to the array. The object can be like:
charname: "Laura",
priority: 5,
check: "Love>900"

And since it's an array, you can sort the array by priority at the time of pushing it into the array. So when the queue is read from, it can automatically find the first event to run which has the highest priority. There are other ways of doing this, but that is just an example off the top of my head.
Oh no lol, I thought of the problem quickly and it popped up in my head, not the other way around. Right, it could also be location based and not timed based. But... aren't FIFO queues of small pre-determined size already implemented/interpreted as arrays with extra index information in optimized libraries? Or this isn't the case in the Python binaries? Genuinely curious.
I would completely agree with your approach on low-level languages. But even then, you might miss out on potential compiler optimization or hardware intrinsics unless you plan to use them.

And yes, when using a language, you should lean on the parts of the language that it has optimized. But remember, if you're using something just to use it, often times any benefits from the language optimization is lost. Basically, if I can give you any programming advice to you, it's that you (try to) make the solution to the problem, not change the problem to match your solution.
We agree here: trying to make your own data structure in high-level languages (Python) usually results in slower performance than using native libraries unless we are dealing with large scale problems (which I assume is not the case here). I am just afraid that if you want to efficiently implement your own data structure and the operations within it, you would have to resort to things like and try to do better than <stdlib.h> in C and that may be overkill for a game of this size.

No, not really. This is my job (or rather, has been my job. Looking for a new job atm). I just happen to like my job. This is like asking your professional chef friend what he thought of your pasta sauce and he suddenly starts hand-making ravioli to pair with your sauce. For you, that's a big deal. For him, it's Tuesday.
I am not a Python specialist, so I will assume you know better :) I hope you can help the dev (and that the dev accepts it?), that would be great for the community! Looking forward to what you can do!
 

sleepingkirby

Active Member
Aug 8, 2017
655
966
Oh no lol, I thought of the problem quickly and it popped up in my head, not the other way around. Right, it could also be location based and not timed based.
I'm not an expert in python either. I actually loathe the language. But you work with what you have, not what you wish to have or want.

But... aren't FIFO queues of small pre-determined size already implemented/interpreted as arrays with extra index information in optimized libraries? Or this isn't the case in the Python binaries? Genuinely curious.
I don't know 100% for sure, but if something's built on top of arrays, it's not going to be faster than an array. You can't get faster than the thing you're using. If it has extra index information, that's going to slow it down because it has to process, keep track, etc. that index information. Arrays in ASM, if my memory serves, is literally implemented and moved via memory (ram) jumps. In computing, the only things faster than ram jumps and reads are register reads.
I should also mention that predetermined size is a bad idea in this particular case. While good for reads and jumps, you don't want a case where you'll need to constantly resize the limited array as that will, usually, quickly overshadow and performance gains. And since we don't know the max size of all possible events (now and in the future), nor do we want to pre-set an absurdly large size for all eternity, it's better to stick with an expand-able array for now.

With that said, something compiled to a binary doesn't guarantee it's speed. It only, sometimes, guarantees that the interpreter doesn't have to re-translate/compile it down asm code again (sometimes because Java binaries still need to run through a java virtual machine). Optimized also don't guarantee a speed up. It's just written in a way to trim down read and/or run time and/or use different techniques to try to run the fastest version of an algorithm for the situation.

I'm writing the above just in case you have the common misconception that optimized code can run better than barebones code or a different data structure that is closer to solution of the problem. I once knew someone that though that the array optimization in javascript would make array searches as fast as or faster than a hash look up. I ran some tests to find that, while it is fast, direct hash look ups are faster. And that guy wasn't dumb nor a bad programmer, but these misconceptions do pop up in this tech industry.


I would completely agree with your approach on low-level languages. But even then, you might miss out on potential compiler optimization or hardware intrinsics unless you plan to use them.
You might, but you might not. And the compiler optimization might not be faster than what you've created from scratch. It's important to know what the optimization is and when to use it. Looking at the queue object you linked, it's not just providing a FIFO queue, but also:
The module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The class in this module implements all the required locking semantics.
All those multi-thread features (locking, guaranteeing consistency, preventing deadlocks, etc.) are more work in addition to adding the data to the queue. So, inherently, if the queue module is built on top of arrays and is providing all those as features, it will be slower than straight arrays. Conversely, if array speed is that much of a concern for the language, they should already have built in optimization for array functions. If they don't, well, that's on them (the makers and maintainers of python).



We agree here: trying to make your own data structure in high-level languages (Python) usually results in slower performance than using native libraries unless we are dealing with large scale problems (which I assume is not the case here). I am just afraid that if you want to efficiently implement your own data structure and the operations within it, you would have to resort to things like and try to do better than <stdlib.h> in C and that may be overkill for a game of this size.
Agreed. But I would like to warn you about putting libraries on pedestals. In the end, it all computing languages translate the code down to ASM. Just because a library is often used or is native, it doesn't guarantee it'll run better or faster. Again, conversely, if me implementing my own array is slower than a native library's array, the language has a problem. Something as basic as an array should already have it's own optimization. If it doesn't, that's not a language you want to stick with for very long.

I am not a Python specialist, so I will assume you know better :) I hope you can help the dev (and that the dev accepts it?), that would be great for the community! Looking forward to what you can do!
It'll depend on me too. As LeatherMax can attest to, I've been trying to get my own stuff done for a while now. Thought it would a few weeks at most. Life had other plans. There's a lot I would like to make/build/fix. Desmume on the linux side needs a memory scanner. I know this forum has a PHP dev position that's been open since forever. I still have other pet projects/ideas after the current 2 I'm working on.
 
Last edited:
Sep 21, 2019
165
121
I don't know 100% for sure, but if something's built on top of arrays, it's not going to be faster than an array. You can't get faster than the thing you're using. If it has extra index information, that's going to slow it down because it has to process, keep track, etc. that index information. Arrays in ASM, if my memory serves, is literally implemented and moved via memory (ram) jumps. In computing, the only things faster than ram jumps and reads are register reads.
I should also mention that predetermined size is a bad idea in this particular case. While good for reads and jumps, you don't want a case where you'll need to constantly resize the limited array as that will, usually, quickly overshadow and performance gains. And since we don't know the max size of all possible events (now and in the future), nor do we want to pre-set an absurdly large size for all eternity, it's better to stick with an expand-able array for now.

With that said, something compiled to a binary doesn't guarantee it's speed. It only, sometimes, guarantees that the interpreter doesn't have to re-translate/compile it down asm code again (sometimes because Java binaries still need to run through a java machine). Optimized also don't guarantee a speed up. It's just written in a way to trim down read and/or run time and/or use different techniques to try to run the fastest version of an algorithm for the situation.

I'm writing the above just in case you have the common misconception that optimized code can run better than barebones code or a different data structure that is closer to solution of the problem. I once knew someone that though that the array optimization in javascript would make array searches as fast as or faster than a hash look up. I ran some tests to find that, while it is fast, direct hash look ups are faster. And that guy wasn't dumb nor a bad programmer, but these misconceptions do pop up in this tech industry.
Completely agree with this. Thought the dev would know a max number in advance (number of girls and event per girls are limited after all... right?), but maybe that's not even a good solution?

All those multi-thread features (locking, guaranteeing consistency, preventing deadlocks, etc.) are more work in addition to adding the data to the queue. So, inherently, if the queue module is built on top of arrays and is providing all those as features, it will be slower than straight arrays. Conversely, if array speed is that much of a concern for the language, they should already have built in optimization for array functions. If they don't, well, that's on them (the makers and maintainers of python).
Completely agree on this. If it's not implemented as a low-level structure it may be clearly slower.

Agreed. But I would like to warn you about putting libraries on pedestals. In the end, it all computing languages translate the code down to ASM. Just because a library is often used or is native, it doesn't guarantee it'll run better or faster. Again, conversely, if me implementing my own array is slower than a native library's array, the language has a problem. Something as basic as an array should already have it's own optimization. If it doesn't, that's not a language you want to stick with for very long.
Hard agree. Sadly, some people stick with antiquities because they don't want to break legacy code :(
I am just slighly worried because even an integer in python has its own internal data structure: it's not like an int in C. Then is the code written with Renpy even compiled? If it's just interpreted... ouch.

It'll depend on me too. As LeatherMax can attest to, I've been trying to get my own stuff done for a while now. Thought it would a few weeks at most. Life had other plans. There's a lot I would like to make/build/fix. Desmume on the linux side needs a memory scanner. I know this forum has a PHP dev position that's been open since forever. I still have other pet projects/ideas after the current 2 I'm working on.
I see. Good luck to you, this has been informative thank you, real life is more important than a porn game (or is it????).
 
  • Like
Reactions: sleepingkirby

sleepingkirby

Active Member
Aug 8, 2017
655
966
Completely agree with this. Thought the dev would know a max number in advance (number of girls and event per girls are limited after all... right?)
You'd be surprised. Game development is not like programming. You don't always get to know the domain of your input. And even if you do, that might change as the game changes.


Hard agree. Sadly, some people stick with antiquities because they don't want to break legacy code :(
I am just slighly worried because even an integer in python has its own internal data structure: it's not like an int in C. Then is the code written with Renpy even compiled? If it's just interpreted... ouch.
Yes...maybe. Some game will only ship with .rpyc code. Rpyc, as you can probably guess, is "compiled" bytecode. Depending on how you look at it, . But, technically, it's "compiled". Rogue-like ships with both. If I recall correctly, renpy, if the .rpy file exists, will defer to the .rpy file first before the .rpyc file.

I see. Good luck to you, this has been informative thank you, real life is more important than a porn game (or is it????).
Thank you. It's been nice discussing this stuff.
 
  • Red Heart
Reactions: RandomFapinator
4.40 star(s) 154 Votes