Механика времени: как таймер добавляет в расследование напряжение.

Механика времени: как таймер добавляет в расследование напряжение.

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

Зачем детективу таймер?

Казалось бы - расследование, вникай себе спокойно, зачем гнать. Но вот в чём фокус: без ограничения времени детектив теряет напряжение. Можешь обыскать каждый угол, опросить всех по десять раз, перепробовать все варианты. Мне кажется, скучно и беззубо.

Время всё меняет. Оно превращает расследование в выбор. У тебя всего 6 часов - и ты физически не успеешь сделать всё. Пойти на маяк или в клуб? Дожать свидетеля или осмотреть комнату? Каждое решение теперь чего-то стоит. Ты не «проходишь контент», ты расставляешь приоритеты, как настоящий следователь под давлением.

И ещё - таймер создаёт ставки. Убийца может уйти. Шторм приближается, паром вот-вот отчалит. Это не абстрактный счётчик в углу, а тикающая угроза.

Время как валюта.

Главный принцип: каждое действие стоит минут. У меня это работает так:

  • Задать вопрос персонажу - 10 минут
  • Осмотреть предмет, попытка обыска — 2 минуты
  • Переход между локациями - тоже расход

Игрок получает бюджет - 360 минут (6 часов) - и тратит его как хочет. Хочешь опросить Фриду по всем темам? Это десятки минут. А их можно было потратить на дорогу к мысу. Вот и думай, что важнее.

Это заставляет играть иначе. Ты не можешь быть перфекционистом. Приходится оставлять что-то неосмотренным - и жить с этим. Как в жизни.

Как это устроено в коде:

Основа до смешного простая - обычная переменная. В StoryInit задаю стартовый бюджет:

State.variables.remaining_minutes = 360;

Дальше каждое действие просто вычитает из неё. Вот как выглядит вопрос Фриде:

<>

<>

Вычли 10 минут, обновили циферблат.

Циферблат, который не просто число.

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

Хитрость тут в CSS-свойстве conic-gradient (конический градиент - заливка по кругу). Функция считает, какой процент времени остался, переводит в градусы и рисует сектор:

window.updateClock = function () {
var mins = State.variables.remaining_minutes || 0;
var pct = Math.max(0, Math.min(1, mins / 360));
var degrees = Math.round(pct * 360);
var gradient = "conic-gradient(#ff9900 0deg, #ff9900 "
+ degrees + "deg, #2a3828 " + degrees
+ "deg, #2a3828 360deg)";
$("#clockFace").css("background", gradient);
$("#clockMinutes").text(mins);
};

По-человечески: беру остаток минут, считаю какую долю от 360 он составляет, умножаю на 360 градусов - и рисую оранжевый сектор на этот угол, остальное заливаю тёмным. Чем меньше времени - тем меньше оранжевого. Игрок видит, как круг «съедается».

Механика времени: как таймер добавляет в расследование напряжение.

Режим тревоги.

Отдельная мелочь, которая хорошо работает на нервы. Когда остаётся час или меньше - циферблат переключается в тревожный режим:

if (mins <= 60) {

$(".clock-container").addClass("warning");

} else {

$(".clock-container").removeClass("warning"); }

Просто добавляю класс warning, а дальше уже CSS делает своё - краснота, может пульсация. Игрок сразу чувствует: время на исходе, пора решаться. Это тот самый момент, когда рука тянется наконец предъявить обвинение.

Чтобы таймер обновлялся сам.

Чтобы не дёргать updateClock() вручную на каждом экране, я повесил его на событие перехода между пассажами:

$(document).on(":passageend", function () {

updateClock();

});

:passageend - это встроенное событие SugarCube, которое срабатывает каждый раз, когда игрок попадает на новую страницу. Теперь циферблат сам перерисовывается при любом переходе. Один раз настроил - забыл.

Про баланс - сколько времени дать.

Это оказалось самым сложным, и это не про код, а про геймдизайн. Сколько минут дать игроку?

  • Мало - фрустрация. Не успеваешь ничего, злишься, бросаешь.
  • Много - таймер не ощущается. Раз времени вагон, зачем он вообще.

Я целюсь в золотую середину: времени должно хватить, чтобы раскрыть дело, но только если не распыляться. Игрок, который ходит по делу и думает - успевает. Игрок, который тыкается наугад во всё подряд - не успевает. Таймер награждает за собранность, а не наказывает за любопытство. Точные цифры я ещё докручиваю на тестах - это подбирается только вживую.

Механика времени: как таймер добавляет в расследование напряжение.

Честность с игроком.

Важный принцип: таймер не должен быть подлым. Игрок всегда видит, сколько осталось (вот он, циферблат в углу). Каждое действие честно показывает цену. Никаких внезапных «упс, время вышло» из ниоткуда.

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

Пока получается так
Пока получается так

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

А как ты относишься к таймерам в играх? Заводят и держат в тонусе - или бесят и мешают спокойно вникать? Знаю, что тема спорная, интересно мнение 👍