Jump to content

WorldSim:ResetAll() does not reset all internal state as before


clearlove
  • Closed

In the previous version, in worldgen_main.lua, the following codes are used when generation fails.

collectgarbage("collect")
WorldSim:ResetAll()

According to my experiments, the WorldSim:ResetAll() does not reset all internal states as previous version.


Steps to Reproduce

You can modify the function `LoadParametersAndGenerate` in worldgen_main.lua with the following to verify:

local function table_to_json_string(tbl)
	local result = "{"
	for k, v in pairs(tbl) do
		if type(v) == "table" then
			result = result .. '"' .. k .. '":' .. table_to_json_string(v) .. ","
		else
			if type(v) == "string" then
				v = '"' .. v .. '"'
			elseif type(v) == "function" then
				v = '"function"'
			end
			result = result .. '"' .. k .. '":' .. tostring(v) .. ","
		end
	end
	-- remove trailing comma and close table
	if result ~= "{" then
		result = result:sub(1, -2)
	end
	result = result .. "}"
	return result
end

local function table_to_json_file(tbl, filename)
	local json_string = table_to_json_string(tbl)
	local file = io.open(filename, "w")
	if file then
		file:write(json_string)
		file:close()
	else
		error("Could not open file for writing: " .. filename)
	end
end

local function LoadParametersAndGenerate(debug)

    local world_gen_data = nil
    assert(GEN_PARAMETERS ~= nil, "Parameters were not provided to worldgen!")
    world_gen_data = json.decode(GEN_PARAMETERS)

    SetDLCEnabled(world_gen_data.DLCEnabled)

    local generated_data = GenerateNew(debug, world_gen_data)
    table_to_json_file(generated_data, "generated_data_official1.json")
    collectgarbage("collect")
    WorldSim:ResetAll()
    local generated_data = GenerateNew(debug, world_gen_data)
    table_to_json_file(generated_data, "generated_data_official2.json")
    return generated_data
end

The data in generated_data_official1.json is different from generated_data_official1.json. However, in the previous version, they are identical except for the field "session_identifier".

  • Like 5



User Feedback


This function resets all of the world tile states but does nothing to preserve world generation state if it did the loop in GenerateNew where this form of reset is used would be doing nothing.

Changed Status to Closed

Share this comment


Link to comment
Share on other sites

17 hours ago, JesseB_Klei said:

where this form of reset is used would be doing nothing.

Yes! This is how it has always functioned, but as of the latest update, it no longer "does nothing". It seems to entirely reroll the world layout when called before returning the data from GenerateNew, which I highly doubt is intended

Share this comment


Link to comment
Share on other sites

On 7/3/2024 at 4:42 AM, JesseB_Klei said:

This function resets all of the world tile states but does nothing to preserve world generation state if it did the loop in GenerateNew where this form of reset is used would be doing nothing.

Changed Status to Closed

Hi JesseB, thanks for your reply. It seems I didn't make myself clear. The bug is that the following code is no longer idempotent since V617969.

SEED = SetWorldGenSeed(1172289482)
local generated_data = GenerateNew(debug, world_gen_data)
collectgarbage("collect")
WorldSim:ResetAll()

It might not be a bug in ResetAll(); instead, it could be caused by updates in other parts of the code.

 

The following are the several phenomena that I have observed.

SEED = SetWorldGenSeed(1172289482)
local generated_data = GenerateNew(debug, world_gen_data)
collectgarbage("collect")
WorldSim:ResetAll()
SEED = SetWorldGenSeed(1172289482)
local generated_data2 = GenerateNew(debug, world_gen_data)  -- different from generated_data
collectgarbage("collect")
WorldSim:ResetAll()
SEED = SetWorldGenSeed(1172289482)
local generated_data3 = GenerateNew(debug, world_gen_data)  -- identicial to generated_data3
collectgarbage("collect")
WorldSim:ResetAll()

But for the previous version, all these "generated_data" are the same.

 

More experiments:

I further comment out some codes in `forest_map.Generate` to see which lines destroy such idempotent.  I think the following line in `forest_map.Generate` is responsible for this change.

topology_save.root:ConvertGround(SpawnFunctions, entities, map_width, map_height)

I deleted this line and the code following it, and got a `PartialGenerateNew` to replace `GenerateNew`. Executing `PartialGenerateNew` will not affect the subsequent calls to function `GenerateNew` while `GenerateNew` will.

SEED = SetWorldGenSeed(1172289482)
PartialGenerateNew(debug, world_gen_data)
collectgarbage("collect")
WorldSim:ResetAll()
SEED = SetWorldGenSeed(1172289482)
local generated_data = GenerateNew(debug, world_gen_data)  -- the "PartialGenerateNew" will not influence this generated_data

 

  • Like 1

Share this comment


Link to comment
Share on other sites

 I conduct further experiments. I deleted more lines of codes, and found that the `ConvertGround` function will call the function `LayoutForDefinition`. The following line of `LayoutForDefinition` will make a difference.

local objs = require("map/layouts")

I hypothesize that it is this `require` sentence that destroys the idempotent. I verify this hypothesis using the following codes.

local function LoadParametersAndGenerate(debug)

  local world_gen_data = nil
  assert(GEN_PARAMETERS ~= nil, "Parameters were not provided to worldgen!")
  world_gen_data = json.decode(GEN_PARAMETERS)


  SetDLCEnabled(world_gen_data.DLCEnabled)

  local test_obj = require("map/layouts")  -- Adding this line change the map in V617969, while does not change the map in V605310
  SetWorldGenSeed(1172289482)
  return GenerateNew(debug, world_gen_data)
end

Adding this `require` statement will change the generated map in V617969. I also tested V605310, adding such a line will make no difference. 

——————————————————————————

Update: 

Oh, I think I have figured this bug out. This is a bug that lies in the newly added "AbandonedBoat1" and "AbandonedBoat2" layout. The following modification is needed.

["AbandonedBoat1"] = StaticLayout.Get("map/static_layouts/abandonedboat",
  {
    start_mask = PLACE_MASK.IGNORE_IMPASSABLE_BARREN_RESERVED,
    fill_mask = PLACE_MASK.IGNORE_IMPASSABLE_BARREN_RESERVED,
    areas = 
    {
      -- item_area1 = {math.random() >= .5 and "spoiled_fish_small" or "spoiled_fish"},
      item_area1 = function() return math.random() >= .5 and {"spoiled_fish_small"} or {"spoiled_fish"} end,
      -- item_area2 = {math.random() >= .5 and "twigs" or "cutgrass"},
      item_area2 = function() return math.random() >= .5 and {"twigs"} or {"cutgrass"} end,
      mast_area = {"mast_broken"},
      fishing_item_area = {"chum"},
      seastack_area = function() return math.random() < 0.9 and {"seastack"} or nil end
    },
  }),

["AbandonedBoat2"] = StaticLayout.Get("map/static_layouts/abandonedboat",
  {
    start_mask = PLACE_MASK.IGNORE_IMPASSABLE_BARREN_RESERVED,
    fill_mask = PLACE_MASK.IGNORE_IMPASSABLE_BARREN_RESERVED,
    areas = 
    {
      -- item_area1 = {math.random() >= .5 and "oar" or "oar_driftwood"},
      item_area1 = function() return math.random() >= .5 and {"oar"} or {"oar_driftwood"} end,
      -- item_area2 = {math.random() >= .5 and "twigs" or "cutgrass"},
      item_area2 = function() return math.random() >= .5 and {"twigs"} or {"cutgrass"} end,
      mast_area = {},
      -- fishing_item_area = {math.random() >= .5 and "oceanfishinglure_hermit_snow" or "oceanfishinglure_hermit_heavy"},
      fishing_item_area = function() return math.random() >= .5 and {"oceanfishinglure_hermit_snow"} or {"oceanfishinglure_hermit_heavy"} end,
      seastack_area = function() return math.random() < 0.9 and {"seastack"} or nil end
    },
  }),

The call of `math.random()` should be wrapped into a function. In addition to breaking the idempotence of the GenerateNew function, this error also causes the old seeds to become completely invalid.

Edited by clearlove
  • Thanks 1

Share this comment


Link to comment
Share on other sites

I have submitted a separate bug report. This bug report does not touch the core of the bug. See: 

 

Share this comment


Link to comment
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
  • Create New...