Skip to content

Slot implementation and refactor of loader#125

Open
Thodor12 wants to merge 1 commit intoversion/mainfrom
feature/slot_system_121
Open

Slot implementation and refactor of loader#125
Thodor12 wants to merge 1 commit intoversion/mainfrom
feature/slot_system_121

Conversation

@Thodor12
Copy link
Copy Markdown
Contributor

@Thodor12 Thodor12 commented Apr 8, 2026

Changes proposed in this pull request

  • A new layout system that allows to define more easily reusable layout files.
  • A slot system that works together with these layouts to allow customization of the layout through the means of overridable slots:

window.xml

<window>
    <view pos="330 130" size="300 100">
        <layout source="blockui:gui/layout/labeled_row.xml">
            <text slot="label" text="Name:" size="90 16" pos="0 2" textscale="0.9" color="white"/>
            <text slot="content" text="Steve" size="155 16" pos="0 2" color="lime"/>
        </layout>
        <layout source="blockui:gui/layout/labeled_row.xml" pos="0 24">
            <text slot="label" text="Level:" size="90 16" pos="0 2" textscale="0.9" color="white"/>
            <text slot="content" text="42" size="155 16" pos="0 2" color="aqua"/>
        </layout>
        <layout source="blockui:gui/layout/labeled_row.xml" pos="0 48">
            <!-- label fallback used, only content provided -->
            <text slot="content" text="(label is fallback)" size="155 16" pos="0 2" color="orange"/>
        </layout>
    </view>
</window>

labeled_row.xml

<layout>
    <!-- A row with a fixed label on the left and a slot for content on the right -->
    <view pos="0 0" size="90 20">
        <slot name="label">
            <text text="Label:" size="90 16" pos="0 2" textscale="0.9"/>
        </slot>
    </view>
    <view pos="95 0" size="155 20">
        <slot name="content"/>
    </view>
</layout>
  • Slots support fallback content in case the slot is not provided
  • More tight constraint checking on what valid root tags are supported, right now XML files may only support a <window> and <layout> tag, this in itself gives (luckily) no problems within Minecolonies except for 1 thing which I've got a branch ready to fix, this is for the request trees.
  • Put the debugging visualizers and debug screen behind a system property, so that these are not usable within a "live" scenario, unless you were to pass the debug env property. (This debug env is now by default set on the runClient config, so that it always works in dev).
  • Added a new testcase for the slotting mechanism

Testing

  • Yes I tested this before submitting it.
  • I also did a multiplayer test.

Review please

@someaddons
Copy link
Copy Markdown
Contributor

what is a slot?

@Raycoms
Copy link
Copy Markdown
Contributor

Raycoms commented Apr 8, 2026

Slot is for sure a bad name, why not just layout? Slots are a minecraft thing already

@Thodor12
Copy link
Copy Markdown
Contributor Author

Thodor12 commented Apr 8, 2026

what is a slot?

Slots are a way to "slot in" a component or piece of HTML/XML into a defined position within a layout file. It's quite common in any frontend framework.

https://vuejs.org/guide/components/slots
https://dev.to/abbeyperini/slots-slots-slots-everybody-4p5i

One example of what you could do is define a layout for a module page (the builder paper), and then define a slot in the layout where the content gets rendered.

You then create a window file for the specific module window you want to make, dump the builder paper layout in there, and the children of the layout get automatically put in the right position (right under the title of the building for example). That is the power of slots.

@Thodor12
Copy link
Copy Markdown
Contributor Author

Thodor12 commented Apr 8, 2026

If you take my example code, basically what it does is this:

window.xml

<window>
    <view pos="330 130" size="300 100">
        <layout source="blockui:gui/layout/labeled_row.xml">
            <text slot="label" text="Name:" size="90 16" pos="0 2" textscale="0.9" color="white"/>
            <text slot="content" text="Steve" size="155 16" pos="0 2" color="lime"/>
        </layout>
    </view>
</window>

labeled_row.xml

<layout>
    <!-- A row with a fixed label on the left and a slot for content on the right -->
    <view pos="0 0" size="90 20">
        <slot name="label">
            <text text="Label:" size="90 16" pos="0 2" textscale="0.9"/>
        </slot>
    </view>
    <view pos="95 0" size="155 20">
        <slot name="content"/>
    </view>
</layout>

Final output: (window.xml):

<window>
    <view pos="330 130" size="300 100">
        <!--<layout source="blockui:gui/layout/labeled_row.xml">
            <text slot="label" text="Name:" size="90 16" pos="0 2" textscale="0.9" color="white"/>
            <text slot="content" text="Steve" size="155 16" pos="0 2" color="lime"/>
        </layout>-->
        <!-- actual slotted content -->
        <view pos="0 0" size="90 20">
            <!-- <slot name="label">
                <text text="Label:" size="90 16" pos="0 2" textscale="0.9"/>
            </slot> -->
            <text text="Name:" size="90 16" pos="0 2" textscale="0.9" color="white"/>
        </view>
        <view pos="95 0" size="155 20">
            <!-- <slot name="content"/> -->
            <text text="Steve" size="155 16" pos="0 2" color="lime"/>
        </view>
    </view>
</window>

@someaddons
Copy link
Copy Markdown
Contributor

ah now the description makes more sense! useful context

@armele
Copy link
Copy Markdown

armele commented Apr 8, 2026

Are the existing layout files likely to be backwards-compatible, or will all layout files need a rework?

Copy link
Copy Markdown
Member

@Nightenom Nightenom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too hard to review given complexity and size - please avoid unnecessary changes like formatting/code moves/comment removals etc. there is too many unrelated changes, formatter can be run separetely in other PR

also take in mind that 26+ gui rendering is complete nuke in how it works when it comes to layering and rendering order (I'm still not sure about the overall damage to our code as I haven't managed to run it yet)

@Nightenom
Copy link
Copy Markdown
Member

Nightenom commented Apr 8, 2026

Overall I like the concept and I'm all-in. But I agree on the slot confusion here - slot in vanilla means inventory slot, and this rather looks like parametrized content override, the thing we have with layouts is already a slot.

So I would suggest suggest following: keep the layout system as is, support content override on per-id basis when injecting the layout. That way you don't have to create <slot> element in layout, and it automatically supports overriding of anything (not just slots).
It could be also extended to be bidirectional - meaning I would like to inject layout A with overriding element B but keeping B's child C intact (potentially allowing eg. to replace view with zoomdragview while keeping it's content without having to redefine it)

But take my opinion as 2-cents throw in discussion, the overall state is acceptable, just imho too artificially constrained and touching way more code than necessary.

@Thodor12
Copy link
Copy Markdown
Contributor Author

Thodor12 commented Apr 8, 2026

So I would suggest suggest following: keep the layout system as is, support content override on per-id basis when injecting the layout. That way you don't have to create <slot> element in layout, and it automatically supports overriding of anything (not just slots). It could be also extended to be bidirectional - meaning I would like to inject layout A with overriding element B but keeping B's child C intact (potentially allowing eg. to replace view with zoomdragview while keeping it's content without having to redefine it)

We could have that too down the line, but it doesn't cover this use-case entirely.
Currently layouts do not allow for any children. They're a reference to another file and that's it.

One example I sent to Ray is this:

module_layout.xml

<layout>
  <view>
    <image source="builder_paper"/>

    <text text="building title"/>

    <view pos="0 100"> <!-- ensure content starts at Y 100 -->
      <slot/>
    </view>
  </view>
</layout>

layoutbuilderres.xml

<window>
  <layout source="module_layout.xml">
    <list>
      <!-- Builder resources list -->
    </list>
  </layout>
</window>

This is a concept of how we could use this with builder papers. Each module has a reusuable layout that removes the need for defining the background image, header, etc on every module. Plus if you ever need to change them, all of them gain the benefit of the changes.

I do not see a way that content overrides could achieve this, as it wouldn't make the layouts themselves be able to fully customize the children, only modify existing children.
So, whilst this is an option, it's not what I'm after.

@Thodor12
Copy link
Copy Markdown
Contributor Author

Thodor12 commented Apr 8, 2026

Are the existing layout files likely to be backwards-compatible, or will all layout files need a rework?

They should continue to work @armele, nothing changed on the actual usage of the layout tag. They work completely differently now, but the properties they have remain the same.

It doesn't matter if a layout in itself doesn't have any slots, the only thing you have to actually check right now is that each layout file must be wrapped within a <layout> tag, as part of the root tag enforcement.

@someaddons
Copy link
Copy Markdown
Contributor

someaddons commented Apr 9, 2026

So I would suggest suggest following: keep the layout system as is, support content override on per-id basis when injecting the layout. That way you don't have to create <slot> element in layout, and it automatically supports overriding of anything (not just slots). It could be also extended to be bidirectional - meaning I would like to inject layout A with overriding element B but keeping B's child C intact (potentially allowing eg. to replace view with zoomdragview while keeping it's content without having to redefine it)

We could have that too down the line, but it doesn't cover this use-case entirely. Currently layouts do not allow for any children. They're a reference to another file and that's it.

One example I sent to Ray is this:

module_layout.xml

<layout>
  <view>
    <image source="builder_paper"/>

    <text text="building title"/>

    <view pos="0 100"> <!-- ensure content starts at Y 100 -->
      <slot/>
    </view>
  </view>
</layout>

layoutbuilderres.xml

<window>
  <layout source="module_layout.xml">
    <list>
      <!-- Builder resources list -->
    </list>
  </layout>
</window>

This is a concept of how we could use this with builder papers. Each module has a reusuable layout that removes the need for defining the background image, header, etc on every module. Plus if you ever need to change them, all of them gain the benefit of the changes.

I do not see a way that content overrides could achieve this, as it wouldn't make the layouts themselves be able to fully customize the children, only modify existing children. So, whilst this is an option, it's not what I'm after.

I think it should work for your case aswell, e.g:

if you give the slot an ID, e.g. <slot id="slotid1"> then you could declare the builder resources list with:
<list overrides="slotid1"> so it'd replace the element at that pos with a new one. If you want to inject more children you can just override it with a <view overrides="slotid1"> --children-- <\view>

@Thodor12
Copy link
Copy Markdown
Contributor Author

Thodor12 commented Apr 9, 2026

If you have to make the ID override system like that then it has no benefit compared with the slots, because slots have fallback content if the slot is not provided. Slots are also their own system and wouldn't necessarily have to hijack the ID fields for that purpose

@Thodor12
Copy link
Copy Markdown
Contributor Author

Thodor12 commented Apr 9, 2026

The only usecase I saw for the override was if you could partially modify a single attribute of a component.

Personally however I don't want any kind of override system because the whole idea behind layouts is that the layout defines the root style and what is allowed to be modified inside of it.
Overrides would allow modification on everything, which is more of a risk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants