Skip to content

Instantly share code, notes, and snippets.

@cookieukw
Last active September 14, 2026 17:47
Show Gist options
  • Select an option

  • Save cookieukw/329cd0fcdf97c8d7d7a1587ad5d40647 to your computer and use it in GitHub Desktop.

Select an option

Save cookieukw/329cd0fcdf97c8d7d7a1587ad5d40647 to your computer and use it in GitHub Desktop.
Hytale Group Mover [BLOCKBENCH PLUGIN]
let button;
Plugin.register('hytale_group_mover', {
title: 'Hytale Group Mover',
author: 'cookieukw',
description: 'Safely moves parent groups and all nested children while preserving offsets (preventing stretch drift in Hytale).',
icon: 'open_in_full',
version: '1.0.0',
variant: 'both',
min_version: '5.0.0',
tags: ['Hytale'],
onload() {
button = new Action('hytale_move_group', {
name: 'Move Group (Preserve Offsets)',
description: 'Move selected group and its children while preserving offsets (fixes stretch drift).',
icon: 'open_in_full',
click: function() {
let group = Group.selected[0];
if (!group) {
Blockbench.showQuickMessage('Please select a Group in the Outliner!', 3000);
return;
}
new Dialog({
id: 'hytale_move_group_dialog',
title: 'Move Group (Preserve Offsets)',
form: {
x: {label: 'Target X', type: 'number', value: group.origin[0]},
y: {label: 'Target Y', type: 'number', value: group.origin[1]},
z: {label: 'Target Z', type: 'number', value: group.origin[2]}
},
onConfirm(formData) {
let targetX = parseFloat(formData.x);
let targetY = parseFloat(formData.y);
let targetZ = parseFloat(formData.z);
if (isNaN(targetX) || isNaN(targetY) || isNaN(targetZ)) return;
// Calculate exact translation delta
let dx = targetX - group.origin[0];
let dy = targetY - group.origin[1];
let dz = targetZ - group.origin[2];
if (dx === 0 && dy === 0 && dz === 0) return;
Undo.initEdit({elements: Cube.all, groups: Group.all});
// Move parent group pivot
group.origin.V3_set([targetX, targetY, targetZ]);
// Recursively move all nested child subgroups and cubes by the same delta
function moveNode(node) {
if (node instanceof Cube) {
node.from.V3_set([node.from[0] + dx, node.from[1] + dy, node.from[2] + dz]);
node.to.V3_set([node.to[0] + dx, node.to[1] + dy, node.to[2] + dz]);
node.origin.V3_set([node.origin[0] + dx, node.origin[1] + dy, node.origin[2] + dz]);
} else if (node instanceof Group) {
node.origin.V3_set([node.origin[0] + dx, node.origin[1] + dy, node.origin[2] + dz]);
node.children.forEach(child => moveNode(child));
}
}
group.children.forEach(child => moveNode(child));
Canvas.updateAll();
Undo.finishEdit('Move Group preserving offsets');
}
}).show();
}
});
MenuBar.menus.tools.addAction(button);
},
onunload() {
button.delete();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment