Saving/Loading big map table
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Saving/Loading big map table
Hi everyone!
I'm trying to save generated map in a file, then load it.
If map is small like 128x128 i have no problem saving/loading it using bitser lib. But if map is 8192x2048 i can't load it anymore, application just closes printing this to console '[Finished in 1.8s with exit code 3221225477]'.
Also I'm doing map generation in love.load, and application is 'not responding' while map is generating, after map generation functions are done, application starts responding normally. Do i need to use something like coroutine for generation, so i can show progress bars and such? Or there is better ways to do this?
I'm trying to save generated map in a file, then load it.
If map is small like 128x128 i have no problem saving/loading it using bitser lib. But if map is 8192x2048 i can't load it anymore, application just closes printing this to console '[Finished in 1.8s with exit code 3221225477]'.
Also I'm doing map generation in love.load, and application is 'not responding' while map is generating, after map generation functions are done, application starts responding normally. Do i need to use something like coroutine for generation, so i can show progress bars and such? Or there is better ways to do this?
- zorg
- Party member
- Posts: 3465
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: Saving/Loading big map table
coroutines are fine, but you'll need to yield in love.update, since love.load only gets called once at startup.
otherwise you could use actual threads, but that's more complicated.
as for the bitser thing, it may or may not have a bug with large amounts of data...
otherwise you could use actual threads, but that's more complicated.
as for the bitser thing, it may or may not have a bug with large amounts of data...
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Re: Saving/Loading big map table
i've tried all serializers listed on love2d wiki, bitser was the only one that managed to save such big table.zorg wrote: ↑Mon May 21, 2018 10:16 pm coroutines are fine, but you'll need to yield in love.update, since love.load only gets called once at startup.
otherwise you could use actual threads, but that's more complicated.
as for the bitser thing, it may or may not have a bug with large amounts of data...
do you have any suggestions what should i try?
Re: Saving/Loading big map table
Try Smallfolk maybe? https://github.com/gvx/Smallfolk - it's not binary, though, so the size will be larger. But since it doesn't generate Lua source, it will probably be able to handle that table size.
Also consider the possibility that it's LuaJIT going out of memory. If that's the case, allocating through ffi.new instead of using tables would help. But you'll have to come up with your own serializer in that case.
Also consider the possibility that it's LuaJIT going out of memory. If that's the case, allocating through ffi.new instead of using tables would help. But you'll have to come up with your own serializer in that case.
-
- Party member
- Posts: 234
- Joined: Mon Aug 29, 2016 8:51 am
Re: Saving/Loading big map table
If bitser happens to silently crash the game with large amounts of data, you probably need to increase it's buffer size. That's what fixed it for me @zorg
Re: Saving/Loading big map table
What exactly do you store in the map?
Shameless plug for Blob, my binary serialization library. (De-)serialization of 2048 * 8192 ints:
Doesn't crash, is fast enough to not stall (above code takes ~240 ms in a VM on my laptop) and stores the data in a compact format.
It does also serialize tables, but tables that large would have a hefty overhead; one byte overhead per table key, one byte per table value (except for booleans), and all numbers are stored as 64 bit values.
Shameless plug for Blob, my binary serialization library. (De-)serialization of 2048 * 8192 ints:
Code: Select all
local blob = Blob(nil, 2048 * 8192 * 4)
for y = 0, 2047 do
for x = 1, 8192 do
blob:writeU32(y * 8192 + x)
end
end
local map = {}
for y = 0, 2047 do
for x = 1, 8192 do
map[y * 8192 + x] = blob:readU32()
end
end
It does also serialize tables, but tables that large would have a hefty overhead; one byte overhead per table key, one byte per table value (except for booleans), and all numbers are stored as 64 bit values.
Re: Saving/Loading big map table
In my map i store type of a block 'map[x][y].type = 0'grump wrote: ↑Tue May 22, 2018 8:24 am What exactly do you store in the map?
Shameless plug for Blob, my binary serialization library. (De-)serialization of 2048 * 8192 ints:Doesn't crash, is fast enough to not stall (above code takes ~240 ms in a VM on my laptop) and stores the data in a compact format.Code: Select all
local blob = Blob(nil, 2048 * 8192 * 4) for y = 0, 2047 do for x = 1, 8192 do blob:writeU32(y * 8192 + x) end end local map = {} for y = 0, 2047 do for x = 1, 8192 do map[y * 8192 + x] = blob:readU32() end end
It does also serialize tables, but tables that large would have a hefty overhead; one byte overhead per table key, one byte per table value (except for booleans), and all numbers are stored as 64 bit values.
But how do i save to/load from file using this Blob lib?
Re: Saving/Loading big map table
For optimal results, you should define a maximum value range for type, choose a matching data type (8 bits, 16 bits, 32 bits, 64 bits are possible) and use the corresponding Blob:write*/read* functions as shown above. I advise against serializing huge arrays with Blob:writeTable(), since it introduces overhead and is considerably slower than doing it manually.
Saving and loading is beyond the scope of the lib. You can either useBut how do i save to/load from file using this Blob lib?
Code: Select all
-- save
assert(love.filesystem.write("filename", blob:string()))
-- load
local blob = Blob(assert(love.filesystem.read("filename")))
Code: Select all
-- save
local file = assert(io.open("filename", "wb"))
file:write(blob:string())
file:close()
-- load
local file = assert(io.open("filename", "rb"))
local blob = Blob(file:read("*all"))
file:close()
Edit: it's designed to work with data in RAM - if your maps don't fit at least twice into memory (once for the raw data, and at least the same amount of RAM for the parsed data), it'll become harder to serialize them, because you have to implement chunk loading yourself. 8192 * 2048 ints need 64 MB of RAM, so that should not be a huge problem for you.
Re: Saving/Loading big map table
So if i understand this correctry when i do this:grump wrote: ↑Tue May 22, 2018 12:53 pmFor optimal results, you should define a maximum value range for type, choose a matching data type (8 bits, 16 bits, 32 bits, 64 bits are possible) and use the corresponding Blob:write*/read* functions as shown above. I advise against serializing huge arrays with Blob:writeTable(), since it introduces overhead and is considerably slower than doing it manually.
Code: Select all
for y = 1, 2048 do
for x = 1, 8192 do
blob:writeU8(1)
end
end
and when i do this :
Code: Select all
local map = {}
for y=1,2048 do
map[y] = {}
for x=1,8192 do
map[y][x] = blob:readU8()
end
end
Re: Saving/Loading big map table
Yes. Although using a table of tables is not the most efficient way to do this, it will work fine.
For maximum effciency use a plain, one-dimensional array and index like this:
Or even simpler:
That's not Blob related though, just general performance advice. You'll get better cache hit rates when you do it like this.
For maximum effciency use a plain, one-dimensional array and index like this:
Code: Select all
local map = {}
for y = 0, 2047 do
for x = 1, 8192 do
map[y * 8192 + x] = blob:readU8()
end
end
Code: Select all
local map = {}
for pos = 1, 2048 * 8192 do
map[pos] = blob:readU8()
end
-- looking up a x, y coordinate
local type = map[(y - 1) * 8192 + x]
Who is online
Users browsing this forum: Ahrefs [Bot] and 6 guests