Both look very good. My only suggestion is related to cross-platform portability, and possibly speed.

TCollection and TCollectionItem are ideal if you plan to stream the object as it inherits from TPerstent. I would be inclined to write a more specific streaming code and would suggest doing something like...

[pascal]
TLightItem = class( TObject )
public
// All your other properties here
procedure Initialise;
end;

TLightSystem = class( TObjectList )
private
function GetItems( aIndex : Integer ) : TLightItem;
procedure SetItems( aIndex : Integer; const aLightItem : TLightItem );
public
function Add( aLightItem : TLightItem ) : Integer;
function Extract( aLightItem : TLightItem ) : TLightItem;
function Remove( aLightItem : TLightItem ) : Integer;
function IndexOf( aLightItem : TLightItem ) : Integer;
function First : TLightItem;
function Last : TLightItem;
procedure Insert( aIndex : Integer; aLightItem : TLightItem );
property Items[ Index : Integer ] : TLightItem read GetItems write SetItems; default;
end;
...
implementation

{ TLightSystem }

function TLightSystem.Add(aLightItem : TLightItem): Integer;
begin
result := inherited Add( aLightItem);
end;

function TLightSystem.Extract(aLightItem : TLightItem): TLightItem;
begin
result := TLightItem( inherited Extract( aLightItem) );
end;

function TLightSystem.First: TLightItem;
begin
result := TLightItem( inherited First );
end;

function TLightSystem.GetItems(aIndex: Integer): TLightItem;
begin
result := TLightItem( inherited Items[ aIndex ] );
end;


function TLightSystem.IndexOf(aLightItem : TLightItem): Integer;
begin
result := inherited IndexOf( aLightItem);
end;

procedure TLightSystem.Insert(aIndex: Integer; aLightItem : TLightItem);
begin
inherited Insert( aIndex, aLightItem);
end;

function TLightSystem.Last: TLightItem;
begin
result := TLightItem( inherited Last );
end;

function TLightSystem.Remove(aLightItem : TLightItem): Integer;
begin
result := inherited Remove( aLightItem);
end;

procedure TLightSystem.SetItems(aIndex: Integer; const aLightItem : TLightItem);
begin
inherited Items[ aIndex ] := aLightItem;
end;

[/pascal]

This should give you a lighter and thus faster ( though I would suggest benchmarking things like Add and Remove to be sure ) class hierachy and should also be portable to FreePascal should you want to port your code later on. The you could add specific Load and Save Methods to the TLightSytem class to handle your streaming.

Anyway it is just a thought.