{}const=>[]async()letfn</>var
LuaРазработка

Lua за один вечер: от нуля до текстового RPG-квеста за несколько шагов

Разбираемся с языком Lua с нуля — без занудства и с мемами. Установим Lua, разберём переменные, таблицы, функции и циклы, а в финале напишем полноценный текстовый RPG-квест с боевой системой, ловушками и инвентарём. Всё за один присест.

К

Кодик

Автор

calendar_today
schedule9 мин чтения

Знаешь это чувство, когда открываешь новый язык программирования и первые 20 минут думаешь: «Ну это же просто»? А потом начинается. Скобки не те, точки с запятой забыл, компилятор орёт на тебя как сосед сверху в 3 часа ночи.

С Lua всё по-другому. Серьёзно. Этот язык настолько лаконичный, что ты можешь выучить его основы за чашку кофе. А за вечер — собрать вполне рабочий мини-проект. Не веришь? Ну давай проверим.

Что вообще такое Lua и зачем оно мне?

Lua (читается «Лу-а», а не «Луа» — но, честно, все говорят как хотят) — это лёгкий скриптовый язык, который родился в Бразилии в 1993 году. Да, он старше большинства JavaScript-фреймворков. И, в отличие от них, до сих пор не deprecated.

Где используется Lua:

  • Игры — Roblox, World of Warcraft, Garry's Mod, Love2D. Если ты когда-нибудь писал аддон для WoW — ты уже Lua-разработчик, поздравляю.

  • Nginx и OpenResty — высоконагруженные веб-серверы крутят Lua-скрипты для обработки запросов.

  • Neovim — если ты из тех, кто настраивает свой редактор дольше, чем пишет код, Lua — твой новый лучший друг.

  • Встраиваемые системы и IoT — Lua настолько лёгкий, что работает даже там, где Python задыхается.

Короче, Lua — это как швейцарский нож, только без штопора. Компактный, полезный и удивительно мощный.

🔥 100 000+ учеников уже с нами

Устал читать теорию?
Пора кодить!

Кодик — приложение, где ты учишься программировать через практику. AI-наставник, интерактивные уроки, реальные проекты.

🤖 AI 24/7
🎓 Сертификаты
💰 Бесплатно
🚀 Начать учиться
Присоединились сегодня

Шаг 0: Установка (быстрее, чем npm install)

Linux/macOS:

# Ubuntu / Debian
sudo apt install lua5.4

# macOS
brew install lua

Windows:

Скачай LuaBinaries с официального сайта или поставь через scoop:

scoop install lua

Проверяем:

lua -v
# Lua 5.4.x  Copyright (C) ...

Готово. Ни Docker, ни виртуальное окружение, ни package.json на 300 строк. Просто работает.

Шаг 1: Hello World и первые основы

Создай файл hello.lua:

print("Hello, World!")
print("Lua проще, чем ты думал")

Запусти:

lua hello.lua

Вот и всё. Без public static void main, без import sys, без use strict. Просто пишешь и запускаешь.

Переменные — без типов, без проблем

local name = "Алексей"
local age = 25
local is_developer = true

print(name .. " — разработчик: " .. tostring(is_developer))

Обрати внимание: .. — это конкатенация строк. Не +, не шаблонные строки. Два скромных точки. Lua минималист.

Условия — старая добрая классика

local level = 42

if level >= 100 then
    print("Ты легенда!")
elseif level >= 50 then
    print("Почти там!")
else
    print("Продолжай качаться")
end

Заметь: then и end вместо фигурных скобок. Поначалу непривычно, но через час уже не замечаешь.

Циклы — три вида на все случаи

-- Цикл for (классический)
for i = 1, 5 do
    print("Итерация: " .. i)
end

-- Цикл while
local count = 0
while count < 3 do
    count = count + 1
    print("Счётчик: " .. count)
end

-- Перебор таблицы (о таблицах — ниже)
local fruits = {"яблоко", "банан", "манго"}
for index, fruit in ipairs(fruits) do
    print(index .. ". " .. fruit)
end

Шаг 2: Таблицы — единственная структура данных (и этого достаточно)

В Lua нет массивов, словарей, объектов, множеств, кортежей, деков... Есть таблицы. И они заменяют вообще всё. Это как если бы JavaScript-объект и массив слились в одну сущность:

-- Как массив
local colors = {"красный", "зелёный", "синий"}
print(colors[1])  -- "красный" (индексация с 1, да-да)

-- Как словарь
local player = {
    name = "Hero",
    hp = 100,
    level = 1
}
print(player.name)  -- "Hero"
print(player["hp"]) -- 100 (тоже работает)

-- Комбинированный вариант
local config = {
    title = "My Game",
    resolution = {1920, 1080},
    fullscreen = true
}

Индексация с 1 — да, это шок после всех языков с нулевой индексацией. Но ты привыкнешь. Наверное. Когда-нибудь.

Шаг 3: Функции — первоклассные граждане

-- Обычная функция
local function greet(name)
    return "Привет, " .. name .. "!"
end

print(greet("мир"))

-- Функция как переменная (анонимная)
local square = function(x)
    return x * x
end

print(square(7))  -- 49

-- Множественный возврат (это Lua-суперсила!)
local function get_player_stats()
    return "Hero", 100, 15
end

local name, hp, attack = get_player_stats()
print(name .. " | HP: " .. hp .. " | ATK: " .. attack)

Множественный возврат значений — одна из тех штук в Lua, которая заставляет вздохнуть: «А почему так не везде?»

Шаг 4: Собираем мини-проект — текстовый квест!

Теория — это хорошо, но мы тут не лекцию читаем. Давай напишем настоящий мини-проект — текстовый RPG-квест. Тебе предстоит исследовать подземелье, сражаться с монстрами и (возможно) выжить.

Создай файл dungeon.lua:

-- === ТЕКСТОВЫЙ КВЕСТ: ПОДЗЕМЕЛЬЕ ===

math.randomseed(os.time())

-- Состояние игрока
local player = {
    name = "",
    hp = 100,
    attack = 15,
    potions = 3
}

-- Список монстров
local monsters = {
    {name = "Гоблин", hp = 30, attack = 8, xp = 10},
    {name = "Скелет", hp = 50, attack = 12, xp = 20},
    {name = "Тёмный маг", hp = 40, attack = 18, xp = 25},
    {name = "Огр", hp = 80, attack = 10, xp = 30},
}

-- Вспомогательные функции
local function separator()
    print(string.rep("-", 40))
end

local function show_status()
    separator()
    print("HP: " .. player.hp .. " | Зелья: " .. player.potions)
    separator()
end

local function ask(question, options)
    print("\n" .. question)
    for i, opt in ipairs(options) do
        print("  " .. i .. ") " .. opt)
    end
    io.write("Твой выбор: ")
    local choice = tonumber(io.read())
    if not choice or choice < 1 or choice > #options then
        print("Непонятный выбор, попробуй ещё раз.")
        return ask(question, options)
    end
    return choice
end

-- Система боя
local function battle(monster)
    print("\n⚔️  Перед тобой появляется " .. monster.name .. "! (HP: " .. monster.hp .. ")")

    local enemy_hp = monster.hp

    while enemy_hp > 0 and player.hp > 0 do
        show_status()
        local action = ask("Что делаешь?", {"Атаковать", "Выпить зелье", "Попробовать сбежать"})

        if action == 1 then
            local damage = math.random(player.attack - 5, player.attack + 5)
            enemy_hp = enemy_hp - damage
            print("Ты наносишь " .. damage .. " урона!")

            if enemy_hp > 0 then
                local enemy_damage = math.random(monster.attack - 3, monster.attack + 3)
                player.hp = player.hp - enemy_damage
                print(monster.name .. " бьёт тебя на " .. enemy_damage .. " урона!")
            end

        elseif action == 2 then
            if player.potions > 0 then
                local heal = math.random(20, 35)
                player.hp = player.hp + heal
                player.potions = player.potions - 1
                print("Ты восстанавливаешь " .. heal .. " HP!")
            else
                print("У тебя нет зелий! Ход потерян...")
            end
            local enemy_damage = math.random(monster.attack - 3, monster.attack + 3)
            player.hp = player.hp - enemy_damage
            print(monster.name .. " бьёт тебя на " .. enemy_damage .. " урона!")

        elseif action == 3 then
            if math.random(1, 100) <= 40 then
                print("Тебе удалось сбежать!")
                return false
            else
                print("Не удалось сбежать!")
                local enemy_damage = math.random(monster.attack - 3, monster.attack + 5)
                player.hp = player.hp - enemy_damage
                print(monster.name .. " бьёт тебя на " .. enemy_damage .. " урона!")
            end
        end
    end

    if enemy_hp <= 0 then
        print("\n🎉 " .. monster.name .. " повержен!")
        if math.random(1, 100) <= 30 then
            player.potions = player.potions + 1
            print("Ты находишь зелье!")
        end
        return true
    end

    return false
end

-- Комнаты подземелья
local function explore_room(room_number)
    separator()
    print("\n🚪 Комната " .. room_number)

    local events = {"monster", "monster", "treasure", "trap", "empty"}
    local event = events[math.random(1, #events)]

    if event == "monster" then
        local monster = monsters[math.random(1, #monsters)]
        return battle(monster)

    elseif event == "treasure" then
        print("Ты находишь сундук с сокровищами!")
        local bonus = ask("Что берёшь?", {"Зелье здоровья (+1)", "Точильный камень (+3 к атаке)"})
        if bonus == 1 then
            player.potions = player.potions + 1
            print("Зелья: " .. player.potions)
        else
            player.attack = player.attack + 3
            print("Атака теперь: " .. player.attack)
        end
        return true

    elseif event == "trap" then
        print("Ловушка! Шипы выстреливают из стены!")
        local trap_damage = math.random(5, 15)
        player.hp = player.hp - trap_damage
        print("Ты получаешь " .. trap_damage .. " урона.")
        return true

    else
        print("Пустая комната. Тишина и пыль.")
        if math.random(1, 100) <= 20 then
            print("Ты находишь зелье в углу!")
            player.potions = player.potions + 1
        end
        return true
    end
end

-- === НАЧАЛО ИГРЫ ===

print("╔══════════════════════════════════════╗")
print("║     ПОДЗЕМЕЛЬЕ: ТЕКСТОВЫЙ КВЕСТ     ║")
print("║         Написано на Lua              ║")
print("╚══════════════════════════════════════╝")

io.write("Как тебя зовут, искатель приключений? ")
player.name = io.read()
print("\nДобро пожаловать, " .. player.name .. "!")
print("Перед тобой вход в подземелье из 5 комнат.")
print("Пройди их все — и стань легендой.\n")

local rooms_cleared = 0

for room = 1, 5 do
    if player.hp <= 0 then
        break
    end

    explore_room(room)

    if player.hp <= 0 then
        break
    end

    rooms_cleared = rooms_cleared + 1

    if room < 5 then
        show_status()
        local choice = ask("Идёшь дальше?", {"Вперёд!", "Хватит на сегодня"})
        if choice == 2 then
            print("\nТы решаешь вернуться. Иногда отступить — тоже мудрость.")
            break
        end
    end
end

separator()
separator()

if player.hp <= 0 then
    print("\n💀 " .. player.name .. " пал в подземелье...")
    print("Комнат пройдено: " .. rooms_cleared .. " из 5")
    print("Попробуй ещё раз — подземелье ждёт!")
else
    if rooms_cleared == 5 then
        print("\n🏆 " .. player.name .. " прошёл всё подземелье!")
        print("HP: " .. player.hp .. " | Оставшиеся зелья: " .. player.potions)
        print("Ты — настоящая легенда!")
    else
        print("\n🏠 " .. player.name .. " вернулся из подземелья.")
        print("Комнат пройдено: " .. rooms_cleared .. " из 5")
    end
end

print("\nСпасибо за игру! 🎮")

Запускай:

lua dungeon.lua

И вот ты уже написал полноценный проект на Lua. С боевой системой, рандомом, инвентарём и ветвлением сюжета. Не какой-нибудь калькулятор, а настоящая игра.

Что дальше? Куда расти

Lua — это отличная точка входа, и вот куда можно двигаться:

  • Love2D — фреймворк для 2D-игр на Lua. Если текстовый квест зашёл, представь, что будет с графикой.

  • Neovim-плагины — свой плагин для редактора, написанный на Lua, это отдельный вид удовольствия.

  • OpenResty — встраивай Lua-скрипты прямо в nginx и обрабатывай миллионы запросов.

  • Roblox — серьёзно, на Roblox зарабатывают реальные деньги, а вся логика пишется на Lua.

Хочешь учиться дальше?
Заходи в Кодик!

Если тебе зашёл такой формат — от теории к практике за один присест — тебе точно понравится Кодик. Это приложение для изучения программирования, где каждый урок — это не просто стена текста, а задачи, которые ты решаешь руками. Python, JavaScript, HTML, CSS и другие технологии — всё с реальной практикой, без воды и занудства.

А ещё у нас есть Telegram-канал, где регулярно выходят полезные посты: разборы концепций, шпаргалки, мини-задачи и мемы для разработчиков. Это отличный способ повторять программирование в удобном формате — по дороге на работу, в обеденный перерыв или когда «ещё пять минуточек» перед сном. Подписывайся, и пусть программирование будет частью каждого дня.

Lua — это язык, который доказывает: чтобы быть мощным, не обязательно быть сложным. За один вечер ты прошёл путь от print("Hello") до текстового RPG-квеста с боевой системой. И при этом не установил ни одной зависимости, не написал ни одного конфига и не сломал ни одного package-lock.json.

Теперь у тебя есть рабочий проект, понимание основ и направление для роста. А это уже больше, чем у 90% людей, которые «собирались начать учить программирование на следующей неделе».

Дерзай. 🚀

🎯Хватит откладывать

Понравилась статья?
Пора применять на практике!

В Кодик ты не просто читаешь — ты сразу пишешь код. Теория + практика = реальный скилл.

Мгновенная практика
🧠AI объяснит код
🏆Сертификат

Без регистрации • Без карты