The problem I reported before was in fact a hang. It was quite an interesting one. Essentially when Tristram is created, the shops are reloaded. Each of them is looking for items to sell, and there's no limit on the number of times they'll try random generation to get acceptable items. All that makes an item acceptable is a positive price and having no spell on it, which should be no problem because almost all items have prices and most don't have spells. However, the way items are created is to use data from a master lua table. The Delphi code in charge of building an item is very forgiving about fields that might not be present, and simply fills in defaults, including a value of zero for price. The fields are all there in the master table, but the call TLuaTable.TryGetField doesn't set its result value in the case of success. That means that an arbitrary collection of properties on an object are not initialised, they just come from the defaults. So: every single item that the shop refiller tries to generate has a zero price, even though the lua datastructures are being initialised correctly. Loading Tristram therefore hangs.
The following patch fixes that bug and one other less interesting one. On my machine, running the sytem in debug mode segfaults. The culprit is ClearInterrupts which generates a range exception because the iterator is a Word instead of an Integer (I don't know why this should be, but it is reproducible). Now that except occurs in a constructor, and in fact in a naughty constructor which is doing work before its ancestors have been initialised. One of those ancestors has prev and next pointers to a linked list of like objects, and those prev and next pointers always point to something valid (in the case of the single item list, they both point to the object itself). When an attempt is made to Detach the uninitialised ancestor, it tries to shrink the list using its prev and next pointers, but they are null (because that naughty constructor TTextIODriver.Create is doing work before initialising it). The result is crash.
After applying this patch you should find you can walk around Tristram. This is how far forward I am. Hopefully I can sit down and play now!
Index: src/viotypes.pas
===================================================================
--- src/viotypes.pas (revision 571)
+++ src/viotypes.pas (working copy)
@@ -125,10 +125,10 @@
{ TIODriver }
procedure TIODriver.ClearInterrupts;
-var iCount : Word;
+var iCount : Integer;
begin
FOnQuit := nil;
- for iCount := 0 to High(FInterrupts) do FInterrupts[iCount] := nil;
+ for iCount := Low(FInterrupts) to High(FInterrupts) do FInterrupts[iCount] := nil;
end;
procedure TIODriver.RegisterInterrupt ( aCode : TIOKeyCode; aInterrupt : TIOInterrupt );
Index: src/vluatable.pas
===================================================================
--- src/vluatable.pas (revision 571)
+++ src/vluatable.pas (working copy)
@@ -892,6 +892,7 @@
begin
lua_getfield( FState, -1, PChar( aKey ) );
if lua_isnil( FState, -1 ) then Exit( False );
+ Result := True;
end;
procedure TLuaTable.RunGetField ( const aKey : AnsiString; ReqType : Byte ) ;
@@ -904,6 +905,7 @@
begin
lua_getfield( FState, -1, PChar( aKey ) );
if lua_type( FState, -1 ) <> ReqType then Exit( False );
+ Result := True;
end;
function TLuaTable.IsField ( const aKey : AnsiString; ReqType : Byte ) : Boolean;