Crash on reload on versions prior to 8.2
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.
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.
Crash on reload on versions prior to 8.2
Hi all, so for a long while now I have been stuck with a nasty bug which causes a completely silent crash on auto-reload. The game actually reloads, but then it's just a rotating blue circle cursor followed by CTD.
I have tried a lot of things and at this stage the bug is painfully easy to reproduce:
- I delete all Ren'Py SDK files including persistent files and the 'AppData' renpy folder.
- I install a new version of Ren'py.
- I run "Tutorial", press Shit+R on the title screen, and it crashes.
Interestingly, I run into this issue on every Ren'Py version I've tried except the old 7.3.5 and the brand new 8.2. Sadly, my game is not compatible with 8.2 for other reasons, so what I am looking for is a way to at least log that error so that I can finally do something about it.
Obviously the error has to do with something on my PC, otherwise everyone would have it. Off the top of my head, I can only think about a few things:
- Maybe I'm missing something on how to completely uninstall Ren'py and there is some leftover registry entry or whatever that is screwing with my install
- My computer has two drives, C:/ is restricted to my wife as a user and D:/ to me (where I run Ren'py); Windows is installed on C:/ -> Perhaps something is being accessed without the proper rights?
- Something changed in 8.2 that removed the issue; I'd like to figure out what!
Anyway, I guess the first step would be to catch that error. Is there any way to trace what's happening with auto-reload before it crashes?
I have tried a lot of things and at this stage the bug is painfully easy to reproduce:
- I delete all Ren'Py SDK files including persistent files and the 'AppData' renpy folder.
- I install a new version of Ren'py.
- I run "Tutorial", press Shit+R on the title screen, and it crashes.
Interestingly, I run into this issue on every Ren'Py version I've tried except the old 7.3.5 and the brand new 8.2. Sadly, my game is not compatible with 8.2 for other reasons, so what I am looking for is a way to at least log that error so that I can finally do something about it.
Obviously the error has to do with something on my PC, otherwise everyone would have it. Off the top of my head, I can only think about a few things:
- Maybe I'm missing something on how to completely uninstall Ren'py and there is some leftover registry entry or whatever that is screwing with my install
- My computer has two drives, C:/ is restricted to my wife as a user and D:/ to me (where I run Ren'py); Windows is installed on C:/ -> Perhaps something is being accessed without the proper rights?
- Something changed in 8.2 that removed the issue; I'd like to figure out what!
Anyway, I guess the first step would be to catch that error. Is there any way to trace what's happening with auto-reload before it crashes?
Re: Crash on reload on versions prior to 8.2
Look for files "log.txt", "errors.txt" and "traceback.txt".
Also if you run Ren'Py from command line (terminal), there could be some diagnostic messages.
Also if you run Ren'Py from command line (terminal), there could be some diagnostic messages.
If the problem is solved, please edit the original post and add [SOLVED] to the title.
Re: Crash on reload on versions prior to 8.2
Yup, the game generates no traceback and no errors files. When I say it's a silent crash, I mean it's really really silent.
The same happens with a command prompt.
The only error that I can trace is in Windows event viewer, the one mentioned in the original thread:
Every crash generates that one. That's it.
The same happens with a command prompt.
The only error that I can trace is in Windows event viewer, the one mentioned in the original thread:
Code: Select all
Faulting application name: pythonw.exe, version: 0.0.0.0, time stamp: 0x61a6b501
Faulting module name: MMDevAPI.DLL, version: 10.0.19041.1023, time stamp: 0x00c1ffe2
Exception code: 0xc0000005
Fault offset: 0x000000000001b33b
Faulting process id: 0x6d38
Faulting application start time: 0x01d80bff24ddc8d2
Faulting application path: D:\RenPy\renpy-7.4.9-sdk\lib\windows-x86_64\pythonw.exe
Faulting module path: C:\Windows\SYSTEM32\MMDevAPI.DLL
Report Id: 72c56750-4c60-4c3e-840b-68ccbe45cb73
Faulting package full name:
Faulting package-relative application ID:
Re: Crash on reload on versions prior to 8.2
There can be incompatibilities
(1) between different Ren'Py versions,
(2) and between Python executables and used libraries (DLL in Windows).
In this case there's probably the incompatibility between the Python executable
D:\RenPy\renpy-7.4.9-sdk\lib\windows-x86_64\pythonw.exe
and some system library
C:\Windows\SYSTEM32\MMDevAPI.DLL
Theoretically it's possible to find a version of MMDevAPI.DLL that would work well with this Python executable, but as we are talking about DLL in the system folder, replacing it with another versions might lead to other problems (other programs crashing).
You can try to put the necessary version of DLL in some local folder (maybe where the Python executable is?), I'm not sure, but it might work as that local DLL would be used.
But more adequate solution would be either use the old version of Ren'Py that works with your game, or re-write the parts of your game for the latest Ren'Py.
For example, ProportionalScale can be implemented as CDD
https://renpy.org/doc/html/cdd.html
In __init__ you calculate how the image should be scaled (if the width to height ratio is different for the original and the scaled image, then should the original image be cropped to fit, or a part of the target rectangle should be left blank?). You set the zoom factor accordingly.
In render() you just create the render with the target width & height, and blit there the original image with "zoom" property.
renpy.load_image:
https://renpy.org/doc/html/cdd.html#renpy.load_image
zoom:
https://renpy.org/doc/html/cdd.html#renpy.Render.zoom
(1) between different Ren'Py versions,
(2) and between Python executables and used libraries (DLL in Windows).
In this case there's probably the incompatibility between the Python executable
D:\RenPy\renpy-7.4.9-sdk\lib\windows-x86_64\pythonw.exe
and some system library
C:\Windows\SYSTEM32\MMDevAPI.DLL
Theoretically it's possible to find a version of MMDevAPI.DLL that would work well with this Python executable, but as we are talking about DLL in the system folder, replacing it with another versions might lead to other problems (other programs crashing).
You can try to put the necessary version of DLL in some local folder (maybe where the Python executable is?), I'm not sure, but it might work as that local DLL would be used.
But more adequate solution would be either use the old version of Ren'Py that works with your game, or re-write the parts of your game for the latest Ren'Py.
For example, ProportionalScale can be implemented as CDD
https://renpy.org/doc/html/cdd.html
In __init__ you calculate how the image should be scaled (if the width to height ratio is different for the original and the scaled image, then should the original image be cropped to fit, or a part of the target rectangle should be left blank?). You set the zoom factor accordingly.
In render() you just create the render with the target width & height, and blit there the original image with "zoom" property.
renpy.load_image:
https://renpy.org/doc/html/cdd.html#renpy.load_image
zoom:
https://renpy.org/doc/html/cdd.html#renpy.Render.zoom
If the problem is solved, please edit the original post and add [SOLVED] to the title.
Re: Crash on reload on versions prior to 8.2
Thank you for the suggestions! Yes, I think my best bet is to replace ProportionalScale with something more long-lasting. I'll look into CDDs although it looks way above my level of understanding for now...
Re: Crash on reload on versions prior to 8.2
Here is my attempt to replicate ProportionalScale() using more modern methods:
Edited thanks to jeffster's remarks
I'd be lying if I said I understand everything it's doing, but it seems to work well enough. I would welcome any feedback!
Edited thanks to jeffster's remarks
Code: Select all
class ProportionalScale(renpy.Displayable):
'''Resizes a renpy image to fit into the specified width and height.
The aspect ratio of the image will be conserved.'''
def __init__(self, imgname, maxwidth=None, maxheight=None, **properties):
super(ProportionalScale, self).__init__()
self.width = maxwidth or config.screen_width
self.height = maxheight or config.screen_height
if not renpy.exists(imgname):
imgname = "backgrounds/not_found.webp"
self.image = Transform(imgname, size=(self.width, self.height), fit="contain", **properties)
def render(self, width, height, st, at):
return renpy.render(self.image, self.width, self.height, st, at)
def visit(self):
return [ self.image ]
def per_interact(self):
renpy.redraw(self, 0)
Last edited by goldo on Mon Mar 04, 2024 7:44 pm, edited 1 time in total.
Re: Crash on reload on versions prior to 8.2
It looks close to what I was thinking about, maybe even better.
If you want some nitpicking comments:
I'm not sure if you need methods "visit" and "per_interact".
One simple picture might work without them.
But if they help prediction (I don't know), then maybe it's OK to have them.
Do you need the conversions to int: "int(maxwidth), int(maxheight)"?
"maxwidth" and "maxheight" are probably integers already.
You don't use "self.imgname" anywhere except in __init__, hence it doesn't have to be saved as the object property ("self.").
You don't need to check "if renpy.exists(imgname)", instead it should be a bit more efficient to use "try-except" feature:
(If "try" block causes an error (i.e. an exception), then "except" block is executed).
Using value "if not None" instead of this:
can be done with or operator:
You don't need to get "self.width, self.height" in render() because you already set the resulting width & height (as maxwidth & maxheight), right?
And you never use "bilinear" (you probably don't need to, in modern RenPy).
All that together:
If you want some nitpicking comments:
I'm not sure if you need methods "visit" and "per_interact".
One simple picture might work without them.
But if they help prediction (I don't know), then maybe it's OK to have them.
Do you need the conversions to int: "int(maxwidth), int(maxheight)"?
"maxwidth" and "maxheight" are probably integers already.
You don't use "self.imgname" anywhere except in __init__, hence it doesn't have to be saved as the object property ("self.").
You don't need to check "if renpy.exists(imgname)", instead it should be a bit more efficient to use "try-except" feature:
Code: Select all
try:
self.image = Transform(imgname, size=(maxwidth, maxheight), fit="contain", **properties)
except:
self.image = Transform("backgrounds/not_found.webp", size=(maxwidth, maxheight), fit="contain", **properties)
Using value "if not None" instead of this:
Code: Select all
if not maxwidth: maxwidth = config.screen_width
...
maxwidth
Code: Select all
maxwidth or config.screen_width
And you never use "bilinear" (you probably don't need to, in modern RenPy).
All that together:
Code: Select all
init python:
class ProportionalScale(renpy.Displayable):
'''Resizes a renpy image to fit into the specified width and height.
The aspect ratio of the image will be preserved.'''
def __init__(self, img, maxwidth=None, maxheight=None, **properties):
super(ProportionalScale, self).__init__()
self.w = maxwidth or config.screen_width
self.h = maxheight or config.screen_height
try:
self.image = Transform(img, size=(self.w, self.h),
fit="contain", **properties)
except:
self.image = Transform("backgrounds/not_found.webp", size=(self.w, self.h),
fit="contain", **properties)
def render(self, width, height, st, at):
return renpy.render(self.image, self.w, self.h, st, at)
If the problem is solved, please edit the original post and add [SOLVED] to the title.
Re: Crash on reload on versions prior to 8.2
...And you probably can use just Transform() with size parameter (instead of a custom displayable).
If the problem is solved, please edit the original post and add [SOLVED] to the title.
Re: Crash on reload on versions prior to 8.2
Absolutely!
According to the documentation, 'visit()' is needed for prediction, and 'per_interact()' for rollback. I haven't tried without though.I'm not sure if you need methods "visit" and "per_interact".
One simple picture might work without them.
But if they help prediction (I don't know), then maybe it's OK to have them.
It's just to make this thing foolproof in case I accidentally feeds it a calculation like '0.7* button_size' or something...Do you need the conversions to int: "int(maxwidth), int(maxheight)"?
"maxwidth" and "maxheight" are probably integers already.
That's true, originally the exist check was in the render method so that's why I was saving it but now there is no reason to. I will edit it out.You don't use "self.imgname" anywhere except in __init__, hence it doesn't have to be saved as the object property ("self.").
Sadly 'Transform("this file doesn't even exist", size=(maxwidth, maxheight), fit="contain", **properties)' is a valid instruction so no error will be thrown in that case. I've tried to put the try... except... check in render() but it didn't work, another error was coming up when predicting.You don't need to check "if renpy.exists(imgname)", instead it should be a bit more efficient to use "try-except" feature:Code: Select all
try: self.image = Transform(imgname, size=(maxwidth, maxheight), fit="contain", **properties) except: self.image = Transform("backgrounds/not_found.webp", size=(maxwidth, maxheight), fit="contain", **properties)
Nice, I didn't know that trick!Using value "if not None" instead of this:can be done with or operator:Code: Select all
if not maxwidth: maxwidth = config.screen_width ... maxwidth
Code: Select all
maxwidth or config.screen_width
But then I need to save maxwidth and maxheight as attributes, right?You don't need to get "self.width, self.height" in render() because you already set the resulting width & height (as maxwidth & maxheight), right?
Thanks, I will remove it.And you never use "bilinear" (you probably don't need to, in modern RenPy).
I'll edit the code above to reflect the changes I will keep. Thanks a lot!All that together:Code: Select all
init python: class ProportionalScale(renpy.Displayable): '''Resizes a renpy image to fit into the specified width and height. The aspect ratio of the image will be preserved.''' def __init__(self, img, maxwidth=None, maxheight=None, **properties): super(ProportionalScale, self).__init__() self.w = maxwidth or config.screen_width self.h = maxheight or config.screen_height try: self.image = Transform(img, size=(self.w, self.h), fit="contain", **properties) except: self.image = Transform("backgrounds/not_found.webp", size=(self.w, self.h), fit="contain", **properties) def render(self, width, height, st, at): return renpy.render(self.image, self.w, self.h, st, at)
Re: Crash on reload on versions prior to 8.2
You are welcome.
I just tested and it appears that Transform(...size) can take floats. No manual int() conversion is necessary.
About prediction:
I never experienced performance problems, using CDDs without visit(), even with slow (storage-class) HDDs.
When it's just the same image, the screen gets predicted and probably the image gets loaded when necessary.
And then the displayable could be reused:
https://renpy.org/doc/html/screen_optim ... able-reuse
I tested Transform() with non-existing displayable, and indeed it just gives blank result (white or maybe zero-size).
However, isn't it OK to have just white surface instead of some "not found" image?
I would do that instead of an extra check for existence. But you do you of course.
Just note that Transform() can take not only a file name, but other displayables (existing as well), and that might come useful.
Hence my version:
Or maybe
...Or maybe subclass Transform()...
Anyway, good luck with new versions, updated for latest RenPy.
I just tested and it appears that Transform(...size) can take floats. No manual int() conversion is necessary.
About prediction:
I never experienced performance problems, using CDDs without visit(), even with slow (storage-class) HDDs.
When it's just the same image, the screen gets predicted and probably the image gets loaded when necessary.
And then the displayable could be reused:
https://renpy.org/doc/html/screen_optim ... able-reuse
I tested Transform() with non-existing displayable, and indeed it just gives blank result (white or maybe zero-size).
However, isn't it OK to have just white surface instead of some "not found" image?
I would do that instead of an extra check for existence. But you do you of course.
Just note that Transform() can take not only a file name, but other displayables (existing as well), and that might come useful.
Hence my version:
Code: Select all
init python:
class ProportionalScale(renpy.Displayable):
def __init__(self, img, maxwidth=None, maxheight=None, **properties):
super(ProportionalScale, self).__init__()
self.w = maxwidth or config.screen_width
self.h = maxheight or config.screen_height
self.image = Transform(img, size=(self.w, self.h), fit="contain", **properties)
def render(self, width, height, st, at):
return renpy.render(self.image, self.w, self.h, st, at)
show ProportionalScale("smile.jpg", 766.667, 800)
Code: Select all
show Transform("smile.jpg", size=(766.667, 800), fit="contain")
Anyway, good luck with new versions, updated for latest RenPy.
If the problem is solved, please edit the original post and add [SOLVED] to the title.
Re: Crash on reload on versions prior to 8.2
Thanks! I was under the impression that floats would behave as multiples of the available width and height (as it does when using xsize 0.5 or ysize 0.8 in plain ATL). Maybe only if lower than 1.0? But that would be weirdly inconsistent.
-
- Newbie
- Posts: 4
- Joined: Mon Jul 03, 2023 6:28 am
- Contact:
Re: Crash on reload on versions prior to 8.2
All good now?
Last edited by AnthonyOlson on Mon Apr 08, 2024 2:37 am, edited 2 times in total.
Re: Crash on reload on versions prior to 8.2
Yes, although I hesitate to mark the topic as solved since I still have the crashes on reload in prior versions - although I took the rather painful step of porting the whole UI to 8.2 to work around it...
Re: Crash on reload on versions prior to 8.2
No, the documentation doesn't mention such duality, so I think this "size" differs from that "xysize" in this regard.
Why do you care about old versions?goldo wrote: Yes, although I hesitate to mark the topic as solved since I still have the crashes on reload in prior versions - although I took the rather painful step of porting the whole UI to 8.2 to work around it...
If you distribute a Ren'Py game, the engine gets packed inside, so players will use the version you have packed.
If the problem is solved, please edit the original post and add [SOLVED] to the title.
Re: Crash on reload on versions prior to 8.2
I used to care very much because the whole game was made with one of the legacy UI themes and before the switch to Python 3, so every version update has been very painful in terms of refactoring. In general, Ren'Py is not the best for retrocompatibility.
However, because of this latest problem I decided to redo the code and the whole UI using the new GUI system, so now I don't care as much, but I would have been happy not to have to do that. Basically a week of intensive work to end up with the game UI more or less where it used to be, or even a little worse in some places.
Who is online
Users browsing this forum: Baidu [Spider]