ImproperUI

ImproperUI

Minecraft渲染太难学习的终极解决方案。使用一种高度受层叠样式表启发的自定义脚本语言,来创建完全可用的游戏内GUI!

游戏机制

ImproperUI

解决 Minecraft 渲染难以学习的终极方案。


Modrinth 下载量 CurseForge 下载量 GitHub 下载量(所有资源,所有版本)

简介

与我另一个项目 ClickCrystals Script 不同,ImproperUI Script 要求你具备以下基础知识:

  • 基本 CSS 属性及其工作原理
  • 基本 HTML 结构
  • Java

ImproperUI 的语法深受 CSS(层叠样式表)的启发,但并非完全相同。

下面是一个包含可拖动和可滚动元素的交互界面截图,作为该模组的主页。 该界面是使用 ImproperUI Script 编写的:

https://github.com/ItziSpyder/ImproperUI/raw/main/assets/demo.png

最新更改

版本:0.0.6-BETA

新增:
  - 添加了 ConfigReader
  - 添加了 ImproperUIAPI.getConfigReader()

补丁:
  - 修复了配置文件整数参数无法正确解析的问题

将 ImproperUI 添加到你的项目

要添加 ImproperUI,你需要下载其 jar 文件,然后手动将其添加到 gradle 中。 我不想创建在线仓库,也不想让它成为一个独立的模组。哎呀。

这里有一个示例,展示了如何在模组中使用 ImproperUI!

第 1 步

下载 jar 文件并将其添加到你的项目文件中,同时作为依赖项添加到 build.gradle 中。

依赖项 {
    compileOnly files("libs/ImproperUI-theVersionYouWant.jar")
}

第 2 步

将下载的 jar 文件作为模组添加到你的 mods 文件夹中!你必须将其用作库!

第 3 步(最后一步)

初始化 API。在此部分,你调用 ImproperUIAPI 上的 init() 函数,然后提供:

  • 你自己模组的 modId
  • 你自己模组的 主类模组初始化器
  • 最后是你自己模组 src/main/resources/ 文件夹内的一系列脚本路径。
  • 按照惯例,你应该在你自己模组的 src/main/resources/assets/YOURMODID/improperui/ 文件夹内创建脚本
public class ImproperUI implements ModInitializer {

    @Override
    public void onInitialize() {
        ImproperUIAPI.init("improperui", ImproperUI.class,
                "assets/improperui/improperui/what.ui",
                "assets/improperui/improperui/screen.ui"
        );
    }
}
public class YourModInitializer implements ModInitializer {

    @Override
    public void onInitialize() {
        ImproperUIAPI.init("yourModId", YourModInitializer.class,
                "assets/yourModId/improperui/yourscreen1.ui",
                "assets/yourModId/improperui/yourscreen2.ui"
        );
    }
}

请注意,当你实际尝试解析或运行这些脚本时,你引用的是脚本文件的名称,而不是此处声明的路径!


事件

要监听你脚本中声明的事件,创建一个实现了 CallbackListener 的新类。

创建一个方法,该方法需要:

  1. 带有 CallbackHandler 注解
  2. 参数包含你想要监听的事件类型
  3. 方法名称应与脚本中声明的事件匹配
public class CustomCallbacks implements CallbackListener {
    
    @CallbackHandler
    public void sendHelloWorld(MouseEvent e) {
        if (e.input.isDown())
            ChatUtils.sendMessage("Hello World");
    }
}

在你的脚本中,事件应如下所示:

元素 {
    点击事件: sendHelloWorld
}

最后,当你声明一个 ImproperUIPanel 界面时,将回调注册到你的面板:

public void openScreen() {
    ImproperUIPanel panel = new ImproperUIPanel();
    panel.registerCallback(new CustomCallback());
    // 在此解析脚本并添加子元素
    // panel.addChild()
    MinecraftClient.getInstance().setScreen(panel);
}

如果你正在运行脚本,请在创建参数中提供你的自定义回调:

public void openScreen() {
    ImproperUIAPI.parseAndRunFile("yourModId", "testing.ui", new CustomCallback() /* 和更多... */);
}

辅助方法

辅助方法:
  - ImproperUIPanel.collect() // 所有元素和组件及其子元素的列表
  - ImproperUIPanel.collectOrdered() // 按 z-index 排序的所有元素和组件及其子元素的列表
  - ImproperUIPanel.collectById() // 具有指定 ID 的元素列表
  - ImproperUIPanel.collectByClassAttribute() // 具有指定 class 属性的元素列表
  - ImproperUIPanel.collectById() // 具有指定 ID 的第一个元素
  - ImproperUIPanel.collectByClassAttribute() // 具有指定 class 属性的第一个元素

API:
  - ImproperUIAPI.parse() // 解析脚本并返回所有解析后的结果元素
  - ImproperUIAPI.parseAndRunFile() // 解析 init() 中注册的脚本文件名称(而非路径)并使用这些元素打开界面
  - ImproperUIAPI.parseAndRunScript() // 解析 init() 中注册的脚本并使用这些元素打开界面
  - ImproperUIAPI.reload() // 重新加载 API
  - ImproperUIAPI.reInit() // 使用可能不同的 Mod ID 重新初始化 API

配置键

配置键由三部分组成:modId, confileFile, propertyName。它们用于保存配置值,例如,你的滑块和复选框的值。

要在脚本中使用配置键,只需输入所有三个部分,不能有空格,并用冒号 (:) 分隔。 然后将该字符串用作元素的属性类:

滑块 #someId -yourModId:config.properties:testing-slider-value -someAnotherAttributeClass {
    
}

这将创建一个滑块,将值设置并保存到配置中。


标签

元素标签 动态悬停、选择、焦点 支持子元素 支持配置 别名 特定属性:类型
元素 (element) ✅ ✅ ✅ e, div
复选框 (checkbox) ✅ ❌ ✅ active:boolean
单选按钮 (radio) ✅ ❌ ✅ active:boolean
按钮 (button) ✅ ❌ ❌
链接 (link) ✅ ❌ ❌ a href:string
滑块 (slider) ❌ ❌ ✅ min:double max:double value:double range:double,double decimal-places:integer
输入框 (input) ❌ ❌ ✅ textbox pattern:quote placeholder:quote
文本域 (textfield) ❌ ❌ ✅ textarea
标签 (label) ✅ ❌ ❌ textlabel
标题1 (header1) ✅ ❌ ❌ h1
标题2 (header2) ✅ ❌ ❌ h2
标题3 (header3) ✅ ❌ ❌ h3
标题4 (header4) ✅ ❌ ❌ h4
标题5 (header5) ✅ ❌ ❌ h5
标题6 (header6) ✅ ❌ ❌ h6
可定位元素 (positionable) ✅ ✅ ✅

这个项目永远不会完成

所以快来提交你的创意! 给我们加星以获取最新有趣更新/拉取请求!






喜欢那个主界面吗?这是它的脚本!

div #background-gradient {
    size: 100%
    margin-top: 100%
    shadow-distance: 50%
    shadow-color: #9775a6
}

div #display {
    size: 420 240
    center: both
    border-radius: 10
    border-thickness: 1
    border-color: #412752
    background-color: #2d162c
    shadow-distance: 5
    shadow-color: #683a68

    child-align: grid
    grid-columns: 1

    div #title {
        inner-text: "ImproperUI 交互演示"
        size: 100% 10
        text-align: center
        text-scale: 1.69
        text-color: #9775a6
        background-color: none
        margin-top: 15
    }

    div #motto {
        inner-text: "我们在 GTA 6 之前就在 Minecraft 中实现了 CSS"
        size: 100% 10
        text-align: center
        text-scale: 0.8
        background-color: none
        margin-top: 10
    }
    div #motto {
        inner-text: "解决 Minecraft 渲染过于困难的终极方案"
        size: 100% 10
        text-align: center
        text-scale: 0.8
        background-color: none
        margin-bottom: 10
    }

    div #navbar {
        size: 100% 15
        margin-top: 10
        background-color: none

        child-align: grid
        grid-columns: 100

        button #discord {
            inner-text: "Discord"
            background-color: #9775a6
            border-radius: 0
            margin: 0
            width: 20%
            padding-left: 0
            padding-right: 0

            on-click: openDiscord

            hovered => { padding: 3; border-thickness: 0; border-radius: 2; shadow-distance: 2; }
        }
        button #github {
            inner-text: "GitHub"
            background-color: #9775a6
            border-radius: 0
            margin: 0
            width: 20%
            padding-left: 0
            padding-right: 0

            on-click: openGithub

            hovered => { padding: 3; border-thickness: 0; border-radius: 2; shadow-distance: 2; }
        }
        button #modrinth {
            inner-text: "Modrinth"
            background-color: #9775a6
            border-radius: 0
            margin: 0
            width: 20%
            padding-left: 0
            padding-right: 0

            on-click: openModrinth

            hovered => { padding: 3; border-thickness: 0; border-radius: 2; shadow-distance: 2; }
        }
        button #wiki {
            inner-text: "Wiki"
            background-color: #9775a6
            border-radius: 0
            margin: 0
            width: 20%
            padding-left: 0
            padding-right: 0

            on-click: openWiki

            hovered => { padding: 3; border-thickness: 0; border-radius: 2; shadow-distance: 2; }
        }
        button #wiki {
            inner-text: "示例"
            background-color: #9775a6
            border-radius: 0
            margin: 0
            width: 20%
            padding-left: 0
            padding-right: 0

            on-click: openExampleScreen

            hovered => { padding: 3; border-thickness: 0; border-radius: 2; shadow-distance: 2; }
        }
    }

    div #mini-world {
        size: 100% 140
        background-color: none

        child-align: grid
        grid-columns: 21

        scrollable: true
        background-clip: padding

        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }

        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }

        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/stone.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }

        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/stone.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/stone.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/oak_leaves.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } div #greenshade { size: 100%; background-color: green; opacity: 0.5; click-through: true; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }

        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/stone.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/stone.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/stone.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/stone.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/oak_log.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }

        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/grass_block_side.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/grass_block_side.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/grass_block_side.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size: 20; draggable: true; hovered => { border-thickness: 1; border-color: white; } }
        div #block { background-image: textures/block/ice.png; size