1. 8 months ago

    peter

    Jan 2017 Administrator Земля(Москва) User since 2014

    Решил иногда писать сюда о прогрессе над новым INSTEAD lua стеком (STEAD3)
    Сегодня запустился тестовый -диалог. Выглядит он так: https://github.com/gl00my/stead3/blob/master/tests/dialog/main.lua

  2. peter

    Jan 2017 Administrator Земля(Москва) User since 2014

    Немного информации о самой работе.
    Сейчас в ветке instead-2.5 ведется разработка нового инстеда. Кроме различных улучшений в sdl части, я решил попробовать написать совершенно новый стек lua, который был бы лишен текущих проблем, и который учитывал бы весь опыт, полученный за 7-8 лет разработки INSTEAD.

    В ветке 2.5 есть возможность использовать несколько стеков stead, так что совместимость сломана не будет. Очень надеюсь, что следующая версия будет содержать новый стек.

    Идея также состоит в том, чтобы stead3 был минимальным базисом, а все "навороты" могут писаться отдельно и оформляться в модули, которые будут разрабатываться отдельно.

    По мере готовности, я буду писать здесь маленькие заметки о stead3.

  3. peter

    Jan 2017 Administrator Земля(Москва) User since 2014

    Вот как выглядит модуль snapshots в stead3: https://github.com/gl00my/stead3/blob/master/snapshots.lua

  4. alastochkin

    Feb 2017 User since 2016

    peter, скажи, а планируется поддержка сетевой игры в STEAD-3? Мне кажется, будет свеженькое направление для новой версии...

  5. peter

    Feb 2017 Administrator Земля(Москва) User since 2014

    Есть возможность цеплять свои модули, в том числе и сетевые, если перевести игру в standalone режим. Но пока ни у кого не было конкретных планов, что с этим можно делать. Сам я скорее за оффлайн :) Сетевая игра это или монетизация, или совместное прохождение -- оба направления меня не цепляют, но техническая возможность есть.

  6. kolobod

    Feb 2017 User since 2014

    Сейчас каааак набежим с фичзапросами;)))
    Я вот все мечтаю о двух (или... более) отдельных, независимых инвентарях)) Чтоб, значит, в одном месте игрового поля: всякие статусы, навыки, перки и умения. А в другом: карманы с вещами. Или сразу два+ персонажа, одновременно, с их инвентарями. Больше, больше вещей, еще больше)))

  7. kerber

    Feb 2017 User since 2014

    Но можно же положить инвентари в инвентарь. А отрисовывать на картинке.

  8. MaJoR KolZ

    Feb 2017 Постоялец Харьков User since 2014
    Edited 8 months ago by MaJoR KolZ

    kerber прав — для статических штук действительно можно на подложке рисовать (создаешь спрайт — а потом назначаешь его через theme.gfx.bg).

    Я так в "Планете Анунак" сделал statusbar. В репозитории есть скриншоты.
    Кто-то когда-то еще просил кнопку быстрого сохранения — тот же принцип, просто еще в game.click отлавливаешь нажатия по области кнопки

  9. peter

    Feb 2017 Administrator Земля(Москва) User since 2014

    Вынужден огорчить тех, кто ждет именно фич. Фичи будут, но все-таки основное -- это изменения в самом "языке" (движке). Я чуть позже начну рассказывать о том, что я имею в виду.

    В каком то смысле это даже возврат к истокам. :) Инстед, в том виде в каком он мечтался. :) Простой, понятный, предсказуемый, не загроможденный. Stay tuned ;)

  10. kerber

    Feb 2017 User since 2014

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

  11. kerber

    Feb 2017 User since 2014

    kerber Нет нужды пихать фичи в движок. Lua позволяет реализовать их как модуль и вставлять в конкретную игру не загромождая ядро.

    Если надо кому именно фичу для конкретной игры, пишите в чат, обсудим.

  12. kolobod

    Feb 2017 User since 2014

    MaJoR KolZ kerber прав — для статических штук действительно можно на подложке рисовать (создаешь спрайт — а потом назначаешь его через theme.gfx.bg.
    Я так в "Планете Анунак" сделал statusbar.

    Огромное спасибище за наводку, обязательно посмотрю - если смогу осилить код!

  13. peter

    Feb 2017 Administrator Земля(Москва) User since 2014

    Итак, немного напишу сегодня. :)

    Объявление объектов в stead3.

    obj {
        nam = 'яблоко';
    }

    Вроде, похоже на stead2? Да, но есть важные отличия.

    nam может быть только строкой. Он не может быть функцией. Не может быть булевым значением. Только строка. nam -- однозначный и достаточный идентификатор объекта. Что это значит? После того как вы создали объект, вы всегда можете получить к нему доступ с помощью:

    std.ref 'яблоко' или (более кратко) std 'яблоко' или (еще более кратко) _'яблоко'

    То-есть, можно написать что-то вроде: _'яблоко'.variable = true

    Если вам нравится старый стиль, как это было в stead2, вы можете сделать ссылку при объявлении:

    apple = obj {
        nam = 'яблоко';
    }
    apple.variable = true

    Или получить временную/постоянную ссылку позже:

    apple = _'яблоко'
    local a = _'яблоко'

    В обработчике вы можете сопоставить объект его имени просто:

    use = function(s, w)
        if w/'яблоко' then p [[Я откусил яблоко.]] end
    end

    Или, конечно, так:

    use = function(s, w)
        if w == _'яблоко' then p [[Я откусил яблоко.]] end
    end

    Итак, nam стал единственным идентификатором. Для отображения объекта в инвентаре используется он-же, или, если вы задали disp -- то disp. disp уже может быть и строкой и функцией (впрочем, как это было и раньше).

    При размещении объектов в списках (в комнатах, например) мы используем имя объекта, то -есть:

    obj {
        nam = 'яблоко';
    }
     
    room {
        obj = { 'яблоко' };
    }

    Вы можете не задавать nam у объекта (или комнаты), при этом имя будет сгенерировано автоматически в виде цифры. Это удобно для деккораций или динамически создаваемых объектов. Для динамических объектов удобно использовать теги, о которых я расскажу как-нибудь в другой раз. :)

    Переменные объекта. Как их объявлять? Никак, теперь это не нужно. Забудьте про var {}. Но об этом я тоже расскажу в следующих постах.

  14. MaJoR KolZ

    Feb 2017 Постоялец Харьков User since 2014

    Что var объявлять больше не нужно — это отлично.

    if w/'яблоко' then

    Это перегрузка операции деления? Почему тогда не перегрузить проверку на равенство? Мол, если строка — вызвать объект и сравнить, иначе — сравнить таблицы Lua.

  15. skiminok1986

    Feb 2017 Постоялец Курган User since 2014

    А ссылку в obj = { ... } использовать теперь нельзя?

  16. peter

    Feb 2017 Administrator Земля(Москва) User since 2014

    MaJoR KolZ Что var объявлять больше не нужно — это отлично.

    if w/'яблоко' then

    Это перегрузка операции деления? Почему тогда не перегрузить проверку на равенство? Мол, если строка — вызвать объект и сравнить, иначе — сравнить таблицы Lua.

    Потому что lua не вызывает метод __eq, когда один из аргументов это строка. А вот деление -- вызывает. Но в любом случае, w/'яблоко' даже короче и вполне симпатично. :)

  17. peter

    Feb 2017 Administrator Земля(Москва) User since 2014

    skiminok1986 А ссылку в obj = { ... } использовать теперь нельзя?

    Так нельзя:

    apple = obj {}
     
    room {
        obj = { 'apple' }
    }

    А так -- можно:

    apple = obj {}
     
    room {
        obj = { apple }
    }

    Но во 2м случае apple должен был быть объявлен выше.

  18. peter

    Feb 2017 Administrator Земля(Москва) User since 2014
    Edited 8 months ago by peter

    Продолжаем. Имена объектов должны быть уникальными. Если вы создадите еще один объект с тем-же именем, вы сразу же получите ошибку.

    Но иногда нет смысла именовать объект руками. Например, когда мы создаем его прямо в сцене:

    obj {
        nam = 'main';
        obj = {
            disp = 'стол';
            dsc = 'тут стоит стол';
        }
    }

    Или у нас очень много однотипных объектов, типа фраз в диалоге. Мы же не собираемся каждой фразе давать уникальное имя? Если мы не зададим имя, движок сам создаст числовой индекс для такого объекта, но пользоваться им неудобно. Для таких случаев предусмотрены теги. Тег - это строка, которая начинается с символа # (таким образом в коде игры всегда понятно о чем мы говорим, о тегах или именах). Теги не обязаны быть одинаковыми, но они должны быть уникальными в пределах комнаты (вернее говоря, просто при поиске по тегу мы найдем 1-й такой объект).

    obj {
        nam = 'main';
        obj = {
            tag = '#стол';
            -- nam = 'имя стола'; -- мы могли бы дать имя стулу, но зачем?
            dsc = 'тут стоит стол';
        }
    }

    Или, альтернативная форма записи (когда мы не задаем имя, а только тег):

    obj {
        nam = 'main';
        obj = {
            nam = '#стол'; -- на самом деле мы задали тег, 
                                  -- который может мыслится как локальное имя
            dsc = 'тут стоит стол';
        }
    }

    При этом, в качестве отображения в инвентаре используется disp, если его нет, то тег, с убранным первым символом #. Большинство функций STEAD3 умеют работать как с тегом, так с именем, например:

    walk '#переход1'

    Будет искать объект с тегом #переход1 среди доступных переходов.

    Теги очень широко используются в диалогах, вы можете посмотреть это на примере диалога, который приведен выше в этой ветке.

    Говоря об объектах, нужно еще сказать, что в room появился новый атрибут -- title. Теперь disp (или tag/nam) используется для показа названия перехода в эту комнату, а title -- становится названием комнаты, когда мы в нее перешли. Если title не задан, то стандартная схема disp/tag/nam.

    На сегодня все. :) В следующий раз расскажу про переменные.

  19. peter

    Feb 2017 Administrator Земля(Москва) User since 2014
    Edited 8 months ago by peter

    Про переменные.
    В stead3 вам не нужно определять переменные объекта, которые вы хотите сохранить, через var {}. В stead2 было так:

    apple = obj {
        nam = 'яблоко';
        var { eaten = false }; -- сохранится
        _red = true; -- сохранится, так как начинается с символа _
    }

    В stead3:

    obj {
        nam = 'яблоко';
        eaten = false;
    }

    eaten сохранится, если в процессе игры значение этой переменной менялось.

    То-есть, если где-то в коде было _'яблоко'.eaten = true, то такая переменная сохранится.

    Если где-то в коде есть _'яблоко'.newvar = 1, то такая переменная тоже сохранится (создание переменных на лету).

    UPD: По результатам обсуждения решили, что по умолчанию создание переменных на-лету запрещено. Все переменные должны быть объявлены заранее. Если вы не указали std.nostrict = false в начале игры. :) Либо, для добавления переменных на лету используйте:

    apple 'variable' (10) -- создали переменную на-лету

    Есть только определенная особенность с таблицами. Дело в том, что таблица будет сохранена в save если к ней в процессе игры был доступ хотя бы на чтение.

    obj {
        nam = 'яблоко';
        tabl = { 1, 2, 3}; -- будет сохранена, если к таблице были обращения
    }

    Это сделано из-за того, что модификации внутри таблицы сложно отследить (без лишнего усложнения кода движка), поэтому таблицы сохраняются целиком. Но что если вы не хотите, чтобы таблица (или переменная) попадала в save файл? Тогда придется написать так:

    obj {
        nam = 'яблоко';
       {   -- блок переменных, за которыми не следит instead
            tabl = { 1, 2, 3}; -- не будет сохранена
            x = 8; -- не будет сохранена
        }
    }

    Что с глобальными переменными?

    В stead3 теперь отслеживается доступ к неинициализированным переменным. Таким образом, описки в именах переменных, обращение к несуществующей переменной -- сразу дадут ошибку. Присвоение неинициализированных переменных разрешено только если:

    1. значение - это объект
    2. значение - это функция

    Всего теперь есть три вызова:

    global -- объявление глобальной переменной
    const -- объявление константы (стед3 сдедит за тем, чтобы переменная не менялась)
    declare -- объявление переменной, за которой не следит stead3

    Форма записи допускает следующие варианты использования:

    Как раньше:

    declare {
       a = 1,
       b = 2, 
    ...
    }

    Или одиночное объявление:

    declare 'myfunc'  (function() pn "Hello!" end)
    global 'X' (11)

    Все формы объявлений контролируют уникальность имен переменных. Вы не сможете создать две переменные с одинаковыми именами.

    Для чего нужен global и const -- понятно. Но зачем declare?

    В stead2 единственным способом записать функцию в save была конструкция code [[ ]]
    В stead3 такой конструкции нет. Зато тут можно объявлять функции!

    declare 'myfunc' (function() pn "Hello!" end)
    global 'X' (myfunc)

    X сохранится и в save будет записана ссылка на функцию! Так что, теперь вместо code можно декларировать функции. Но это можно делать только заранее, в глобальном контексте игры, примерно как определяются объекты/комнаты.

    declare также полезен в тех случаях, когда вам не нужно, чтобы инстед вообще не следил за вашей структурой данных.

    Что с динамическими объектами?

    У нас есть new, но прототип теперь другой. В качестве иллюстрации, напишу пример:

    declare 'mycat' (function(nam)
        return obj { nam = nam; dsc = 'Тут сидит котик!' }
    end)

    где то в недрах игры:

    act = function(s)
        p [[Я взял еще одного котика.]]
        take(new(mycat, "Барсик"))
    end

    Как видим, теперь new принимает на вход не текст, а задекларированный конструктор и параметры к нему в виде параметров функции.

    to be continued...

  20. MaJoR KolZ

    Feb 2017 Постоялец Харьков User since 2014
    Edited 8 months ago by MaJoR KolZ

    peter В stead3 теперь отслеживается доступ к неинициализированным переменным.

    Вот это круто!

    P.S. А есть какие-нибудь приблизительные сроки когда будет релиз?

  21. Newer ›

or Sign Up to reply!