KerboScript в примерах и задачах. Часть 0. Базовые функции языка и математика

Kerbal Space Program » Гайды

Всем когда-нибудь надоедает играть в стоковую KSP, после чего игра удаляется нафиг обвешивается кучей модов и начинается по-настоящему. Ваш покорный слуга после постройки станции на Муне решил, что с прямым управлением неинтересно, и поставил RemoteTech. Обнаружилось, что на Дюну в этом случае худо-бедно зонд ещё можно мягко посадить, то на безатмосферные планеты и спутники сажать выходит только жёстко. Гонять Джеба на Илу только ради того, чтобы было кому посмотреть на термометр на поверхности, показалось негуманно. Было принято нелёгкое решение: отправить Джеба на работу в Кербинские авиалинии наблюдать за барометром на высоте более 18,3 км над Зоной 8XJD5V, а для исследования космоса заменить его автоматикой.

Такое решение было навеяно ещё и желанием воспроизвести, в некотором смысле, советскую космическую программу. А она, как известно, полагалась больше на автоматику, чем на ручное управление.

Самый, пожалуй, известный мод для автоматизации полетов - это MechJeb kOS - Kerbal Operating System. Он позволяет писать программы для автоматизации практически всего и управления кораблём почти так же, как вручную, только на автомате. При установленном RemoteTech это очень удобно, поскольку можно управлять аппаратом, не имея связи с космическим центром, только последовательность команд продумать и загрузить в крафт нужно заранее.

Данный гайд посвящен написанию kOS скриптов для аппаратов в начале карьеры. Другие гайды:

Далее предполагается, что читатель знаком с основными понятиями, такими как апоцентр, перицентр, наклонение, дельта-V, удельный импульс и т.п.

Список установленных модов помимо kOS (если хочется скачать крафты и посмотреть).
Новые части:
  • Asteroid Day
  • Cryogenic Engines
  • Cryogenic Tanks
  • DMagic Orbital Science
  • Docking Camera (KURS)
  • Kerbal Atomics
  • Kerbalism
  • KSP Interstellar Extended
  • RealChute
  • RemoteTech
  • SpaceY Heavy Lifters
  • Universal Storage
  • USI Kolonization
  • Ven's Stock Part Revamp

Геймплей:
  • Community Tech Tree
  • Kerbalism
  • Kerbal Engineer
  • Strategia
  • Unmanned before Manned


Итак, приступим.


Первая задача космической программы - запустить хоть что-нибудь хоть куда-нибудь.
В простейшем случае, у нас есть ракета, которую нужно запустить вертикально вверх. В принципе, для этого не нужен ни автопилот, ни ручное управление - достаточно поставить спиральное хвостовое оперение, и ракета при взлёте стабилизируется вращением - и тут хватило бы дельты до космоса.
Но нам всё равно придётся управлять - так что уж поуправляем.
В kOS есть два метода управления - RAW CONTROL и COOKED CONTROL. Чтобы понять первый режим, представьте езду на автомобиле в роли штурмана, если у водителя завязаны глаза.
RAW CONTROL ("сырой" контроль) - это, по сути, ввод действий, которые производит игрок вроде: "Подождать 5 сек.; нажать Z (полная тяга); нажать пробел; включить SAS; подождать 20 сек.; зажать D; подождать 1 сек.; отпустить D; ...". Работа в этом режиме нужна обычно для контроля стыковки, также можно с помощью такого контроля написать собственный алгоритм САС (здесь - Система Автоматической Стабилизации, а не аварийного спасения). Для операций взлёта, посадки и орбитального маневрирования он не очень практичен, поскольку для каждого крафта придётся писать очень сложную последовательность команд.
COOKED CONTROL ("обработанный" контроль) - это использование аналога продвинутой SAS, которой можно задать любое направление для удержания, а также можно задать необходимый уровень тяги. Аналогично стоковой САС, для поворота в заданном направлении и удержании его используется ПИД контроллер. Для пилотирования этот режим гораздо практичнее.
Пробуем управлять ракетой.
Для этого нам нужно сделать ракету, в которой есть беспилотный модуль, модуль kOS, антенна, поскольку без работающего соединения мы не можем передавать команды, и батарейка для работы всего этого богатства.

Тестовая ракета. Модуль kOS подсвечен фиолетовым.

Тестовая ракета. Модуль kOS подсвечен фиолетовым.

Открываем консоль kOS для интерактивного управления.
Контроль ориентации в "обработанном" режиме производится командой
lock steering to expression.

Чтобы лететь вертикально вверх, пишем
lock steering to up.

Не забываем точку в конце команды - это особенность КербоСкрипта.
Эта команда "привязывает" рулёжку к направлению "вверх".
steering - это специальная структура в kOS, которая отвечает за то, в каком направлении должен быть ориентирован аппарат.
lock - выражение, которое привязывает переменную к выражению - т.е. каждый раз, когда системе требуется значение переменной, выражение expression перевычисляется и подставляется новое значение. Другое выражение для установки значения переменной -
set var to expr. // var устанавливается в значение expr в момент вызова команды, каждый раз не перевычисляется


up - одно из предзаданных направлений, которое означает ориентацию "носом вверх" (подробнее см. ниже).
Для запуска ступени пишем
stage.

Ракета взлетает, зачем-то разворачивается на 180 градусов и летит, как положено, вверх. На 4 км, к сожалению, всё равно теряет управление, т.к. слабенькая САС в зонде не справляется. Ну и ладно, задание "запустить первый аппарат" всё равно уже выполнено.

Теперь вопрос - а где же тут автоматизация? Мы же вручную вбили все команды.
Сейчас будет.
Заходим в папку, где установлена игра. Там появилась подпапка Ships/Script. В ней мы и будем хранить наши скрипты. Создаем файл test.ks такого содержания:
lock steering to up.
stage.
wait until false.

Этот скрипт делает всё то, что мы делали до этого. Последняя строчка добавляет команду wait - она работает в двух режимах:
wait 10 // ждать 10 секунд
wait until condition // ждать до тех пор, пока не выполнится condition

Без последней команды скрипт считается выполненным после запуска ступени, и контроль управления передаётся игроку. wait until false в данном случае не даёт программе завершиться, а автопилоту отпустить руль.
Запускаем аппарат. В консоли пишем:
switch to 0.
runpath("test.ks").

Первая строчка переключает диск на номер 0. Дисковое пространство организовано так, что для каждого kOS модуля диск 0 - это "мейнфрейм ЦУП" - то, что лежит в папке Ships/Script, диск 1 - это его собственное хранилище (размер его в байтах можно посмотреть в ЦВС или в полёте по правой кнопке, изменить в ЦВС), диски 2, 3 и т.д. - другие kOS модули на том же корабле. То есть у каждого модуля, если их в корабле несколько, нумерация дисков индивидуальная.
По умолчанию бортовой компьютер работает с диска 1. Командой switch мы его переключаем на работу с другого диска. Вместо переключения на другой диск можно указывать полный путь к файлу, который надо запустить:
runpath("0:/test.ks"). // работает независимо от того, где сейчас рабочая директория

Естественно, доступ к диску 0 имеется только при наличии работающего соединения. В отсутствие рабочего соединения kOS может запускать только те файлы, которые хранятся на корабле. Поэтому, в идеале, перед полётом нужно скопировать на бортовую ЭВМ всё, что может понадобиться.

Этап второй. Moar Boosterz, или двухступенчатая ракета с вертикальным полётом.


Добавляем вниз разделитель и ещё один бустер. В этот раз присопливим стабилизаторы, чтобы ничего не переворачивалось.

Тестовая ракета 2. Умеет в космос.

Тестовая ракета 2. Умеет в космос.

К этой ракете уже нужна программа посложнее, поскольку в нужный момент нужно сбросить первую ступень и запустить вторую. Разберём, как это сделать.
Условные переходы и цикл с условием
Перво-наперво, нужно понять, в каком случае требуется сброс ступени. Тут есть три варианта:
а) Рассчитать время работы первой ступени. После запуска уже известной командой wait подождать это время, после чего написать команду на запуск второй ступени.
б) Отслеживать количества топлива в первой ступени и сбросить, когда его там не останется.
в) Отслеживать тягу ракеты и запускать вторую ступень, когда пропадёт тяга.
Из этих вариантов выберем третий, потому что ещё Штирлиц знал, что лучше всего запоминается последняя фраза. (На самом деле, при определении остатков топлива kOS может выдавать ненулевую цифру даже когда ступень закончила работать, а пропадание тяги фиксируется безотказно). Полностью программа полёта получается такая: после взлёта дождаться пропадания тяги, после чего запустить новую ступень.
Получить данные о тяге можно, вызвав
ship:availablethrust // возвращает суммарную тягу всех активных двигателей


ship - это переменная (типа VESSEL), в которой хранятся данные об аппарате, на котором находится активный kOS модуль. Если рядом находятся два разных корабля, имеющих kOS на борту, то для каждого из них ship будет означать текущий корабль.
ship:availablethrust даёт тягу на "полном газу" (с учётом ограничителей, выставленных в ЦВС).
Теперь запишем программу полёта двухступенчатой ракеты в виде кода:
stage.
wait until ship:availablethrust = 0.
stage.
}

И... к сожалению, этот код может не сработать. Например, в ракете на картинке по одной команде stage лишь сбросится первая ступень, а вторая не запустится. Чтобы этого избежать, следует проверить, появилась ли реально тяга после "пробела". Добавим условный переход:
stage.
wait until ship:availablethrust = 0.
stage.
if ship:availablethrust = 0 {
  wait 0.5.
  stage.
}
else {
  print "Second stage started".
}

Здесь использован условный оператор if ... else, работающий практически так же, как и в большинстве других языков. Чтобы по условию выполнялась последовательность команд, её необходимо заключить в фигурные скобки. Если выполнить нужно только одну команду (как после else в примере), скобки не обязательны, но здесь оставлены для единообразия. Ожидание полсекунды в if вставлено для того, чтобы команда на разделение точно прошла - при попытке сделать две команды stage подряд можно попасть внутрь одного "тика" (цикла расчета физики в игре), и две команды обработаются как одна, чего нам не надо.
Этот код, однако, тоже может не работать, если между сбросом одной ступени и стартом другой есть ещё что-то (например, сброс обтекателя). Естественным выглядит проверка тяги в цикле. В KerboScript имеется только цикл с предусловием until. К работе его нужно привыкнуть, т.к., в отличие от while в других языках, тело цикла в KerboScript выполняется в том случае, если условие цикла не выполнено (в переводе: "пока не будет выполнено условие, повторять действие"). Поэтому программа запуска ступеней нашей двухступенчатой ракеты с циклом будет выглядеть так:
stage.
wait until ship:availablethrust = 0.
until ship:availablethrust > 0 {
  wait 0.5.
  stage.
}

Эту программу сохраняем в файл test.ks. Управления ориентацией для разнообразия тут нет - ракета стабилизирована вращением за счёт спиралевидного оперения.
До космоса эта конструкция добирается, но чтобы добиться стабильной орбиты, нужно тягу давать и в горизонтальном направлении. Как это сделать?
Чтобы в этом разобраться, не нужно понять, что в kOS представляет собой ориентация и каким образом её можно задать. Заодно это прояснит, почему первая ракета после взлёта разворачивалась на 180 градусов вокруг оси.

Нетрадиционная ориентация


Переходим в ангар.
У каждой детали, с которой можно управлять (достуен переключатель Control from here по ПКМ), есть встроенные оси тангажа (X), рыскания (Y) и крена (Z).
Они представляют собой векторы, причём для части в ангаре по умолчанию ось крена направлена "вперёд", к выходу, ось рыскания - вверх, ось тангажа - вправо.
Получить значения этих векторов в текущий момент времени можно через
ship:facing:forevector  // ось Z
ship:facing:upvector    // ось Y
ship:facing:rightvector // ось X

Заметим, что эти оси образуют левую тройку, а не правую - если наблюдателя поставить на "кончик" вектора Z, то кратчайший поворот, переводящий ось X в ось Y, будет по часовой стрелке, а не против. Это, например, означает, что пикирование будет задаваться через положительный тангаж, а кабрирование - через отрицательный, отака фигня, малята.

Теперь мы поняли, что у капсулы Mk1 "перед" с острого конца, "верх" там, где иллюминатор, а "право" - там, где у сидящего в ней Джебедайи находится правая рука. Заодно заметим, что в ЦВС у неповёрнутой детали ось Z направлена вверх, ось X к выходу (на восток), ось Y на юг.
Для тех, кто не знает - вот в таком положении сидит в капсуле Джебедайя.

Для тех, кто не знает - вот в таком положении сидит в капсуле Джебедайя.

Вывод: чтобы задать ориентацию аппарата, нужно задать три взаимно ортогональных оси, с которыми надо совместить оси аппарата. Именно это и содержит структура DIRECTION - направления трёх осей. Важные ориентации:
ship:facing        // как в данный момент ориентирован аппарат
up                 // наверх
north              // на север
ship:prograde      // передом в направлении орбитальной скорости
ship:retrograde    // передом в направлении против орбитальной скорости
ship:srfprograde   // по скорости относительно поверхности
ship:srfretrograde // против скорости относительно поверхности 

Внезапно возникающие вопросы: а где право у северного направления? А у верха? И как это вообще понимать?
Давайте запустим аппарат из капсулы Mk1 (лучше с учёным на борту, поможет нам разобраться), какого-нибудь беспилотного модуля, антенны и kOS модуля.
Открываем консоль, пишем:
print north
.
Видим какое-то R(270.097,315.717,0). А это, братцы, углы Эйлера. Это значит, что для получения ориентации на север нужно базовую тройку векторов сначала повернуть на 0 градусов вокруг оси Z, потом на 270.097 градусов вокруг старой оси X и, наконец, на 315.717 градусов вокруг старой оси Y. О как! А где эта базовая тройка векторов? И куда смотрят всё-таки оси "севера"?
Поймём сначала, как получить оси.
По аналогии с ориентацией аппарата, у любого объекта типа DIRECTION можно получить поля
direction:forevector  // ось Z
direction:upvector    // ось Y
direction:rightvector // ось X

Можно убедиться, что у "севера" ось Z направлена по касательной к сфере в северном направлении, X - на восток, Y - вертикально вверх.
У направления "вверх" - ось Z смотрит вертикально вверх, ось Y - на север (по касательной к сфере), ось X, таким образом, на запад.
Вот как-то так мы ориентированы относительно верха, если немного скатиться по наклонной.

Вот как-то так мы ориентированы относительно верха, если немного скатиться по наклонной.

Контроль ориентации.
Хорошо, про определение ориентации понятно. А как её контролировать? Вариантов много.
Первый - задать в виде вращения R(a,b,c). Проблема в том, что неизвестно, куда направлены оси базовой системы координат, поэтому напрямую этот метод использовать не очень-то получится.
lock steering to R(3,4,5). // кто знает, куда это направлено?

Второй - можно суммировать две ориентации - т.е. написать, например, R(10,20,30) + R(35,25,15) - получится R(45,45,45). Тоже метод так себе, потому что не очень понятно, к какому итоговому вращению такое суммирование приведёт. Исключение - добавка к любому вращению R(0,0,a) приводит к дополнительному вращению на a градусов по крену.
lock steering to up + R(0,0,180). // обычно это начальная ориентация ракеты на стартовом столе

Третий способ - перемножение поворотов - что будет, если последовательно применить повороты в порядке справа налево.
lock steering to R(0,0,180) * up. // повернуть все оси ориентации UP на 180 градусов вокруг абсолютной оси Z

Четвёртый способ - функция heading(dir,pitch), которая задаёт направление с азимутом dir градусов и углом к горизонту pitch градусов. Ось Direction:upvector в этом случае выбирается так, чтобы Direction:forevector, Direction:upvector и Up:forevector лежали в одной плоскости. heading(dir,pitch) + R(0,0,roll) даст вам нужные азимут, тангаж и крен для ориентации аппарата.
lock steering to heading(90,45). // азимут на восток, нос на 45 градусов вверх

Пятый способ - функция lookdirup(forevec,upvec) - с ней Direction:forevector задаётся вдоль forevec, Direction:upvector - проекция upvec на плоскость, ортогональную Direction:forevector.
lock steering to lookdirup(prograde:vector,-up:vector). // носом в прогрейд, окошком на Кербин

Шестой способ - функция angleaxis(degrees,axisvector) - задает вращение на угол degrees вокруг оси axisvector.
set pitchUp30 to angleaxis(-30,ship:facing:rightvector). // вращение вокруг оси тангажа на 30 градусов против часовой стрелки
set newDir to pitchUp30*ship:facing. // новое направление есть поворот старого по тангажу
lock steering to newDir. // поворачиваем корабль в новом направлении

Седьмой способ - функция rotatefromto(vec1,vec2) - создаёт один из поворотов, переводящих vec1 в vec2.
lock steering to rotatefromto(prograde:vector,up:vector)*prograde. // нос будет смотреть вверх, куда повернётся иллюминатор - неясно


Вроде бы ясно, как задать ориентацию, остался вопрос - что собой представляет исходная координатная система, которая поворачивается для задания ориентации?

Координаты и векторы
Вектор в kOS можно задать в виде V(a,b,c).
Компоненты вектора доступны по суффиксам V:x, V:y, V:z.
Исходная координатная система задана векторами Ex = (1,0,0), Ey = (0,1,0), Ez = (0,0,1). То есть по определению
R(0,0,0):rightvector = V(1,0,0).
R(0,0,0):upvector = V(0,1,0).
R(0,0,0):forevector = V(0,0,1).

Нелишне запомнить, что ось Y всегда направлена вдоль оси текущего небесного тела на север, а оси X и Z лежат в экваториальной плоскости. С помощью этого, например, легко посчитать наклонение орбиты.
Векторами являются очень многие параметры - кроме осей ориентации, это положения объектов, скорости, угловые скорости.
Начало координат расположено по умолчанию на текущем модуле kOS - почувствуйте себя центром Вселенной. Поэтому, например, вектор, соединяющий наш корабль с целью, будет просто target:position. А, например, вектор, проведённый из центра планеты к цели, будет target:position - body:position.
С векторами можно делать много классных и полезных операций. Разберём некоторые из них.
  1. Сложение и вычитание
    Векторы складываются по известным из школьной геометрии правилам теугольника или параллелограмма. В координатном виде в прямоугольной декартовой системе координат
    V(a1,a2,a3) + V(b1,b2,b3) = V(a1+b1,a2+b2,a3+b3)

    Сложение векторов

    Сложение векторов: c = a + b
    Вычитание векторов

    Вычитание векторов
  2. Длина вектора
    Доступна по суффиксу :mag. По определению
    V(a,b,c):mag = sqrt(a^2 + b^2 + c^2)

    Из соображений производительности, если вам нужен квадрат длины, лучше пользоваться суффиксом :sqrtmagnitude
    V(a,b,c):sqrmagnitude = a^2 + b^2 + c^2

  3. Скалярное произведение
    Число, равное произведению длин векторов на косинус угла между ними. Обозначается a·b или (a;b). В кербоскрипте вычисляется функцией vdot(v1,v2). В координатном виде
    vdot(V(a1,a2,a3),V(b1,b2,b3)) = a1*b1 + a2*b2 + a3*b3

    Из скалярного произведения можно вычислить косинус угла между векторами и восстановить сам угол. Это сделано уже за нас:
    vang(v1,v2) // возвращает угол между векторами v1 и v2 в градусах

    Если (a;b) = 0 - значит, векторы ортогональны
  4. Векторное произведение
    Это вектор, длина которого равна произведению длин двух векторов на синус угла между ними, направленный перпендикулярно им обоим. Обозначается a×b или [a;b]. Направление определяется так: если сверху смотреть на два перемножаемых вектора, то a×b смотрит на нас, если кратчайший поворот от a к b идёт в положительном направлении, и от нас - если в отрицательном. Из-за левой системы координат в KSP положительное направление вращения - по часовой стрелке! Очевидное свойство: a×b = - b×a. Если векторное произведение равно нулю, векторы коллинеарны.
    Вычисляется оно функцией vcrs. В координатном виде
    vcrs(V(a1,a2,a3),V(b1,b2,b3)) = V(a2*b3-a3*b2, a3*b1-a1*b3, a1*b2-a2*b1)

  5. Нормализация
    Особое место занимают такие векторы, у которых длина равна единице. Любой ненулевой вектор, конечно, можно отнормировать, если поделить все его компоненты на длину. Это доступно через суффикс :normalized
    vec:normalized:x = vec:x / vec:mag // с другими компонентами аналогично

  6. Проецирование
    Если нам известен какой-нибудь вектор e, то любой другой вектор раскладывается на сумму вектора, коллинеарного e и ортогонального e. Ортогональная проекция вектора v на вектор e (тангенциальная компонента) - это вектор vT = e*(e;v)/|e|2. Ортогональная составляющая vn = v - vT - это остальная часть вектора v.
    Проекция вектора на ось

    Проекция вектора на ось
    Ортогональная составляющая вычисляется как
    vxcl(E, V) // Vector exclude E vector from V vector

    Тангенциальная проще всего так:
    set Enorn to E:normalized.
    set Vt to Enorm * vdot(Enorm, V). 



Дайте порулить


Теперь попробуем применить что-нибудь на практике.
Делаем ракету из Mk1 кабины с беспилотным командным модулем, kOS модулем и парашютом. Через разделитель прикрепляем к ней "Блоху" с крылышками. И не забудем об антенне.

Создаём файл Ships/Script/steeringtest.ks:
lock steering to heading(90, 90) + R(0,0,-90). // начальная ориентация на стартовом столе
wait 5. //Дадим себе полюбоваться видом
stage. // Поехали!
wait until alt:radar > 150. // alt:radar возвращает высоту kOS модуля над поверхностью - ждём подъёма на 150 метров
until ship:availablethrust = 0 { //держим направление до тех пор, пока есть топливо в бустере
  lock steering to heading(90, 80). // Летим на восток окном вверх (точнее, почти на запад)
  print "AoA: " + round(vang(ship:facing:forevector,velocity:surface),1) + " degrees    ". //Печатаем угол атаки с точностью до 1 цифры после запятой
  wait 1.
}
stage. // сбросили бустер
wait until vdot(velocity:surface,up:forevector) < 0. // дожидаемся, пока полетели вниз
lock steering to lookdirup(-velocity:surface,up:starvector). // развернулись кормой вперёд, окном на запад
wait 0.5. 
stage.    // раскрыли парашют
wait until ship:status = "SPLASHED" or ship:status = "LANDED".
print "WE HAVE " + ship:status +". Have a good day. ".

ракета должна автоматически взлететь, развернуться в сторону океана и приводнить капсулу.
На этом простое введение закончено. В следующей части - как выйти на орбиту.
KerboScript в примерах и задачах. Часть 2.5. Триггеры. Завершение спутниковой сети
28 мар 2017 в 03:52, Гайды
KerboScript в примерах и задачах. Часть 1. Выход на орбиту
25 мар 2017 в 17:42, Гайды
  1. Marschig

    Marschig 25 марта 2017 14:00

    Оно, конечно, интересно, но напоминает анекдот про бандита и GTA:
    "Вот так весь день работаешь, сядешь вечером поиграть и отвлечься, а тут то же самое" :)

    1. Pand5461

      Pand5461 25 марта 2017 15:26 Автор

      Мне вот рассказывали про дегустаторов на табачной фабрике - так они говорят "одно дело по работе, а другое - для души".

  2. Wonderboy

    Wonderboy 26 марта 2017 00:58

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

    1. Pand5461

      Pand5461 26 марта 2017 01:28 Автор

      Недовольство тем, что "женщину вынули, автомат засунули" понимаю, но не разделяю.
      Если поставить RemoteTech, то из-за задержки сигнала на межпланетных аппаратах другого выбора и не остаётся, кроме как автопилот писать.
      Кроме того, по мере написания улучшается понимание и механики за всем этим тоже.

  3. Slv

    Slv @Абракадабр 27 марта 2017 17:09

    Шутка конечно интересная, вот только вместо "хелло ворд" у меня вышло "fuck you Gleb" и следом вызов int19h (на асме)... так что мне думается не стоит браться за КОС. %-))

    1. Pand5461

      Pand5461 27 марта 2017 22:38 Автор

      @Slv, это аура то ли профи пилота, то ли профи тестера. С такой только смотреть издали на пуски друзей и вблизи на краши врагов.

  4. Yaroslav Khaidayev

    Yaroslav Khaidayev @Slavjan 1 апреля 2017 17:00

    было бы на мнооого полезнее если бы уважаемый Pand5461 просто по порядку выложил: Операторы ветвления, Операторы цикла и т.д. То есть более формально, а то и у автора kOS неразбериха в документации и тут ещё больший каламбур. НЕ я понимаю, кому-то так может быть и понятнее, но стоит добавить немного формальности в текст.

    1. Pand5461

      Pand5461 1 апреля 2017 21:33 Автор

      Возможно, соберусь потом подрихтовать ещё, раз есть такие пожелания.
      UPD: добавил описание условия и того, как работает цикл until, в более структурированном виде. Про for и from тут не пишу, поскольку они нужны реже и для других целей.

  5. Iavasdemsul

    Iavasdemsul @Илья 7 мая 2017 23:21

    годно...держи плюс

  6. cda2023

    cda2023 16 июля 2017 23:31

    последний скрипт криво работает (не раскрывает парашют и не пишет сообщение).
    в связи с этим хотелось бы узнать нет ли возможности запускать эти скрипты по шагам как в нормальных языках программирования?

    1. Pand5461

      Pand5461 17 июля 2017 13:53 Автор

      К сожалению, пошагово выполнять нельзя, т.к. для этого потребуется полная симуляция игры по фреймам. Можно видео того, как не работает с открытым терминалом (в ЛС)?

{login}
  • bowtiesmilelaughingblushsmileyrelaxedsmirk
    heart_eyeskissing_heartkissing_closed_eyesflushedrelievedsatisfiedgrin
    winkstuck_out_tongue_winking_eyestuck_out_tongue_closed_eyesgrinningkissingstuck_out_tonguesleeping
    worriedfrowninganguishedopen_mouthgrimacingconfusedhushed
    expressionlessunamusedsweat_smilesweatdisappointed_relievedwearypensive
    disappointedconfoundedfearfulcold_sweatperseverecrysob
    joyastonishedscreamtired_faceangryragetriumph
    sleepyyummasksunglassesdizzy_faceimpsmiling_imp
    neutral_faceno_mouthinnocent
Последние сообщения с форума
  • Автор
    Тема в разделе: Вопросы по игре
    Просмотров: 1566139
    Ответов: 12701
  • Автор
    Тема в разделе: В ангаре у Боба
    Просмотров: 9488
    Ответов: 55
  • Автор
    Тема в разделе: Технические вопросы
    Просмотров: 25849
    Ответов: 68
  • Автор
    Тема в разделе: Моды
    Просмотров: 2078
    Ответов: 2
  • Автор
    Тема в разделе: В ангаре у Боба
    Просмотров: 219337
    Ответов: 1484
    Все сообщения..
    Полный список последних сообщений
    Loading...

    Нашли ошибку?
    Вы можете сообщить об этом администрации.
    Выделив текст нажмите Ctrl+Alt