Where ?
I searched here and on google, I found nothing. Well, nothing except your recent messages on this subject in a game thread. But without more proof of the problem than you gave here.
I searched in Ren'py's code, there's no test of the stack limit. I grepped it, at no time the word "stack" is used in an error message.
So, I performed some test. The size of a return stack entry being relatively fix, this was enough to have a better view of the problem :
Code:
label called:
$ depth = renpy.call_stack_depth()
"Stack depth [depth]"
call called
label start:
call called
and there nothing like a "stack filled error".
There's an error when Ren'py come around the 62 000 entries in the return stack, but it's a memory use one :
Code:
File "L:\devel\renpy\renpy\python.py", line 1190, in __init__
self.context = renpy.game.context().rollback_copy()
File "L:\devel\renpy\renpy\execution.py", line 717, in rollback_copy
rv.abnormal_stack = list(self.abnormal_stack)
MemoryError:
Ren'py already used 1.5 GB at this time. And like Ren'py use the 32 bits version of Python :
Code:
[...]\super powered - 0.38\lib\windows-i686>python -v
[...]
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
the copy made it hit the
You must be registered to see the links
which is of 2GB. Ren'py received the MemoryError exception thrown by Python (on its own, because it thought that the limit was here), logged it and silently died.
The fact that the test was running without image have no impact on the result since the default cache size used by Ren'py for the image is of
You must be registered to see the links
. On real use, the error would have happened around the 55 000 entries.
In most modern languages (if not all), internally arrays are created to have X entries by default, then have their size increased by X once they are filled. This while the addition to an entry at the end of the array is just the assignation of a pointer. And you don't need more time to do this if the array have a million entries, than you need if it only have three entries ; unless the implementation is shitty and don't keep track of the next free index.
The only point that can possibly slowdown the process because of the size of the array, is when the said size is extended. Yet it only apply if the whole array (the pointers) is copied to the newly allocated memory space. Even if the array is implemented as a chained list, in place of a more effective algorithm, it will only need the time necessary to the allocation of the new memory space and the update of the last segment of the array ; so it will be atomic even with older computers.
The size of the array is a cost only when you need to access a specific entries, or to perform manipulation on the array. But here it's a LIFO stack. Everything always happen at the end of the array, which is assured to be present on all the caches, and everything is just a writing or reading of a pointer. Therefore it's atomic with any CPU since the early 90's ; even slower algorithm should need less than 20 ticks to do this.
The only impacting point is, like I said above, the (shallow) copy made during the rollback.
And ? All this have nothing to do with the
call
statements.
A Ren'py game itself is purely 100% events free. You can't interrupt the flow of the game, you can just change it. The fact that the screens are updated more or less every 5 seconds when there's no changes in the game, and the fact that Ren'py pass its time to predict the future statements, have no influence on the size of the return stack.
As for the influence on the RAM user space, it happen only at the start of the game, before the cache is effectively filled up to its limit. Therefore, this influence happen before the size of the return stack start to possibly be a problem.
The said stack will grow only when a
call
statement is proceeded, and the said statement can only be proceeded after an interaction coming from the player. There can be more than one
call
behind this interaction, but they'll all stop once Ren'py end its "interaction" ; so once a dialog line will be displayed, a screen will be called, or the
renpy.input
will be used.
Absolutely not.
The problem implied by the rollback is that it (shallow) copy the variables, including the return stack. The time needed to make this copy is obviously 100% dependent of the size of the return stack, and 0% dependent of the number of copies you previously made.
You can have 1 maximal rollback points or 1000, you'll need the same amount of time to copy a 1000 entries list. A time that is bigger than the one needed to copy a 10 entries list.
This said, a smaller number of rollback point permit you to have a bigger return stack, since it occupy less space in RAM.
Or for those who don't want/can't log on Google,
You must be registered to see the links
.