BLOXAR Script Engine

Официальная документация по скриптовому движку BLOXAR. Пишите логику миров, анимации, механики и мини-игры прямо в браузере — без сборщиков и фреймворков.

💡 Движок

Скрипты пишутся на чистом JavaScript. Движок вызывает ваш код 60 раз в секунду — это даёт плавные анимации и мгновенную реакцию на ввод игрока.

🚀 Первый скрипт

  1. Откройте проект в Studio Mode.
  2. В панели Explorer нажмите и выберите 📜 Script.
  3. Перетащите скрипт внутрь любого блока 📦 Part.
  4. Кликните по скрипту — откроется редактор кода.
  5. Напишите код и нажмите Save & Close.

Важно: Скрипты не работают в Студии. Нажмите Publish World и зайдите как игрок.

🧬 Системные переменные

4 переменные доступны в каждом скрипте без объявления.

parent

3D-блок, внутри которого лежит скрипт. Доступны .position, .rotation, .scale.

time

Время в секундах с запуска. Используй с Math.sin(time) для цикличных анимаций.

player

Объект персонажа. Например: parent.position.distanceTo(player.position) — расстояние до игрока.

script

Объект скрипта. Храни переменные в script.userData — они не сбрасываются каждый кадр.
Пример: script.userData.count = (script.userData.count || 0) + 1;

🛠️ Манипуляции с объектами

Команды для изменения внешнего вида и положения блоков. Вызываются через BLOXAR.*

BLOXAR.setColor(obj, hexColor)

Красит объект. Формат цвета: 0xFF0000 (красный), 0x00FF00 (зелёный).

BLOXAR.move(obj, x, y, z)

Сдвигает объект на заданное расстояние. Вызывай каждый кадр для непрерывного движения.

BLOXAR.rotate(obj, rx, ry, rz)

Вращает объект. Углы в радианах. Math.PI = 180°. Для постоянного вращения вызывай каждый кадр.

❤️ Игрок и Здоровье

BLOXAR.damagePlayer(amount)

Наносит урон. Максимум здоровья = 100. При 0 — игрок умирает и возрождается.

BLOXAR.healPlayer(amount)

Восстанавливает здоровье. Не может превысить 100.

🔊 Аудио и UI

BLOXAR.playSound(type)

Воспроизводит звук. Доступные типы: 'step', 'jump', 'land'.

BLOXAR.isKeyPressed(key)

Возвращает true, если клавиша зажата. Принимает строку в нижнем регистре.
Примеры: 'e', 'f', 'shift', 'space', 'arrowup'.

BLOXAR.showText(text)

Показывает текст-подсказку в центре экрана. Передай "" чтобы скрыть.

BLOXAR.playSound3D(x, y, z, type, intensity)

Воспроизводит пространственный звук в точке мира. Чем дальше игрок, тем тише.
Доступные типы: 'step', 'jump', 'explosion', 'pickup'. intensity — громкость (по умолчанию 1).

🧱 Создание и удаление блоков

BLOXAR.createPart(x, y, z, color, sx, sy, sz, hasPhysics) → Object3D

Создаёт блок в мире и возвращает его. Если hasPhysics = true — блок падает под действием гравитации. sx/sy/sz — масштаб по осям (по умолчанию 1).

BLOXAR.destroyPart(obj)

Удаляет объект и освобождает память GPU. Всегда вызывай для динамически созданных блоков, которые больше не нужны.

// Создаём красный куб и удаляем через 3 секунды
const cube = BLOXAR.createPart(0, 5, 0, 0xFF3B3B, 1, 1, 1, false);

if (!script.userData.timer) script.userData.timer = time;
if (time - script.userData.timer > 3) {
    BLOXAR.destroyPart(cube);
}

✨ Эффекты и Частицы

BLOXAR.spawnEffect(x, y, z, hexColor, count)

Создаёт взрыв частиц в точке. count — количество частиц (по умолчанию 10). Частицы автоматически исчезают.

// Эффект взрыва на позиции блока при приближении игрока
const dist = parent.position.distanceTo(player.position);
if (dist < 2 && !script.userData.exploded) {
    script.userData.exploded = true;
    BLOXAR.spawnEffect(parent.position.x, parent.position.y, parent.position.z, 0xFF6600, 25);
    BLOXAR.playSound('land');
}

🗡️ Инструменты (Weapons & Items)

Система для создания оружия, предметов и экипировки в руки персонажа.

BLOXAR.createTool(shape, color, sx, sy, sz) → Mesh

Создаёт 3D-меш инструмента. shape: 'box' | 'sphere' | 'cone' | 'cylinder'. Возвращает объект — передай его в equipTool().

BLOXAR.equipTool(obj, slotNum, offsetX, offsetY, offsetZ)

Крепит инструмент к правой руке в слот slotNum (1–5). Смещение по умолчанию: (0, -0.8, 0.3).

BLOXAR.unequipTool(slotNum)

Снимает и удаляет инструмент из указанного слота.

BLOXAR.setHoldOffset(obj, x, y, z)

Изменяет позицию уже надетого инструмента относительно ладони.

BLOXAR.setToolName(slotNum, label)

Устанавливает подпись слота в инвентаре (отображается как tooltip).

BLOXAR.getActiveSlot() → number

Возвращает номер активного слота (1–5). Используй для отслеживания, что держит игрок.

// Создаём меч в слоте 1 при старте
if (!script.userData.ready) {
    script.userData.ready = true;
    const sword = BLOXAR.createTool('box', 0xC0C0C0, 0.1, 1.2, 0.1);
    BLOXAR.equipTool(sword, 1);
    BLOXAR.setToolName(1, 'Меч');
}

// Удар при нажатии E
if (BLOXAR.isKeyPressed('e')) {
    BLOXAR.playAnimation('swing');
    BLOXAR.spawnEffect(player.position.x, player.position.y + 1, player.position.z, 0xffffff, 8);
}

💪 Анимации рук

Быстрые одноразовые анимации правой руки. Идеальны для атак, броска, взаимодействий.

BLOXAR.playAnimation(animName)

Запускает пресет анимации правой руки. Автоматически останавливается по завершении.

BLOXAR.stopAnimation()

Немедленно останавливает анимацию руки и возвращает её в исходное положение.

Доступные пресеты рук

'swing'широкий взмах
'stab'укол вперёд
'spin'вращение руки
'throw'бросок
'idle_hold'покачивание ∞
// Атака при нажатии ЛКМ (клавиша 'f' как замена)
if (BLOXAR.isKeyPressed('f')) {
    if (!script.userData.attacking) {
        script.userData.attacking = true;
        BLOXAR.playAnimation('swing');
        BLOXAR.damagePlayer(-10); // Лечим как пример логики
    }
} else {
    script.userData.attacking = false;
}

🕺 Анимации тела

Полные анимации персонажа: все конечности одновременно. Два подхода: пресеты и ручное управление.

BLOXAR.playBodyAnim(animName)

Запускает пресет анимации всего тела. Большинство анимаций зацикленные — останавливай через stopBodyAnim().

BLOXAR.stopBodyAnim()

Останавливает анимацию тела и сбрасывает все конечности в нейтральное положение.

BLOXAR.setLimb(limbName, rx, ry, rz)

Напрямую задаёт вращение конечности. Вызывай каждый кадр для плавной анимации. Углы в радианах.
Доступные limbName: 'rArm', 'lArm', 'rLeg', 'lLeg', 'head', 'body'.

Доступные пресеты тела

'wave'приветствие ∞
'dance'танец ∞
'sit'поза сидя ∞
'cheer'радость (авто)
'raise_hands'руки вверх ∞
'float'парение ∞
'spin_body'вращение тела ∞
// Танцевать при нажатии G, остановить при отпускании
if (BLOXAR.isKeyPressed('g')) {
    BLOXAR.playBodyAnim('dance');
} else {
    BLOXAR.stopBodyAnim();
}

// Кастомная анимация через setLimb — кивание головой
BLOXAR.setLimb('head', Math.sin(time * 3) * 0.4, 0, 0);

// Поднять левую руку синусоидой
BLOXAR.setLimb('lArm', Math.sin(time * 2) * 1.2, 0, Math.cos(time) * 0.3);

💾 DataStore (Сохранения)

Сохраняй прогресс игрока между сессиями. Данные привязаны к конкретному плейсу и конкретному игроку.

BLOXAR.saveData(key, value)

Сохраняет значение под ключом. Данные записываются локально мгновенно и асинхронно синхронизируются с сервером.

BLOXAR.loadData(key) → any | null

Читает сохранённое значение по ключу. Возвращает null если ключа нет.

⚠️ Только в игре: DataStore не работает в Студии и в Sandbox. Тестируй в опубликованном плейсе.

// Счётчик посещений — увеличивается каждый заход
if (!script.userData.loaded) {
    script.userData.loaded = true;

    let visits = BLOXAR.loadData('visits') || 0;
    visits += 1;
    BLOXAR.saveData('visits', visits);
    BLOXAR.showText('Ты здесь уже ' + visits + ' раз!');

    // Через 3 секунды скрыть текст
    script.userData.showUntil = time + 3;
}

if (script.userData.showUntil && time > script.userData.showUntil) {
    BLOXAR.showText('');
    script.userData.showUntil = null;
}

🔗 SharedData (Общая память)

Общая память между всеми скриптами в плейсе. Идеальна для передачи состояния от одного скрипта к другому — например, "кнопка нажата" → "дверь открыта".

BLOXAR.set(key, value)

Записывает значение в общую память. Видно всем скриптам мгновенно.

BLOXAR.get(key, defaultValue) → any

Читает значение из общей памяти. Второй аргумент — значение по умолчанию (если ключа нет).

BLOXAR.has(key) → boolean

Возвращает true, если ключ существует в SharedData.

BLOXAR.delete(key)

Удаляет ключ из общей памяти.

// === Скрипт 1: Кнопка-триггер ===
const dist = parent.position.distanceTo(player.position);
if (dist < 2 && BLOXAR.isKeyPressed('e')) {
    BLOXAR.set('doorOpen', true);
    BLOXAR.setColor(parent, 0x2EE6A6); // Кнопка зеленеет
}

// === Скрипт 2: Дверь (в другом блоке) ===
if (BLOXAR.get('doorOpen', false)) {
    parent.position.y += 0.05; // Поднимается вверх
    if (parent.position.y > 5) BLOXAR.delete('doorOpen');
}

⚡ Система событий (Events)

Регистрируй колбеки (функции), и движок сам вызовет их в нужный момент.

BLOXAR.onStart(callback)

Срабатывает один раз при загрузке скрипта. Идеально для спавна NPC или настройки начальных данных.

BLOXAR.onTouched(callback)

Срабатывает, когда игрок входит в зону блока (хитбокс блока + небольшой запас).

BLOXAR.onTouchEnded(callback)

Срабатывает, когда игрок выходит из зоны блока.

BLOXAR.onPlayerNear(distance, callback(dist))

Вызывает функцию каждый кадр, пока игрок находится ближе, чем distance юнитов. В функцию передается текущее расстояние.

BLOXAR.onKeyDown(key, callback)

Срабатывает один раз при нажатии указанной клавиши (например, 'e').

BLOXAR.onKeyUp(key, callback)

Срабатывает один раз при отпускании клавиши.

BLOXAR.onTouched(() => {
    BLOXAR.setColor(parent, 0x2EE6A6);
    BLOXAR.playSound('pickup');
});

BLOXAR.onKeyDown('f', () => {
    BLOXAR.showText("Нажата клавиша F!");
});

👾 Система NPC и Врагов

Спавн и управление мобами.

BLOXAR.spawnNPC({x, y, z, color, speed, hp, name, aggroRange, attackRange, attackDamage, attackCooldown, patrol}) → NPC Object

Создаёт NPC. Принимает объект с настройками. Возвращает объект NPC для дальнейшего управления. Не работает в Studio Mode.

BLOXAR.damageNPC(npc, amount)

Наносит урон конкретному NPC. При уроне моб мигает красным, полоска HP обновляется.

BLOXAR.killNPC(npc)

Немедленно убивает NPC, проигрывает эффект частиц и удаляет его из мира.

BLOXAR.getNPCs() → Array

Возвращает массив всех активных NPC на карте.

BLOXAR.setNPCOnDeath(npc, callback)

Устанавливает функцию, которая выполнится при смерти данного NPC.

BLOXAR.onStart(() => {
    const boss = BLOXAR.spawnNPC({
        x: parent.position.x, y: parent.position.y + 2, z: parent.position.z,
        name: "Босс Охраны", color: 0xFF0000, hp: 300, attackDamage: 25
    });
    
    BLOXAR.setNPCOnDeath(boss, () => {
        BLOXAR.showText("Босс повержен!");
        BLOXAR.playSound3D(parent.position.x, parent.position.y, parent.position.z, 'explosion');
    });
});

🎒 Инвентарь и Предметы

BLOXAR.giveItem({id, name, icon, type, count, maxStack}) → number | null

Даёт предмет игроку. Возвращает номер слота (1-5), куда попал предмет, или null, если инвентарь полон. Учитывает стаки (maxStack).

BLOXAR.removeItem(slotNum, count) → boolean

Забирает указанное количество предмета из слота. Если количество становится ≤ 0, слот очищается.

BLOXAR.getItem(slotNum) → Object | null

Возвращает данные предмета в указанном слоте.

BLOXAR.findItem(itemId) → number | null

Возвращает номер первого слота, в котором найден предмет с указанным ID.

BLOXAR.onItemUse(callback(item, slotNum))

Срабатывает при клике ЛКМ, когда у игрока в руках находится предмет.

🖥️ GUI Builder (Интерфейс)

Создание кастомных 2D-интерфейсов на экране игрока. Все элементы отрисовываются поверх игры.

BLOXAR.gui.createFrame(id, {width, height, x, y, anchor, background}) → DOM Element

Создаёт панель-контейнер. anchor: 'topleft', 'center', 'bottomright' и т.д.

BLOXAR.gui.createLabel(id, frameId, {text, fontSize, color, bold, align})

Создаёт текстовую надпись внутри указанного Frame.

BLOXAR.gui.createButton(id, frameId, {text, background, onClick})

Создаёт кликабельную кнопку внутри Frame. onClick — функция-колбек при нажатии.

BLOXAR.gui.createProgressBar(id, frameId, {value, max, color, label})

Создаёт полосу прогресса (полезно для HP боссов, опыта, таймеров).

BLOXAR.gui.setProgress(id, value, max, label)

Обновляет значения существующего ProgressBar.

BLOXAR.gui.destroy(id) / BLOXAR.gui.destroyAll()

Удаляет конкретный элемент по ID или полностью очищает весь созданный интерфейс.

BLOXAR.onStart(() => {
    // Создаем окно по центру
    BLOXAR.gui.createFrame('shop', { width: 250, height: 120, anchor: 'center' });
    BLOXAR.gui.createLabel('shop_title', 'shop', { text: 'Магазин', bold: true, align: 'center' });
    
    // Кнопка покупки
    BLOXAR.gui.createButton('buy_sword', 'shop', { 
        text: 'Купить меч (100 🟡)', 
        onClick: () => {
            BLOXAR.giveItem({ id: 'sword', name: 'Меч', icon: '🗡️' });
            BLOXAR.gui.destroy('shop'); // Закрываем магазин
        }
    });
});

🌍 Окружение и Свет

Управление погодой, небом и динамическим освещением.

BLOXAR.setWeather(type)

Включает погоду. Доступные типы: 'none', 'rain', 'snow'.

BLOXAR.setTimeOfDay(t)

Устанавливает время суток (0..1). Например, 0.25 — полдень, 0.75 — полночь.

BLOXAR.setSkyColor(topHex, bottomHex)

Меняет цвет зенита и горизонта (работает, если отключен цикл дня и ночи).

BLOXAR.createLight(type, color, intensity, x, y, z, distance) → Light Object

Создаёт источник света. type: 'point', 'spot', 'directional'.

BLOXAR.removeLight(lightObj)

Удаляет созданный источник света из мира.

BLOXAR.setFog(colorHex, near, far) / BLOXAR.clearFog()

Настраивает или отключает туман на карте.

🏃 Физика и Движение

Управление скоростью, прыжками и положением игрока.

BLOXAR.setPlayerPos(x, y, z)

Мгновенно телепортирует игрока в указанные координаты.

BLOXAR.setSpawnPoint(x, y, z) / BLOXAR.respawnPlayer()

Обновляет точку возрождения и принудительно убивает/возрождает игрока.

BLOXAR.setPlayerSpeed(multiplier)

Устанавливает множитель скорости бега (например, 0.2 для ускорения).

BLOXAR.setJumpForce(force)

Изменяет силу прыжка (по умолчанию 0.3).

BLOXAR.addImpulse(dx, dy, dz)

Применяет физический толчок к игроку (подбрасывает или отталкивает).

BLOXAR.setGravity(g) / BLOXAR.resetGravity()

Изменяет глобальную гравитацию (по умолчанию 0.015).

💬 Уведомления и Очки

BLOXAR.showNotification(text, duration, color)

Показывает стильное уведомление внизу экрана (toast-сообщение).

BLOXAR.showBigText(text, duration, color)

Огромный текст по центру экрана (идеально для "УРОВЕНЬ ПРОЙДЕН").

BLOXAR.showPopup(title, body, btnText, onBtnCallback)

Открывает модальное окно с кнопкой. Код останавливается до закрытия пользователем.

BLOXAR.addScore(amount) / BLOXAR.setScore(val)

Изменяет глобальный счетчик очков (⭐) на экране игрока.

BLOXAR.createLabel3D(text, x, y, z, color)

Создаёт текстовую надпись, которая парит прямо в 3D мире.

BLOXAR.screenFlash(hexColor, duration)

Вспышка экрана указанным цветом (например, при получении урона или бонуса).

🎬 Плавные анимации (Tweens)

Встроенная система для плавного перемещения и изменения блоков без ручного расчета.

BLOXAR.tweenPos(obj, tx, ty, tz, duration, onDone)

Плавно перемещает объект в новую точку за duration секунд.

BLOXAR.tweenScale(obj, sx, sy, sz, duration, onDone)

Плавно изменяет масштаб объекта.

BLOXAR.tweenColor(obj, toHex, duration)

Плавно перекрашивает материал объекта.

BLOXAR.shake(obj, intensity, duration)

Заставляет блок дрожать (отлично подходит для разрушающихся платформ).

BLOXAR.cameraShake(intensity, duration)

Тряска экрана игрока (эффект взрыва или землетрясения).

⏱ Таймеры и Лучи

BLOXAR.wait(seconds, callback)

Выполняет функцию через указанное количество секунд.

BLOXAR.loop(seconds, callback)

Бесконечно повторяет функцию каждые X секунд. Возвращает ID таймера (для отмены через cancelLoop).

BLOXAR.raycast(ox, oy, oz, dx, dy, dz) → Object | null

Пускает невидимый луч из точки (o) в направлении (d). Возвращает первый блок, в который попал луч.

BLOXAR.raycastFromPlayer() → Object | null

Пускает луч ровно из центра экрана игрока (туда, куда он смотрит).

💡 Готовые примеры (Copy & Paste)

Парящий блок-хамелеон

// Вращение
BLOXAR.rotate(parent, 0, 0.05, 0.02);

// Парение
parent.position.y += Math.sin(time * 5) * 0.005;

// Смена цвета по клавише F
if (BLOXAR.isKeyPressed('f')) {
    BLOXAR.setColor(parent, 0xFFD700);
} else {
    BLOXAR.setColor(parent, 0x1A2639);
}

Интерактивная кнопка

const dist = parent.position.distanceTo(player.position);

if (!script.userData.isPressed) {
    if (dist < 3) {
        BLOXAR.showText('Нажми [E] чтобы активировать');
        if (BLOXAR.isKeyPressed('e')) {
            script.userData.isPressed = true;
            BLOXAR.playSound('jump');
            BLOXAR.setColor(parent, 0x2EE6A6);
            BLOXAR.showText('');
        }
    } else {
        BLOXAR.showText('');
    }
}

Ловушка-шипы (урон при касании)

const dist = parent.position.distanceTo(player.position);

if (dist < 1.2) {
    if (!script.userData.cooldown || time - script.userData.cooldown > 1.5) {
        script.userData.cooldown = time;
        BLOXAR.damagePlayer(20);
        BLOXAR.playSound('land');
        BLOXAR.spawnEffect(player.position.x, player.position.y, player.position.z, 0xFF3B3B, 15);
    }
}

Танцевальная зона

const dist = parent.position.distanceTo(player.position);

if (dist < 3) {
    if (!script.userData.dancing) {
        script.userData.dancing = true;
        BLOXAR.playBodyAnim('dance');
        BLOXAR.showText('🎵 Танцевальная зона!');
    }
} else {
    if (script.userData.dancing) {
        script.userData.dancing = false;
        BLOXAR.stopBodyAnim();
        BLOXAR.showText('');
    }
}

Портал с эффектом вращения

// Постоянное вращение блока
BLOXAR.rotate(parent, 0.02, 0.04, 0.01);

// Пульсация частицами
if (Math.floor(time * 4) % 2 === 0 && !script.userData.lastPulse) {
    script.userData.lastPulse = true;
    BLOXAR.spawnEffect(parent.position.x, parent.position.y, parent.position.z, 0x2F6BFF, 5);
} else if (Math.floor(time * 4) % 2 !== 0) {
    script.userData.lastPulse = false;
}

// Телепорт при касании
const dist = parent.position.distanceTo(player.position);
if (dist < 1.5) {
    BLOXAR.showText('⚡ Телепорт активен');
} else {
    BLOXAR.showText('');
}