Много типовых, а также много уникальных

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

То есть я хочу чтобы там еще объекты разные были в каждой локации свои, ну и чтобы выкинуть можно было
а потом подобрать.

То есть просто двумерный массив на такое хранение не прокатит...

Ну и как мне описать room, у которого dsc, nam, ways, etc. зависят от x, y? к тому же еще некоторые переходы
могут быть по логике заблокированы (нужен ключ, завал, и тд.) и как это удобнее опять же хранить, что возвращает к вопросу описания двнных. Сделал несколько вариантов тестового кода, но ни один за основу не взять,
так как проблема с ways...
ways актуально в том плане, что хочется "компас" - то есть нужно действовать в терминах лево-право, вперёд/назад,
чтобы выходы были с одинаковым текстом и при выходе выполнялась логика, меняющая соответственно x, y и обновляющая всё, что выводится.

Дайте пожалуйста пример минимального лабиринта на Instead.
Типа с одной комнатой, динамической dsc, pic, obj, etc. Что-то я затупляю сильно...

Я чета туго соображаю наверное сегодня...
А как я пойму, надо ли мне данные генерировать, или они у меня уже есть?

Вот есть в игре лабиринт, хочется его генерировать 1 раз при первом обращении (посещение нужной локации, например), и оставлять далее без изменений, для данного сейва. Чтобы оно сохранялось, и загружалось.

Как такое осуществить?

Короче, есть часть игры, представляющая из себя условно "рогалик".
То есть есть более-менее представимая в виде карты область из комнат, связанных между собой переходами.
В комнатах есть разные неуникальные предметы, уникальные предметы, и разные уникальные/неуникальные
NPC. Комнаты по идее все уникальные, хотя и сторятся по одному принципу (тка как в них бывают разные предметы и npc). Всё должно быть достаточно рандомно (кроме количества комнат и их расположения, то есть переходы (в том числе их наличие и отсутствие), предметы/npc - рандомны, количество и расположение - нет.
Хочется придумать оптимальное представление, чтобы это было быстро, и не жрало много памяти.

Что косается нужности этого всего - за штраф виде потери некоторой премиальной составляющей, момент, скорее всего будет проходиться посещением всего нескольких локаций. Еслия не передумаю smile

Ну про lua я знаю, мне бы в архитектурном плане

Нужно сделать большой набор связанных между собой локаций, в которых ГГ будет собирать
разные предметы (имеющие чисто количественное значение), и немного воевать с врагами.
Так же там будет несколько квестовых предметов. А-ля мини-рогалик smile
Нужно, чтобы расположение генерилось процедурно при старте игры, и более не менялось.
Как бы минимализировать хранимые данные? Локации строятся по единой схеме,
там есть мебель (в том числе контейнеры типа шкафов и сундуков), могу быть "ресурсные предметы",
могут быть квестовые предметы, могут быть NPC.

И еще попутный вопрос - есть объекты, меняющие не только название, но и использование, типа [1] = 'нечто', [2] = 'горшок' [3] = 'черепки' , и использовать можно в состояниях 2 и 3, и в разных целях. Как лучше такое делать - разные объекты подменять, или сделать один с функциями на nam, tak, dsc?

Дык можно переложить часть нагрузки на страждущих.
Могу на выходных попробовать пройти. К тому же для меня это будет жутко интересно,
так как на Спектруме не закончил проходить smile

Так, тут мне подумалось... а сколько надо задонатить, чтобы в ЗН битвы сделать? smile

11

(40 replies, posted in Игры)

vvb wrote:
j-maks wrote:

Впечатления отличные, годный зомботреш.

что взяли за моду называть любую короткую игру трешем? если пётр это слово употребляет в каждой третьей фразе, это не повод прицеплять его к любому проекту. он может свои проекты называть как угодно.
треш -- мусор, isn't it? а автор старался. меня бесит это слово по отношению к чужим проектам. будьте вежливы к авторам. тем более начинающим.

Жанр же вроде такой, нет? Имеющий отношение к Золотому веку Голливуда? И позорного в нем ничего нет,
это просто обозначает экспулатацию известной раскрученной темы. Ничего плохого в этом нет,
тема зомбей, наверное, никогда себя не исчерпает.

Сделал как-то так:

-- $Name: Test23$
-- $Version: 0.0$

require("namespace")

function namespace_with_self(s, name)
        function rep_self(d)
                local l, k
                for l, k in pairs(d) do
                        if type(d[l]) == "string" then
                                d[l] = k:gsub("#", name..".")
                                print(l, d[l])
                        elseif type(d[l]) == "table" then
                                rep_self(d[l])
                        end
                end
                return d
        end
        return namespace(rep_self(s))
end
db = namespace_with_self({
        test = obj {
                nam = "Ничто",
                tak = "Я не взял ничего",
                dsc = function(s)
                    p"Я не вижу {ничего} интересного"
                    p(s.key_name)
                end
        },
        test2 = room {
                nam = "Тест2",
                dsc = "Где-то там",
                way = {"main"},
                obj = {
                        "#test",
                },
        },
}, "db")

main = room {
        nam = "Начало",
        dsc = "Что-то здесь не так",
        obj = {"db.test"},
        way = {
                "db.test2",
        }
}

Но хочется чего-то большего, светлого и хорошего...

По идее, можно пристраивать key_name к строковым именам объектов в namespace, этого будет достаточно,
внутри функция объектов все видно, но не видно в функции инициализации namespace...

То есть что делать - понятно, непонятно как делать...

Так, тогда сяду думать...

ну просто если допустим так:

library = namespace {
      function dsc_const(s)
...
      end
      table = obj {
             dsc = deref(this).dsc_const
...
      }
      mirror = obj {
...
      }
      room_normal = room {
...
          obj = {
               this..'.table',
               this..'.mirror',
          },
      }
      room_twisted = room {
...
          obj = {
               this..'.table',
               this..'.mirror',
          },
      }
}

ну то есть чтобы использовать как референс.
Это полезно, например, в функциях-фабриках ("конструкторах"), чего у меня будет много.
Ну вот какая-то конструкция надобна... по минимуму, чтобы имена объектов строить, по максимуму - чтобы даже
к ним иметь возможность обратиться, как вверху заполняется .dsc.
Вроде кто-то делал полную объектную систему для lua с this/self'ами, мож там есть что вытянуть можно...

А, еще было бы неплохо иметь какой-нибудь this или self для namespace...
чтобы правило инкапсуляции до конца работало...

а room'ы и dlg можно в неймспейс?

Буду с ним играться.

а чем плох key_name?
Хотя наверное так правильнее.
Сейчас использование такое (ссылку ddlg убрал)

harry = npc("harry", {})
harry._dlg.key_name = 'harry._dlg'
alice1 = npc("alice", {})
alice1._dlg.key_name = 'alice1._dlg'

вот если бы эти вторые строчки сами получались...
А нельзя такие объекты таки в свой собственный неймспейс увести,
чтобы не мешались? Это если модуль писать?

Да, c key_name все работает.

так, осознал что такое key_name, пробую...

key_name - это куда засунуть - при вызове dlg?

так, я не доконца понял что делать...
Короче, чтобы не бороться с автосейвом, который принимал
charstats.*.dlg за комнату (и ругался, что не может ее сохранить, даже если там не было dlg { а было просто {
я привел код к такому виду:

function npc(name, data, ddlg)
        local cp = charstats[name]
        local r = obj {
                nam = cp.name,
                _data = {},
                _dlg = dlg(cp.dlg),
                ddlg = ddlg,

                dsc = function(s)
                        local kdsc
                        local ukdsc

                        if s._data.knowndsc then
                                kdsc = s._data.knowndsc
                        else
                                kdsc = "Я вижу {"..s.nam.."}"
                        end
                        if s._data.unknowndsc then
                                ukdsc = s._data.unknowndsc
                        else
                                if s._data.class == "female" then
                                        ukdsc = "Я вижу незнакомую {девушку}."
                                elseif  s._data.class == "male" then
                                        ukdsc = "Я вижу {незнакомца}."
                                end
                        end


                        if s._data.known then
                                ldsc = kdsc
                        else
                                ldsc = ukdsc
                        end
                        p(ldsc)
                        if s._data.firsttime then
                                p(s._data.firsttext)
                                s._data.firsttime = false
                        end
                end,
                act = function(s)
                        if s._data.acttext then
                                p(s._data.acttext)
                        end
                        walkin(stead.deref(s.ddlg))
                end,
                life = function(s)
                        if player_moved() and where(s) ~= s._data.where then
                                move(s, s._data.where, where(s))
                        end
                end,
                save = function(s, name, h, need)
                        if need then
                                h:write(stead.string.format("%s = npc(%s, {})\n",
                                        name, stead.tostring(s.nam)))
                        end
                        stead.savemembers(h, s, name, false)
                end

        }
        local k, v
        r._dlg.save = function(s, name, h, need)
                local dsc;
                if need then
                        h:write(stead.string.format("%s = dlg {charstats."..s.chnam..".dlg}\n",
                                name))
                end
                stead.savemembers(h, s, name, need);
        end
        r._dlg.chnam = name
        for k, v in pairs(cp) do
                r._data[k] = v
        end
        r._data.dlg = nil
        for k, v in pairs(data) do
                r[k] = v
        end
        return r
end

Использование:

global {
        charstats = {
                alice = {
                        name = "Алиса",
                        strength = 100,
                        health = 100,
                        class = "female",
                        known = false,
                        knowndsc = [[Я вижу {Алису}, сидящую в кресле]],
                        unknowndsc = [[Я вижу худую {девушку} с каштановыми волосами,
                                     сидящую в кресле]],
                        firsttime = true,
                        firsttext = [[Ее худоба, ее взъерошенные волосы, темные, почти черные глаза, в этом адском освещении
                        создавали ощущение, что передо мной не девушка, изможденная, но за невзгодами не утратившая еще
                        своей природной красоты, а существо с другой планеты, или чудовище, сошедшее со страниц каких-нибудь
                        страшных сказок]],
                        where = 'dorm1_ent_chairs',
...
                        dlg = {
                                nam = "Алиса",
                                phr = {
                                        {
                                                "Привет!", "Здравствуй.", [[pon('hi');]],
                                        },
                                        {
                                                 tag = 'hi', false, "Меня зовут Яков. А как тебя зовут?", "Алиса",
                                                [[charstats.alice.known = true;pon('intro');]],
                                        },
...
                                                Конечно, если хочешь проснуться утром.]],
                                        },
                                }
                        },
                },
                harry = {
                        name = "Гарри",
                        strength = 100,
                        health = 100,
                        class = "male",
                        known = false,
                        knowndsc = [[Я вижу охранника {Гарри}.]],
...
                        where = 'lobby',
                        dlg = {
                                nam = "Гарри",
                                phr = {
                                        { "Здравствуйте.", [[Добро пожаловать,
                                        приятель. Представься, мне нужно
                                        сделать запись.]],[[pon("intro");]]},
...
                                },
                        }
                },
...
}
...
harry = npc("harry", {}, 'harry_dlg')
harry_dlg = harry._dlg
alice1 = npc("alice", {}, 'alice_dlg')
alice_dlg = alice1._dlg
...
lobby = room {
        forcedsc = true,
        nam = "Холл",
        dsc = [[Огромный, плохо освещенный зал, обставленный старой
                мебелью.]],
        way = {
                'ladder',
                'elevator',
                'corridor',
        },
}
...
dorm1_ent_chairs = room {
        nam = [[Стол и кресла]],
        dsc = [[Стол и кресла представляют с собой образчик старой мебели, классифицируемой как рухлядь.
                Цвет обивки стульев навозможно разобрать, а поверхность стола выщерблена, как будто 
                на нем рубили дрова. Но видно, что мебель еще прочная, и используется -- на стульях
                видны следы ремонта.]],
        way = {
                'dorm1_enterance',
        },
}

Да, с выставлением в глобальный спейс работает, если передать параметром ссылку и делать walkin в неё.

Дык не хочется еще одну неотделимую, но отдельную сущность плодить - необъектненько как-то... да и много их будет...

Дык оно вроде как требует позвать конструктор, который должен быть в глобальном неймспейсе. Не хотеть...