Why does a widget need a canvas?

I am a learning beginner.

What is the purpose of deleting the canvas when using multiple widgets? For example, some help guides will create a main HUD widget with say just health and magic progress bars. Then in another separate widget say for inventory they will delete the canvas and set the fill screen to desired. I sort of understand using the main HUD widget to call to get a reference to the Inventory widget. I don’t understand the significance not having a canvas on a widget.

When I try this and later want to adjust something, the referenced widget is placed off screen. Or I am unable to adjust size or other things of that nature. For me, with my level of understanding, not only does it makes sense to have all info on one widget, I feel like I’m getting more accomplished. But I also want to know why or why not I’m doing something.

1 Like

Canvas serves a very specific purpose, no other widget allows you to:

  • anchor (because you want the minimap to always be in the upper right with a 10x10px margin even if the screen size changes)
  • zOrder (what shows on top of what - you’re flipping records in a jukebox and it’s a carousel-style menu, things will overlap)
  • directly dictate relative children position and their size (movable windows perhaps or placing other widgets in arbitrary positions)

What is the purpose of deleting the
canvas when using multiple widgets?

Does your widget need the above-mentioned features? No? Then remove the canvas. You’ll be saving on performance and declutter the hierarchy.

I think that some of the confusion comes from the fact that the canvas is present in a default new widget. Imagine how much more confusion there would be if it was the progress bar being there by default. You’d delete that, surely, since you do not need a progress bar in every widget. Canvas just happens to be there by default.

I don’t understand the significance
not having a canvas on a widget.

tl;dr: improved performance, lower memory footprint, less clutter, hierarchical simplification, common sense.

If I want to display 1000 inventory widgets representing what’s in my backpack, the item widgets will not need:

  • anchoring (the backpack container itself already sits in a canvas and knows where its children will display)
  • zOrdering (items will not overlap anyway, that’d lead to an annoying user experience)
  • dictating relative children position and their size (it will all sit in a vertical / wrap box or some sort of grid who will automatically position everything and size it accordingly). You do not want that oversized axe to stick out of the inventory box.

When I try this and later want to
adjust something, the referenced
widget is placed off screen. Or I am
unable to adjust size or other things
of that nature. For me, with my level
of understanding, not only does it
makes sense to have all info on one
widget, I feel like I’m getting more
accomplished. But I also want to know
why or why not I’m doing something.

The further you go down the line, the more you’ll notice the need to wrap everything in a separate user widget and use that instead. I stopped using buttons a couple of years ago. Never looked back.

The reasons here are reusability, not duplicating script, maintenance and data flow. If you do not take the advantage of OOP, you’ll be shooting yourself in the foot. Ideally you want to encapsulate behaviour so each element is responsible for its own internal functionality. Wrapping widgets allows for that.


Imagine a scenario: you finally receive the pixel-perfect button downstate icon you requested 2 weeks ago from your artist :|. Rather than replacing it on the 70 buttons you placed since then in the main menu, you instead replace it on 1 because you wrapped it and have been using it ever since. This change will now propagate to all buttons, even though they’re sitting pretty in numerous unrelated widgets.


Another one: an RPG game with character stats represented with cool looking progress bars, with all the bells and whistles imaginable. Each bar has tiny buttons with animations that increase the stats and an OK button to confirm it (20 native widgets per progress bar).

Each character needs 5 of these - you surely do not want to do the same work 5 times and manually hook every field to some data pulled from a data table. You’d encapsulate methods in that progress bar and let it handle certain things like animations or telling the user how quickly they can mash the + button to increase their strength stat.

4 Likes

TIL that, apparently, one can set the default root element:

1 Like

Yup, absolutely yes.

Wrap a native button with a widget - a user widget that has a simple button inside (or additional elements should you choose to decorate it further, ofc). This way a button can have its own variables / methods / animations and conform to UI styling easier.

Let’s say I need a red X close button in the upper right corner of every window that can be closed / dismissed. I would not use a native button for that. I’ll happily pay the upfront cost of setting it up so I can benefit from easier maintenance further down the line.

Likewise, I’d do the same with an Editable Text. Let’s say I need to emulate an MS-DOS-like terminal interface. Even though Construct Object from Class may seem like a perfect choice here for creating and displaying lines of text, I’d rather have custom functionality built into every line of text the terminal can display - a blinking caret to start with.

Again, it all depends on the scope of what we’re working with. I’d do none of the above in a 24h game jam…


There’s also re-parenting widgets but that has always felt like opening a can of worms :expressionless: Some things are inherited, others are not.

1 Like

Great, thanks! I’ll definitely do that.

The further you go down the line, the
more you’ll notice the need to wrap
everything in a separate user widget
and use that instead. I stopped using
buttons a couple of years ago. Never
looked back.

You mean, create a separate widget that looks like a button, and add child widgets to a larger one instead of actual buttons?