ui.hbox - ValueError: Cannot scale to negative size

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
Jake
Support Hero
Posts: 3826
Joined: Sat Jun 17, 2006 7:28 pm
Contact:

ui.hbox - ValueError: Cannot scale to negative size

#1 Post by Jake »

OK, so pursuant to my goal of getting all the character functionality into a single class (amongst other things to suit programming paradigms I'm more used to), I've been trying to implement a descendant of my now mostly-done class that works just the same, only with a little portrait next to their speech instead of a name.

I started off with the two-person-say code. Incidentally, this didn't pause for the mouse when I first picked it out the /extras directory - it looks to my untrained eye like it's from some previous version of the code where the ui.text method incorporated the ui.saybehaviour functionality? After reading through the reference I changed the end of the method from the ui.text call onwards to read like the following, which worked for me, but I'd obviously appreciate knowing whether there's something I'm missing:

Code: Select all

            ui.text(what, **what_args)

            ui.close()
            
            rv = ui.saybehavior()
            ui.interact()

            return rv
Anyway - basing my efforts on that, I wanted to align the picture to the left of the speech box rather than atop it, so I switched out the call to ui.vbox with a call to ui.hbox... and got the error in the thread title, "Cannot scale to negative size". After some fiddling (and trying it as a separate class method called directly, in case I was getting the interface wrong somehow) I ended up with the following minimal case method which exhibits the problem:

Code: Select all

            def trySay(self, what):
            
                ui.hbox()
                
                ui.window()
                ui.image("portrait.png")
                
                ui.window()
                ui.text(what)

                ui.close()
                
                val = ui.saybehavior()
                ui.interact()

                return val
- if I change the hbox to a vbox, it works pretty much the same as the two-person-say does. If I remove the window/image pair, it displays the text fine. If I remove the window/text pair, it displays the image fine. None of the styling seemed to make a difference.
Curiously, if I change the call to ui.hbox to a call to ui.grid(2,1), it renders the image window before crashing out, and renders it full-width.

Is there something I'm getting wrong, or perhaps some style that could be forcing the text window to inconvinient sizes or something? Again, I'm working within the demo script for convinience. The full text of the traceback is as follows:

Code: Select all

I'm sorry, but an exception occured while executing your Ren'Py
script.

ValueError: Cannot scale to negative size

The last script statement executed was on line 94 of game/script.rpy.

-- Full Traceback ------------------------------------------------------------

  File "renpy\bootstrap.pyo", line 96, in bootstrap
  File "renpy\main.pyo", line 233, in main
  File "renpy\main.pyo", line 158, in run
  File "renpy\execution.pyo", line 76, in run
  File "renpy\ast.pyo", line 334, in execute
  File "renpy\python.pyo", line 763, in py_exec_bytecode
  File "game/script.rpy", line 94, in <module>
  File "game/PortraitCharacter.rpy", line 66, in trySay
  File "renpy\ui.pyo", line 51, in interact
  File "renpy\display\core.pyo", line 985, in interact
  File "renpy\display\core.pyo", line 1207, in interact_core
  File "renpy\display\core.pyo", line 718, in show
  File "renpy\display\render.pyo", line 155, in render_screen
  File "renpy\display\render.pyo", line 81, in render
  File "renpy\display\layout.pyo", line 197, in render
  File "renpy\display\render.pyo", line 81, in render
  File "renpy\display\layout.pyo", line 197, in render
  File "renpy\display\render.pyo", line 81, in render
  File "renpy\display\layout.pyo", line 197, in render
  File "renpy\display\render.pyo", line 81, in render
  File "renpy\display\layout.pyo", line 440, in render
  File "renpy\display\render.pyo", line 81, in render
  File "renpy\display\layout.pyo", line 597, in render
  File "renpy\display\render.pyo", line 81, in render
  File "renpy\display\image.pyo", line 201, in render
  File "renpy\display\render.pyo", line 81, in render
  File "renpy\display\im.pyo", line 251, in render
  File "renpy\display\im.pyo", line 103, in get
  File "renpy\display\im.pyo", line 458, in load
  File "renpy\display\im.pyo", line 448, in draw
ValueError: Cannot scale to negative size

The last script statement executed was on line 94 of game/script.rpy.

Ren'Py Version: Ren'Py 5.5.2a
- line 94 of script.rpy is the call to char.trySay, line 66 of PortraitCharacter is the call to ui.interact

User avatar
PyTom
Ren'Py Creator
Posts: 16088
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

#2 Post by PyTom »

Okay, first of all, the code in two_window_say should not call saybehavior. That's the perogative of the code that calls it. There is a fairly complicated dance that goes on when it comes to implementing things like {w}, {p}, slow text, and many of the other features, which I tried to abstract out.

The reason for the error you have is that you have a ui.window that is smaller then the ui.frame around it. Either set that window's background=None, change the Frame to use smaller numbers for the x and y parameters, or set and xminimum and yminimum on the window.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

Jake
Support Hero
Posts: 3826
Joined: Sat Jun 17, 2006 7:28 pm
Contact:

#3 Post by Jake »

PyTom wrote:Okay, first of all, the code in two_window_say should not call saybehavior. That's the perogative of the code that calls it.
OK... IIRC the comments in the two window say script file suggest that you should be able to just drop it into the demo directory, hook it up to the Character class's show function, and it'll replace the normal dialogue window for that Character. I tried this, and it did display all the dialogue absolutely fine, but it didn't wait for a mouse click before moving on to the next line... so I ended up with the character dissolving in and out, then the last of three lines remaining with a regular dialogue box that happened to come after them in the script painted over the top of them. When I clicked that away, the two-window one beneath it also disappeared. What was it that I did wrong?

I'd reasoned it was possibly older code 'cause the function returned the return of ui.text, which didn't have a return value listed in the reference, but I had completely missed the note under renpy.show_display_say to that end...
PyTom wrote:The reason for the error you have is that you have a ui.window that is smaller then the ui.frame around it. Either set that window's background=None, change the Frame to use smaller numbers for the x and y parameters, or set and xminimum and yminimum on the window.
You mean that the window is smaller than the summed border widths of the frame? Hmm... is it that a widget will expand to fill all the available space, so unless the xmaximum property is set on the first window or the xminimum on the second, when the second window gets drawn it literally has zero width to draw in?

[EDIT: Setting maximum dimensions on the [leftmost] portrait window makes it work just fine - thanks!]

Post Reply

Who is online

Users browsing this forum: No registered users