It's buried in Ribbon Maze, but it's an MIT license, so here are the relevant bits:
==== this goes somewhere in config-initialisation ====
local fish = {}
for name,prototype in pairs(game.entity_prototypes) do
if prototype.type=="fish" then
table.insert(fish, name)
end
end
==== Ribbon Maze then saves "fish" as "config.fishList" ====
==== this generates fish ====
local function generateFish(config, surface, chunkPosition, rng)
if rng then
for i = 0, config.fishPerChunk do
local fishName = config.fishList[Cmwc.randRange(rng, 1, #(config.fishList))]
local tileX = chunkPosition.x + Cmwc.randRange(rng, 1, 31)
local tileY = chunkPosition.y + Cmwc.randRange(rng, 1, 31)
surface.create_entity{name=fishName, position={tileX,tileY}}
end
end
end
==== Ribbon Maze is chunk-aligned, so you may want to do things differently ====
Edit:
And of course it loses all the formatting <grumble>