Does the order really matter for bullets and possibly glowing particles and the like? I find it redundant to, say if index 10 is removed from list of 100 bullets you would move all remaining 90 or so of them 1 backwards... It is simpler to move the last index in place of the removed one. 1 operation vs 90 operations. In order for this to work, you need to use a "downto" in the for loop, going from the last item to 0.

Code:
for b:=bullets-1 downto 0 do
  with bullet[b] do begin
    Move;
    dec(AliveTime);
    if AliveTime < 0 then begin
      dec(bullets);
      //bullet[b].Free; // Free it here if you must. Not needed if using records
      bullet[b]:=bullet[bullets]; // Replace current bullet with last one.
    end;
  end;
New bullets will then always be added to the end.