Вместо
object[#object+1]=x
лучше писать
table.insert(object, x)
Это так, к слову.
А удалять со сдвигом можно через remove:
table.remove(object, i)
Это приведёт к удалению элемента с индексом i, а также к смещению всех последующих элементов на 1 влево, чтобы в таблице в итоге не было дырки.
Считается, что это не самый оптимальный способ работы с массивами. Но так как это встроенная функция, и сам Lua написан на C, то получается довольно быстро в пределах нескольких сотен элементов.
С учётом того, что игровые объекты у вас будут появляться/удаляться не каждый тик, а очень редко, такой способ вполне хорош.
=============================================
В зависимости от задачи, можно по-разному оптимизировать её решение.
Если важен быстрый поиск (по ключу), то лучше использовать уникальный ключ вместо ничего не значащего порядкового номера.
object[x.id] = x
Перебор всех объектов будет возможен через pairs. Правда, без гарантии того, в каком порядке будет перебор:
for k,v in pairs(object) do
Если при этом нужно где-то считать количество всех объектов, то это можно делать в отдельной переменной. При таком подходе можно даже в случае безликих индексов наращивать их до бесконечности, не парясь о дырках, а перебор через pairs. В любом случае подсчёт количества - не проблема. Есть два варианта, как можно это делать:
а) Если количество нужно редко, а добавление/удаление происходит часто, то считать можно каждый раз заново:
local cnt = 0
for _ in pairs(object) do
cnt = cnt + 1
end
б) Если же количество нужно считать часто, а добавление/удаление объектов происходит редко, то лучше обновлять счетчик при добавлении и удалении:
objects_cnt = 0 --всегда содержит количество объектов
--добавление
object[x.id] = x;
objects_cnt = objects_cnt + 1;
--удаление
object[x.id] = nil;
objects_cnt = objects_cnt - 1;