Skyrim CK:Вопросы и ответы по скриптам

Материал из Tiarum
Перейти к: навигация, поиск

Содержание

Краткий обзор

На этой странице описываются распространенные ошибки при работе с Papyrus и способы их диагностирования и устранения.

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

Узнали сами - подскажите другим! Если вы нашли способ обойти некоторые сложности, пожалуйста, добавьте их к этому FAQ. Настоятельно рекомендуется давать ссылки и фрагменты кода, чтобы продемонстрировать ваши решения.

FAQ

Общие вопросы

Мой скрипт компилируется, но не работает! Как мне его отладить?

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

Включение логирования производится в ini файле. Откройте (или создайте) свой SkyrimCustom.ini файл в папке .../My Documents/My Games/Skyrim. Добавьте в него следующие строки. Если какие-то из них уже существуют, убедитесь, что значения у этих параметров установлены в "1", в противном случае смените "0" на "1".

[Papyrus]
bEnableLogging=1
bEnableTrace=1
bLoadDebugInformation = 1
  • bEnableLogging включает/выключает систему логирования скриптов;
  • bEnableTrace включает Debug.Trace и связанные с ним функции,
  • bLoadDebugInformation будет загружать информацию о номерах строк, в которых произошла ошибка, таким образом, вы можете легко определить место ее возникновения.

Если все эти параметры включены, игрою создается новая папка по адресу “...\My Documents\My Games\Skyrim\Logs\Script”. (Если вы не видите этой папки, возможно, придется запустить игру еще раз). Ваши логи появятся в этой папке и будут иметь название Papyrus.#.log, где "#" - цифра от 0 до 3. В логе под номером 0 всегда будет храниться самая свежая отладочная информация, в остальных - предыдущая.

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

Если игра обнаруживает ошибку в скрипте, она выведет его в следующем формате:

<timestamp> <error message>
stack:
  <function 0> - "<filename>" Line <line number>
  <function 1> - "<filename>" Line <line number>
  <function 2> - "<filename>" Line <line number>
  ...

Function 0 - это функция, которая вызвала сообщение об ошибке. Function 1 это функция, вызываемая Function 0. Function 2 вызывает Function 1 и т.д. Это поможет вам отследить, что может быть причиной каких-либо ошибок, о которых вам сообщается.

Пример лог-файла:

[02/18/2012 - 10:41:37PM] Papyrus log opened (PC)
[02/18/2012 - 10:41:37PM] Update budget: 1.200000ms (Extra tasklet budget: 1.200000ms, Load screen budget: 500.000000ms)
[02/18/2012 - 10:41:37PM] Memory page: 128 (min) 512 (max) 76800 (max total)
[02/18/2012 - 10:42:20PM] VM is freezing...
[02/18/2012 - 10:42:20PM] VM is frozen
[02/18/2012 - 10:42:21PM] Reverting game...
[02/18/2012 - 10:42:34PM] Loading game...
[02/18/2012 - 10:42:35PM] VM is thawing...
[02/18/2012 - 10:42:35PM] DARYL - [WeaponRackActivateSCRIPT < (001019C3)>] running OnCellLoad() and AlreadyInit = False
[02/18/2012 - 10:42:35PM] DARYL - [WeaponRackActivateSCRIPT < (001019C3)>] The TriggerMarker is [WeaponRackTriggerSCRIPT < (001019C4)>]
[02/18/2012 - 10:42:36PM] warning: Assigning None to a non-object variable named "::temp6"
stack:
	[ (0009F82B)].dunBluePalaceArenaSCRIPT.OnUpdate() - "dunBluePalaceArenaSCRIPT.psc" Line 77
[02/18/2012 - 10:42:36PM] DARYL - [WeaponRackActivateSCRIPT < (001019C3)>] The Starting Weapon is [defaultDisableHavokOnLoad < (0008ADFD)>]
[02/18/2012 - 10:42:36PM] DARYL - [WeaponRackActivateSCRIPT < (001019C3)>] Has a starting weapon
[02/18/2012 - 10:42:36PM] DARYL - [WeaponRackActivateSCRIPT < (001019C3)>] Handling Starting Weapon
[02/18/2012 - 10:42:36PM] DARYL - [WeaponRackActivateSCRIPT < (001019C3)>] Disabling physics on [defaultDisableHavokOnLoad < (0008ADFD)>]
[02/18/2012 - 10:42:36PM] DARYL - [WeaponRackActivateSCRIPT < (001019C3)>] Moving 0 to the WaraxeMarker
[02/18/2012 - 10:42:36PM] DARYL - [WeaponRackActivateSCRIPT < (001019C3)>] finishing OnCellLoad() and AlreadyInit = TRUE
[02/18/2012 - 10:42:38PM] warning:  (000C275C): Ref is in an unloaded cell, so it cannot cast spells..
stack:
	[ (001034BF)].SPELL.Cast() - "<native>" Line ?
	[ (00103491)].dunPotemasMS06BossFightDummy.AttackFunc() - "dunPotemasMS06BossFightDummy.psc" Line 168
	[ (00103491)].dunPotemasMS06BossFightDummy.OnLoad() - "dunPotemasMS06BossFightDummy.psc" Line 66
[02/18/2012 - 10:42:50PM] error: Object reference has no 3D
stack:
	[ (0001E68C)].Sound.Play() - "<native>" Line ?
	[ (0009C024)].fxDustDropRandomSCRIPT.OnLoad() - "fxDustDropRandomSCRIPT.psc" Line 36
[02/18/2012 - 10:42:54PM] warning: Assigning None to a non-object variable named "::temp6"
stack:
	[ (0009F82B)].dunBluePalaceArenaSCRIPT.OnUpdate() - "dunBluePalaceArenaSCRIPT.psc" Line 77
[02/18/2012 - 10:42:55PM] warning:  (000C275C): Ref is in an unloaded cell, so it cannot cast spells..
....
stack:
	[ (001034BF)].SPELL.Cast() - "<native>" Line ?
	[ (00103491)].dunPotemasMS06BossFightDummy.AttackFunc() - "dunPotemasMS06BossFightDummy.psc" Line 168
	[ (00103491)].dunPotemasMS06BossFightDummy.OnLoad() - "dunPotemasMS06BossFightDummy.psc" Line 66
[02/18/2012 - 11:15:08PM] warning: Assigning None to a non-object variable named "::temp6"
stack:
	[ (0009F82B)].dunBluePalaceArenaSCRIPT.OnUpdate() - "dunBluePalaceArenaSCRIPT.psc" Line 77
[02/18/2012 - 11:15:11PM] error: Object reference has no 3D
stack:
	[ (0001E68C)].Sound.Play() - "<native>" Line ?
	[ (0009C024)].fxDustDropRandomSCRIPT.OnLoad() - "fxDustDropRandomSCRIPT.psc" Line 36
[02/18/2012 - 11:15:12PM] warning:  (000C275C): Ref is in an unloaded cell, so it cannot cast spells..
stack:
	[ (001034BF)].SPELL.Cast() - "<native>" Line ?
	[ (00103491)].dunPotemasMS06BossFightDummy.AttackFunc() - "dunPotemasMS06BossFightDummy.psc" Line 168
	[ (00103491)].dunPotemasMS06BossFightDummy.OnLoad() - "dunPotemasMS06BossFightDummy.psc" Line 66
[02/18/2012 - 11:15:19PM] warning: Assigning None to a non-object variable named "::temp6"
stack:
	[ (0009F82B)].dunBluePalaceArenaSCRIPT.OnUpdate() - "dunBluePalaceArenaSCRIPT.psc" Line 77
[02/18/2012 - 11:15:21PM] warning:  (000C275C): Ref is in an unloaded cell, so it cannot cast spells..
stack:
	[ (001034BF)].SPELL.Cast() - "<native>" Line ?
	[ (00103491)].dunPotemasMS06BossFightDummy.AttackFunc() - "dunPotemasMS06BossFightDummy.psc" Line 168
	[ (00103491)].dunPotemasMS06BossFightDummy.OnLoad() - "dunPotemasMS06BossFightDummy.psc" Line 66
[02/18/2012 - 11:15:30PM] VM is freezing...
[02/18/2012 - 11:15:30PM] VM is frozen
[02/18/2012 - 11:15:31PM] Log closed

Но, возможно, вы не увидите никаких ошибок. Что же тогда делать? Вы можете использовать различные отладочные функции, например Trace и TraceStack, чтобы увидеть как работает ваш скрипт, какие переменные и свойства он имеет. Например, посмотрите на такую функцию:

Function MyFunction(int coolValue)
  Debug.Trace("My function called! Coolvalue = " + coolValue)
  If (coolValue == 20)
        Debug.Trace("Cool value is 20! Doing some neat stuff now!")
        ; Do neat stuff!
  EndIf
EndFunction

После добавления операторов трассировки в вашу функцию, вы сможете посмотреть записи в логе, чтобы попытаться точно определить, что пошло не так. В не видите “My function called!” в вашем логе? Это значит, что ваша функция совсем не работает и надо продолжать поиски причины. Вы видите первое сообщение, но не видите второго (“Cool value is 20!”)? Тогда вам придется выяснить, почему выводимое функцией значение отлично от ожидаемого. И вы заметите, что в примере, мы действительно отслеживаем значение переменной простым “объединением” при помощи оператора “+”.

Движок Skyrim также включает в себя консольные команды, которые могут помочь вам отследить, в чем может быть проблема. Если ваш скрипт прикреплен к квесту, введите в консоли “sqv <quest>”. В результате вы получите список переменных и свойств, принадлежащих этому квесту. Если скрипт прикреплен к ссылочному объекту, выберите его в консоли при помощи мыши (или используя команду “prid <reference id>”) и введите “sv” для просмотра переменных и свойств, прикрепленных к данному объекту. (Для прокрутки списков используйте клавиши PgUp и PgDown!) Если ваш скрипт предполагает регистрацию обновления событий, введите “dpu”, чтобы игра сбрасывала дамп в лог-файл каждый раз, когда происходит обновление события. Или, если вы предполагаете, что ваш скрипт зациклился, введите “dps” для создания полного дампа для последующего анализа работы Papyrus.

Не могу удалить предмет у персонажа игрока

  • Фокус с заданием отрицательных значений для функции AddItem проходит только в консоли, а в скриптах не работает. Используйте вместо этой функции - правильную - RemoveItem.

Мой скрипт не компилируется и я не могу использовать Editor ID!

Свойства. Вы нуждаетесь в них. Читайте о них.

Мой плагин работает у меня и не работает у других!

Это звучит как комплексная проблема. Рассмотрим ее по частям:

  • Не забыли ли вы приложить к плагину необходимые файлы мешей (meshes) и/или текстур (textures)? Маловероятно, что текстуры могут стать причиной краха игры, но их отсутствие точно испортит внешний вид (например, объекты будут розовыми или фиолетовыми). Потерянные меши (meshes) могут стать причиной графических аномалий и даже краха игры. Убедитесь, что ваши графические элементы имеют относительные, а не абсолютные пути, иначе они не будут нормально подгружаться из папок, пути к которым отличны от заданных вами.
  • Вы используете пользовательские скрипты, которые расширяют другие пользовательские скрипты? Здесь имеется ошибка [1] в упаковщике .bsa packager where if the parent custom script is not actually present in a base form in the game, then it will not be listed in the file selector for the packager. The solution is to create a dummy mesh that has the parent script attached, or manually include it in the .bsa on build.
Переводить Этот материал нуждается в переводе или допереводе..
Вы можете помочь перевести его. Не забывайте предварительно добавлять строку {{Edit|--~~~~}} в материалы над которыми работаете, чтобы не создавать конфликта правок.
Пожалуйста, снимите шаблон этого сообщения, когда материал будет вычитан.

Создание объектов

Я не могу создать новый объект

  • Problem: I can't create a new object.
  • Explanation: Papyrus currently does not support the instantiation of objects within script; the new keyword only works for arrays, not objects (unlike Java, for example), and constructors do not seem to work.
  • Solution: For a workaround, you could try casting a PlaceAtMe ObjectReference as your desired object. Of course your object must extend ObjectReference for this to work.

Can't cast an object as its child

  • Problem: I can't cast an object as its child. For instance, casting an ObjectReference as a TestReference when TestReference extends ObjectReference.
  • Explanation: Casting will only work if the reference casted actually has its script attached. For instance, the TestReference base object needs to have the TestReference script attached in the editor form window for it to be castable from ObjectReference to TestReference.
  • Solution: Use the editor and attach the script to the object you're actually casting. For instance, if TestReference is supposed to refer to a book, open up the book you want to cast in the editor window, goto the scripts section, and attach the TestReference script from there.

Quests

I can't get my alias to point to a reference

  • Several possibilities here:
    • The reference doesn't actually exist. Did you make sure that a PlaceAtMe command actually generated a reference? Check using Debug.Trace(theReference).
    • An alias is pointing to an object in a container. Evidently this does not work (creating a persistent reference using PlaceAtMe, and pointing the alias to the persistent reference). Solution: don't put the object in the container, or point to the container and get the object that way (not completely tested).
    • You created an alias for a quest that is already running (i.e. dirty save) - even if you are simply adding an additional alias to an already running quest, you can't get the alias to actually point to anything (despite the fact that Debug.Trace happily shows that it exists, which is horribly misleading). Solution is to make a clean save and remove the quest, then add it back. Simply removing the quest via console and adding it back may also work (unverified).

I can't add a property to a script fragment!

  • You need to define the property through the Properties window for a script fragment before it can work in the script. To do this:
    • Remove all references of the property from your script and compile. Use a blank script (;comment) if you need to.
    • You may need to rename the script to get the Properties window to work.
    • Click on the properties window on the lower right side (next to TIF_) to add the new property.
Личные инструменты
Пространства имён
Варианты
Действия
Навигация
Разделы TES
Разделы Fallout
Модмейкерам
Инструменты