браузерный порт старой консольной игрушки

Где-то в начале 2000-х эта консольная игрушка для MS-DOS была популярна и на нашем факультете, хотя
мы и не матмехе. Кто-то принес на дискете. Игра представляет собой текстовый квест, в котором в котором
предлагается сдать сессию на матмехе СПбГУ.
Не так давно обнаружил ее порт на JS. Порт делался дизассемблированим
и причесыванием кода.
Проект, видимо, заброшен. Я немного поиграл, и нашел некоторые баги и спорные моменты.
Например, автор весьма оригинально сделал подход к асинхронности - каждый раз по нажатию на кнопку, вся логика
игры запускается заново, но без отрисовки на экране. Весь код хранится в html файле, для отрисовки используется
таблица. С последним мириться было нельзя, и я принялся за дело.
Сборка
Прикрутил webpack, сборку, запуск в dev-режиме. Можно будет прикрутить babel, настроить компиляциюasync/await для старых браузеров, но не нужно.
Асинхронность
Вместо сложной логики перезапуска игры по нажатию кнопки, проще писать async/await почти везде. Так что я обернул
большинство функций в асинхронные вызовы.
Сначала стал вешать обработчик события в момент вызова функции, и снимать после того, как кнопка нажата. Но оказалось,
что это чувствуется, и часть нажатий теряется. Так что сделал очередь на нажатые кнопки, а ReadKey проверяет эту очередь,
и, либо сразу резолвит промис, либо сохраняет его, если очередь пуста.
1 | const keyBuffer = []; |
Терминал
Выпилил самописный терминал, и добавил xterm.js
Окрашивание текста проихвожу через вывод ANSI-последовательностей. Буду добиваться возможности запуска из node.js,
а не только из браузера.
Сложности
У xterm.js есть проблема определить текущее положение курсора.
В интернетах советуют использовать term.buffer.active.cursorY, но если перед вызовом мы пытаемся что-то вывести,
то это попадет в буфер, и курсор не сдвинется.
Вызов Delay(0) перед получением свойства сработал, но все это как-то некрасиво
1 | await Delay(0); |