Перейти к содержимому

Когда не работает

Ошибок mlog не выдаёт. Значит, искать придётся самому — и есть порядок, в котором это делают

Программа с ошибкой в mlog не падает, не краснеет и ничего не пишет в угол экрана. Она просто считает не то, что вы имели в виду, — и делает это шестьдесят раз в секунду, уверенно и молча.

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

Что видно Куда смотреть
ничего не происходит вовсе выполняется ли программа: @counter стоит на месте или ходит
считает, но не то значения переменных: какое первым перестало быть тем, что ожидали
работает, а потом ломается итерация: со второго прохода переменные приходят не пустыми

Третий — самый коварный, и чаще всего именно он. Программа выполняется в бесконечном цикле, и на второй итерации всё то же самое выполняется в другой обстановке.

Главный приём разбора — не запускать программу, а проходить её по одной инструкции. На «пуске» видно только последствия; на шаге видно, какая строка их создала.

Порядок такой:

  1. «Сначала» — сбросить всё, чтобы смотреть с чистого листа.
  2. Шаг — одна инструкция. После каждого шага смотреть в таблицу.
  3. Найти первую строку, после которой значение стало не тем, которое ждали. Ошибка в ней или выше, ниже её искать бессмысленно.
  4. Если до нужной строки дело вообще не доходит — смотреть на @counter: он показывает, какая строка выполнится следующей.

Это ровно то, чего в игре нет: там процессор либо работает, либо выключен. Шаг — наша кнопка, и держим мы её именно ради разбора.

Программа ниже должна была считать, сколько всего сделано из десяти и какая это доля. Нажмите «сначала», потом четыре раза «шаг» и посмотрите в таблицу.

тик 0
Установить0
=
Операция1
=
Операция2
=
Операция3
=
@counter0number
цельnullnull
счётnullnull
осталосьnullnull
доляnullnull
всегоnullnull

После первой итерации: цель равна 10, счёт — единице, осталось — девяти. Пока похоже на правду. А доля пуста, хотя должна быть числом.

Теперь нажмите «пуск» и подождите пару секунд. Картина меняется: счёт перевалил за десяток и растёт дальше, осталось ушло в минус, доля всё так же пуста.

Здесь две разные ошибки, и обе типичные.

доля пуста, потому что всего никто не заполнил. В строке op div доля счёт всего делитель — переменная, которой не присваивали ничего, то есть null. В арифметике null считается нулём, а деление на ноль в mlog не даёт ни бесконечности, ни ошибки: результат просто «ничего». Пустая переменная в ответе почти всегда значит, что пустым было что-то из того, что в него пошло.

счёт растёт без остановки, потому что программа выполняется в бесконечном цикле. op add счёт счёт 1 прибавляет единицу к тому, что накопилось с прошлого прохода, а проходов шестьдесят в секунду. Строка сама по себе верная — неверно ожидание, что она выполнится один раз.

  1. Опечатка в имени. В таблице появляется лишняя строка с почти таким же именем и значением null — подробно об этом в уроке «Окно переменных».
  2. Пустая переменная в вычислении. null не ругается, а считается нулём: сложение даёт слагаемое, умножение — ноль, деление — пустоту. Ищите не там, где пусто, а там, где должно было заполниться.
  3. Забытая итерация. Переменная, которую ждали пустой, приходит со значением прошлого прохода. Проверяется одним нажатием «сначала»: если первая итерация правильная, а дальше всё едет — дело в итерации.

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

Нет «сломанной» программы. Незнакомая игре строка не ломает остальные — она просто не выполняется, а вы ищете, почему пропал кусок логики. Откуда она берётся, сказано в уроке «Программа — это текст».

Неофициальный проект, с Anuke не связан. Спрайты, шрифты и переводы Mindustry © Anuke, используются по GPL-3.0; Fira Code — по OFL-1.1. Код сайта — GPL-3.0.