QUOTE |
Ну где-то описывалось, читал даже, но освежить и донести до тех, кто не знает, не помешает. Пиши
|
Мой рассказ таков, что без бутылки и не понять
В общем, с каждой картой связано 5 типов скриптов (s_system, s_spatial, s_time, s_item, s_critter).
Для активной в данный момент карты каждый тип скриптов хранится в памяти в таком виде:
CODE |
Пример ┌──────────┐ ┌───────┐ │FirstBlock│ = │Block_1│ │LastBlock │ = │Block_3│ │BlockNums │ = │3 │ │Id │ = │неважн.│ └──────────┘ └───────┘
|
FirstBlock указатель на первый блок, а LastBlock на последний блок скриптов этого типа.
BlockNums количество блоков скриптов этого типа.
Если BlockNums = 0, то FirstBlock и LastBlock равны 0 и скриптов этого типа нет. Если BlockNums = 1, то LastBlock равен FirstBlock.
В свою очередь каждый блок скриптов (Block_1...Block_3) хранится в памяти в таком виде:
CODE |
Block_1 Block_2 Block_3 ╔═╤═════════╤═══════╗ ╔═╤═════════╤═══════╗ ╔═╤═════════╤═══════╗ ║+│скрипт_1 │ ║ ┌─>─╢+│скрипт_17│ ║ ┌─>─╢+│скрипт_33│ ║ ║+│скрипт_2 │ ║ │ ║+│скрипт_18│ ║ │ ║ │ │ ║ ║+│скрипт_3 │ ║ │ ║+│скрипт_19│ ║ │ ║ │ │ ║ ║+│скрипт_4 │ ║ │ ║+│скрипт_20│ ║ │ ║ │ │ ║ ║+│скрипт_5 │ ║ │ ║+│скрипт_21│ ║ │ ║ │ │ ║ ║+│скрипт_6 │ ║ │ ║+│скрипт_22│ ║ │ ║ │ │ ║ ║+│скрипт_7 │ ║ │ ║+│скрипт_23│ ║ │ ║ │ │ ║ ║+│скрипт_8 │ ║ │ ║+│скрипт_24│ ║ │ ║ │ │ ║ ║+│скрипт_9 │ ║ │ ║+│скрипт_25│ ║ │ ║ │ │ ║ ║+│скрипт_10│ ║ │ ║+│скрипт_26│ ║ │ ║ │ │ ║ ║+│скрипт_11│ ║ │ ║+│скрипт_27│ ║ │ ║ │ │ ║ ║+│скрипт_12│ ║ │ ║+│скрипт_28│ ║ │ ║ │ │ ║ ║-│скрипт_13│ ║ │ ║+│скрипт_29│ ║ │ ║ │ │ ║ ║-│скрипт_14│ ║ │ ║+│скрипт_30│ ║ │ ║ │ │ ║ ║-│скрипт_15│ ║ │ ║+│скрипт_31│ ║ │ ║ │ │ ║ ║-│скрипт_16│ ║ │ ║+│скрипт_32│ ║ │ ║ │ │ ║ ╟─┴─────────┼───────╢ │ ╟─┴─────────┼───────╢ │ ╟─┴─────────┼───────╢ ║Количество │16 ║ │ ║Количество │16 ║ │ ║Количество │1 ║ ╟───────────┼───────╢ │ ╟───────────┼───────╢ │ ╟───────────┼───────╢ ║Указатель │Block_2╟─>─┘ ║Указатель │Block_3╟─>─┘ ║Указатель │0x0 ║ ╚═══════════╧═══════╝ ╚═══════════╧═══════╝ ╚═══════════╧═══════╝
|
Когда в игре для карты добавляется новый скрипт, то добавляется он в конец последнего блока (увеличивая количество скриптов в этом блоке) или если количество скриптов равно 16 в этом блоке, то создаётся новый блок и скрипт добавляется в него.
При смене карты её состояние записывается в имя_карты.sav, который потом будет использоваться при записи игры (для текущей карты файл этой карты перезаписывается в момент записи игры). Важно то, что записываются все скрипты (каждого типа скриптов) связанные с картой, но сначала блоки чистятся от "неактивных" скриптов (я не стал разбирать структуру скриптов и точно не знаю почему некоторые скрипты не записываются, поэтому называю их "неактивными" они связаны с игроком) с помощью обмена содержимого "неактивного" скрипта с первым доступным "активным" скриптом из конца списка. Само собой подсчитывается количество записываемых "активных" скриптов, но не трогается содержимое остальных блоков скриптов количество скриптов в блоках и указатели на следующий блок (указатели после записи карты будут нужны для освобождения памяти).
После чистки наступает очередь записи сначала записывается подсчитанное количество "активных" скриптов, а потом содержимое блоков, включая значения количества скриптов в блоке и указатель на следующий блок (при загрузке карты значение указателя игнорируется).
Однако при этом движок вместо того чтобы использовать подсчитанное количество записываемых "активных" скриптов пользуется данными из блоков и это провал.
Лучше на примере есть 3 блока скриптов, в 1 и 2 по 16 скриптов, в 3 один скрипт. Всего 33 скрипта, которые после чистки 4 "неактивных" скриптов станут 29. Движок должен записать первый блок, изменить количество скриптов во втором блоке и затем записать его.
В действительности, поскольку не был изменён указатель на последний блок, движок записывает два блока, затем обнаруживает что в третьем блоке "неактивный" скрипт и нигде не изменяя количество скриптов завершает обработку скриптов этого типа.
Что приводит к некритической ошибке (с поправкой на то, что в действительности представляют из себя "неактивные" скрипты). Если проверить любой из своих сейвов, то с большой вероятностью найдётся несколько некритических результатов этого бага (но карта будет рабочая). Если воспользоваться утилитой TooManyItemsBug:
CODE |
Number of script's descriptors in 3'th sequence = 29 In 0'th block, 16 scripts were used. In 0'th block, 4 unknown bytes = 26002544. In 1'th block, 16 scripts were used. In 1'th block, 4 unknown bytes = 240554040. In last block 4 unknown bytes = 240554040.
|
Ошибка становится критической когда количество "неактивных" скриптов сдвигает список на один или более блоков и до чистки блоков было больше двух. Для нашего примера пусть будет 20 "неактивных" скриптов должен быть записан только первый блок с 13 скриптами, но движок запишет ещё второй блок (ведь указатель на последний блок не поменялся), который и будет являться причиной зависания при загрузке этой карты. Для TooManyItemsBug:
CODE |
Number of script's descriptors in 3'th sequence = 13 In 0'th block, 16 scripts were used. In 0'th block, 4 unknown bytes = 26002544. In last block 4 unknown bytes = 26002544. Unused block detected. In unused block, 16 scripts were used. In unused block, 4 unknown bytes = 1.
|
Update: "Неактивные" скрипты это скрипты связанные с игроком (ну там скриптовые вещи в инвентаре).
А вот описание бага на английском:
QUOTE |
The too many items bug I don't know exactly how it works technically, but what happens is that late in the game, if you have too many (different) items in one location, this will eventually corrupt maps. The number of items in question includes what you and your NPCs are carrying, the items on critters and in containers on the map (including shops), plus the stuff in your car no matter if it's present or not. The bug triggers upon leaving an area, and means that next time you try to enter that map, your computer will lock up completely. Many people have reported this behaviour; you'll notice how the "orbiting rocket" mouse pointer shows up on the screen, but doesn't animate. The hard drive might buzz for a while then fall silent. Depending on your system you may have to turn your computer off entirely. If you reload the game the same thing will happen again eventually, or right away if the save includes the broken state of the map you're trying to enter (but since a map goes bad only when you leave it, the current map of each save will never be corrupted, thankfully). Maps will become corrupted more frequently as you continue to play and amass items, making the game nearly (or literally) unplayable towards the end.
The simplest way to prevent this from happening is to avoid carrying around quest items which you have no further use of. If you want to keep them, don't store them in your trunk but in some accessible container on a map where there are no shops, or where there are not too many items anyway. If you want to be doubly safe, avoid selling too many different items in one place. If you're not in the habit of hoarding items, this will probably not be an issue.
|
© Per Jorner, The Nearly Ultimate Fallout 2 Guide v1.2
Это сообщение отредактировано Crafty - 10 апреля 2015 | 20:55