1 (edited by VTroll 2011-12-10 19:53:34)

Topic: [бета] GREMLINS (Парсерная игра - адвентюра)

Игра в репозитории instead⚫games

Представляю вашему вниманию адвентюру "Gremlins". Её английский вариант был популярен на Спектруме в 80-е годы. Я как поклонник этого жанра, в начале 90-х русифицировал эту игру и решил сделать её ремейк на Instead.

Игра создана по одноимённому всем известному фильму. Автор сценария игры: Scott Adams, программа на Спектруме была выпущена Британской фирмой Adventure International. Над игрой работал программист Brian Howarth и художник Teoman Irmak.

Итак, на сегодняшний день могу предложить посмотреть небольшую демо-версию игры. В ней всего четыре локации. Хотелось бы услышать мнение об игре, замечания, предложения. Сразу скажу насчет графики - графика будет оригинальной с ZX-Spectrum, возможно некоторые локации без графики будут мной дополнены, как в случае с "проулком". В игре, как и в фильме, вашей целью является освобождение города от наводнивших его гремлинов.

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

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

С уважением, Владимир

2 (edited by Peter 2011-12-10 20:45:16)

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

В файле parser.lua заменить строку
-            input.histpos = #input._history + 2;
на
+            input.histpos = #input._history + 1;

В svn исправил.

И еще кое что. Исправил parser.lua игровой. Приаттачиваю.

Post's attachments

Attachment icon parser.lua.zip 4.32 kb, 154 downloads since 2011-12-10 

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Еще совет. вместо parser:word() лучше (когда это возможно) использовать parser:obj()
Так, вместо parser:word('гремлина') лучше использовать parser:word(gremlin1)

:word используется когда доп слово - это не объект сцены.

Кроме того, в word можно использовать алиасы:
parser:word("кухн/ю")
parser:word("наверх,верх,вверх")
итд.

Еще:

Вообще, на первом экране логичнее attack прописать не в комнате, а у gremlin1, и проверять на parser:obj(sword) и parser:obj(knife), сейчас по-моему нечто не корректное.

Плюс, вот еще одно средство:

obj_desc = obj {
    nam = 'descriptor';
    dsc = function(s)
        local k,v
        local no = true
        for k,v in opairs(objs()) do
            if not v.dsc then
                local n;
                if v.disp then
                    n = call(v, 'disp');
                else
                    n = call(v, 'nam');
                end
                if no then
                    p [[Вы видите: ]];
                else
                    pr [[, ]]
                end
                pr(n)
                no = false
            end
        end
        if not no then
            p "."
        end
    end
}

proom = function(v)
    v = room(v)
    putf(obj_desc, v)
        putto('obj_desc', v, 1000)
    return v
end

Если это воткнуть в начало игры, и создавать комнаты как:

kitchen = proom {
....
То все предметы, помещенные в комнату, у которых нет dsc, будут описываться группой. Вы видите:... список. Как в инвентаре. При этом будет использоваться nam, либо disp. (Для disp - приоритет).

И тогда код будет проще.

В целом, парсер жизнеспособен. smile

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Замечания по поводу последнего средства:

всё хорошо смотрится, если все предметы не имеют описания dsc, но если хоть один предмет имеется (а там, допустим, dsc с функцией различного вывода имени объекта), то после перечисления обычных предметов ставиться "." и вдруг продолжаются другие объекты. Хорошо было бы между всеми предметами автоматически ставить "," и только после абсолютно всех "."

Нашел выход: вместо dsc прписываю disp и всё становится так, как я хотел.

С уважением, Владимир

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Используйте disp вместо nam и dsc. Идея была в том, что объекты с dsc должны выводиться отдельно, а без dsc - в группе. Вообще то группа должна всегда быть последней.
P.S.
Нашел баг.
Улучшенный вариант:

obj_desc = obj {
    nam = 'descriptor';
    dsc = function(s)
        local k,v
        local no = true
        for k,v in opairs(objs()) do
            if not v.dsc then
                local n;
                if v.pdsc then
                    n = call(v, 'pdsc');
                else
                    n = call(v, 'nam');
                end
                if no then
                    p [[Вы видите: ]];
                else
                    pr [[, ]]
                end
                pr(n)
                no = false
            end
        end
        if not no then
            p "."
        end
    end
}

proom = function(v)
    v = room(v)
    v.obj[1000] = 'obj_desc'
    return v
end

Для показа используется nam или pdsc. То-есть если описание функция - то описываем его как pdsc (не dsc)

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Это можно использовать, если нужно разделить предметы от персонажей. Например:

Я вижу: дом, дуб, жёлудь. Здесь находится Огерон. Страшный Кавезат.

Можно объекты с живыми персонажами описывать в dsc. И добавить как-нибудь, чтоб был вывод такой:

Я вижу: дом, дуб, жёлудь.
Здесь есть: Огерон, Алиса, Страшный Кавезат.

С уважением, Владимир

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Там у меня баг был - выше исправил. Итого вывод будет такой.

Сначала все dsc (как в классическом инстеде)
Потом
Я вижу: тут либо nam, либо pdsc.


Если нужно изменить порядок, то вместо v.obj[1000] написать putf('obj_desc', v)

p.s. от disp отказался - тк он используется в инвентаре, pdsc более безопасно

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Нашел баг.
Улучшенный вариант:

Теперь вместо disp в персонажах пришлось прописать pdsc - но разницы не вижу. Баг был, вроде бы я заметил появление не нужного предмета (головы в камине), но исправил другим методом: убрал предмет из перечня объектов гостинной и в нужное время вставил "голову" с помощью put().

С уважением, Владимир

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Да про disabled  я забыл.
Еще исправление.
pdsc vs disp - могло всплыть потом. лучше pdsc.

obj_desc = obj {
    nam = 'descriptor';
    dsc = function(s)
        local k,v
        local no = true
        for k,v in opairs(objs()) do
            if not v.dsc and not isDisabled(v) then
                local n;
                if v.pdsc then
                    n = call(v, 'pdsc');
                else
                    n = call(v, 'nam');
                end
                if no then
                    p [[Вы видите: ]];
                else
                    pr [[, ]]
                end
                pr(n)
                no = false
            end
        end
        if not no then
            p "."
        end
    end
}

proom = function(v)
    v = room(v)
    v.obj[1000] = 'obj_desc'
    return v
end

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Я думаю что это сложно, но всё же осмелюсь спросить: можно ли в моей программе использовать персонажей описывая их dsc, а предметы описывать pdsc. Или если нельзя dsc , то например персонажей в pdsc, а предметы в nam. И устроить вывод их так:

Здесь есть: (перечислить персонажей через запятую).
Вы видите: (перечислить предметы через запятую).

С уважением, Владимир

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Сделать можно, но я не понял в чем суть.
Сейчас и так будет две группы. dsc - как есть. pdsc - перечисление. Что именно нужно?
1) перевод строки между группами?
2) несколько типов групп в стиле pdsc?

Мне кажется 2 не нужен - какой критерий в разделении списков? Живой не живой или что? Думаю, что вывод в виде.

В центре комнаты стоит стол. На столе ручка. Здесь есть: меч на стене, дротик, гремлин. Наиболее универсален. В общем нужно понять что требуется.

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Да сейчас две группы, но я хотел разделить на персонажей и предметы. И перед персонажами вывести начало (Здесь есть: или здесь находится/дятся:), так же как перед списком предметов (Я вижу:)

В некоторых адвентюрах, таких, например, как KENTILLA. Вывод делается так:

Я нахожусь в маленькой светлой комнате.
Выход: открыта дверь на юг.
Здесь есть: маг Огерон.
Я вижу:  стол, меч на столе.

То есть здесь есть два списка: один предметов, другой персонажей. Причем если персонаж убит - он всё равно в списках персонажей находится.

Допустим в оригинальном GREMLINS там всё в одном списке, даже перечисляются не через запятую, а через точку. Но ведь можно усовершенствовать, сделать лучше, яснее.

С уважением, Владимир

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Ок, универсальное решение:

pobj_dsc = function(dsc1, dsc2, selector)
    return function(s)
        local k,v
        local ob = {}
        local ppn = false
        if not dsc2 then dsc2 = dsc1 end
        for k,v in opairs(objs()) do
            if not v.dsc and not isDisabled(v) and selector(v) then
                stead.table.insert(ob, v);
            elseif not isDisabled(v) and #ob == 0 then
                ppn = true
            end
        end

        if #ob ~= 0 then
            if ppn then pn() end
            if #ob == 1 then
                p (dsc1);
            else
                p (dsc2);
            end
        end 

        for k,v in pairs(ob) do
            local n;
            if v.pdsc then
                n = call(v, 'pdsc');
            else
                n = call(v, 'nam');
            end
            pr(n)
            if k < #ob - 1 then
                p ","
            elseif k == #ob then
                p "."
            else
                p " и"
            end
        end
    end
end

obj_desc = obj {
    nam = 'descriptor';
    dsc = pobj_dsc("Я вижу","Я вижу:", function(s) -- группа объектов без live свойства
        if not s.live then 
            return true 
        end
    end);
}

obj_desc2 = obj {
    nam = 'descriptor';
    dsc = pobj_dsc("Здесь находится", "Здесь находятся:", function(s) -- группа объектов с live свойством
    if s.live then 
        return true
    end
    end);
}

proom = function(v)
    v = room(v)
    v.obj[1000] = 'obj_desc' -- первая группа
    v.obj[1001] = 'obj_desc2' -- вторая группа
    return v
end

Можно делать сколько угодно групп. Мн и ед число. Разделители между группами (могут глючить - тестить нет возможности сейчас детально), если что - объясню детали.

В примере две группы. Сначала объекты без live, затем с live:

gremlin1 = pobj{
    live = true;

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Супер!!! Просто класс! Идеальный универсальный вариант. Игрушка сейчас выглядит просто "как конфетка". Багов не обнаружил. Всё без глюков. Особенно эффектно выглядит "и" перед последним предметом. Спасибо огромное.

С уважением, Владимир

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

все для творчества:)

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Обнаружил баг в игре: парсер не понимает два введённых глагола, а у меня в глаголах стоят и "вниз" и "идти" для облегчения прохождения, также не работали команды; идти на север, идти на юг и т.п. Вместо них можно было вводить "север", "юг". Хотелось чтобы работало по-разному: и "идти на север" и просто "север". Немного по-эксперементировав с парсером, изменил несколько строчек внутри него и баг был уничтожен. Вот часть в парсерном блоке:

if #v > 1 then
verb = v[1]
   if not ((verb) == "go") then
   p "Слишком сложное предложение, перефразируйте его по-короче." 
   return
   end
end

Не зная как на Lua пишется знак "не равен" (в других языках он такой: <>), поэтому пришлось
нестандартно написать if not ((verb) == "go") then

С уважением, Владимир

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

VTroll wrote:

Не зная как на Lua пишется знак "не равен" (в других языках он такой: <>), поэтому пришлось нестандартно написать if not ((verb) == "go") then

if verb ~= "go" then smile

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Честно говоря, игра мне не очень понравилась. Бессмысленно кровожадная она какая-то. sad Может, лет 20 назад я и сам бы играл в такое, но не сейчас... smile

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Мне наоборот, понравилась больше леса.  И не такая мрачная/гнетущая как "Гиблые земли", но просто пока слишком мало. Кровожадность тут условна, на мой взгляд.

По поводу парсера, я глянул в код -там уже есть какая-то поддержка переходов по ways.

см: game.go = function(s, o)

То-есть, по идее - если переходы сделаны в виде ways (как в обычном непарсерном инстеде, но только у комнат могут быть pat), то не ничего делать не надо - переходы будут работать сами. Другое дело - как сделать альясы переходов без глагола идти.

Потом гляну внимательнее. Может просто сделать так - если слово одно (или нет глаголов) и это way, то делать go?

P.S. где взять последнюю версию гремлинов - может я прямо в ней подправлю?

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Владимир, а русифицированная версия под Спектрум сохранилась?

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Серый волк, русифицированная и оригинальная английская версии у меня имеются. Я их проигрываю на эмуляторе Спектрума.

Peter, я понял про ways, но ими не стал пользоваться, в другой игре возможно применю. Последнюю версию закину на неофициальный депозиторий. http://instead.nailedgames.com/

С уважением, Владимир

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Владимир, тогда когда будет минутка, пришлите, пожалуйста, русифицированную на ящик serwj-volk(пёс)yandex.ru. Собираю архив игр, этой раньше не попадалось. Заранее спасибо.

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Серый Волк, письмо с игрой отправил.

С уважением, Владимир

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

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

С уважением, Владимир

Re: [бета] GREMLINS (Парсерная игра - адвентюра)

Варианты:
1) exit/left обработчики
2) life

Нужно уточнить что именно нужно.