Jump to content

Beta ANR and mod issue


Recommended Posts

I have issue with the beta branch and some of my mods.

The game crashe when loading a world (or creating one) with these mods enabled. I guess it linked with the set piece part. Here is the error log :

 

[00:00:43]: ModIndex:GetModsToLoad inserting moddir, 	MermAndWarg	
[00:00:43]: Could not load mod_config_data/modconfiguration_MermAndWarg_staging	
[00:00:43]: Loading mod: MermAndWarg (Merm and Warg) Version:0.11	
[00:00:43]: Mod: MermAndWarg (Merm and Warg)	Loading modworldgenmain.lua	
[00:00:43]: MOD ERROR: MermAndWarg (Merm and Warg): Mod: MermAndWarg (Merm and Warg)	
[00:00:43]: Mod: MermAndWarg (Merm and Warg)	Loading modmain.lua	
[00:00:43]: [string "scripts/prefabswaps.lua"]:186: attempt to index upvalue '_inactive_prefabs' (a nil value)
LUA ERROR stack traceback:
        scripts/prefabswaps.lua(186,1) in function 'IsPrefabInactive'
        scripts/map/static_layout.lua(79,1) in function 'Get'
        scripts/map/layouts.lua(110,1) in main chunk
        =[C] in function 'require'
        ../mods/MermAndWarg/modworldgenmain.lua(8,1) in main chunk
        =[C] in function 'xpcall'
        scripts/util.lua(609,1) in function 'RunInEnvironment'
        scripts/mods.lua(470,1) in function 'InitializeModMain'
        scripts/mods.lua(440,1) in function 'LoadMods'
        scripts/main.lua(251,1) in function 'ModSafeStartup'
        scripts/main.lua(306,1)
        =[C] in function 'SetPersistentString'
        scripts/mainfunctions.lua(22,1) in function 'SavePersistentString'
        scripts/modindex.lua(76,1)
        =[C] in function 'GetPersistentString'
        scripts/modindex.lua(63,1) in function 'BeginStartupSequence'
        scripts/main.lua(305,1) in function 'callback'
        scripts/modindex.lua(516,1)
        =[C] in function 'GetPersistentString'
        scripts/modindex.lua(490,1) in function 'Load'
        scripts/main.lua(304,1) in main chunk
[00:00:43]: [string "scripts/mainfunctions.lua"]:971: variable 'global_error_widget' is not declared
LUA ERROR stack traceback:
        =[C] in function 'error'
        scripts/strict.lua(23,1)
        scripts/mainfunctions.lua(971,1)
        =[C] in function 'SetPersistentString'
        scripts/mainfunctions.lua(22,1) in function 'SavePersistentString'
        scripts/modindex.lua(76,1)
        =[C] in function 'GetPersistentString'
        scripts/modindex.lua(63,1) in function 'BeginStartupSequence'
        scripts/main.lua(305,1) in function 'callback'
        scripts/modindex.lua(516,1)
        =[C] in function 'GetPersistentString'
        scripts/modindex.lua(490,1) in function 'Load'
        scripts/main.lua(304,1) in main chunk
[00:00:43]: DoLuaFile Error: (null)
[00:00:43]: LuaError but no error string
[00:00:43]: Error loading main.lua
[00:00:43]: Failed mSimulation->Reset()
[00:00:43]: Error during game restart!
[00:00:44]: SteamWorkshop::CancelDownloads clearing all unfinished downloads
[00:00:44]: Collecting garbage...
[00:00:44]: lua_gc took 0.01 seconds
[00:00:44]: ~ShardLuaProxy()
[00:00:44]: ~ItemServerLuaProxy()
[00:00:44]: ~InventoryLuaProxy()
[00:00:44]: ~NetworkLuaProxy()
[00:00:44]: ~SimLuaProxy()
[00:00:44]: SteamWorkshop::CancelDownloads clearing all unfinished downloads
[00:00:44]: lua_close took 0.01 seconds
[00:00:44]: SteamWorkshop::CancelDownloads clearing all unfinished downloads
[00:00:44]: [Steam] Auth ticket cancelled
[00:00:44]:  Manager - ORPHANED UNKNOWN RESOURCES:
[00:00:44]: shaders/ui_yuv.ksh - 1
[00:00:45]: CurlRequestManager::ClientThread::Main() complete
[00:00:45]: HttpClient2 discarded 0 callbacks.
[00:00:45]: Shutting down

 

Here is the code implied as far as i can tell :

-- GLOBAL variables which are needed.
local require = GLOBAL.require

--[[	Copyright © 2015 Ysovuka/Kzisor	 ]]

-- The Layouts table is where we will add our set piece layout.
-- The file is provided in "scripts/map" of the original game.
local Layouts = require("map/layouts").Layouts

-- The StaticLayouts variable is used to get the layout of our set piece.
-- The file is provided in "scripts/map" of the original game.
local StaticLayouts = require("map/static_layout")

-- Thie LEVELTYPE table is used to indicate the level identification.
-- The file is provided in "scripts/map" of the original game.
require("map/level")
local LEVELTYPE = GLOBAL.LEVELTYPE
LEVELTYPE.ALL = "ALL"


-- This function acts as a wrapper which we will use to add our custom layout to the game.
-- The name of the layout will be identical to the filename.
local function AddLayout(name)
	-- Puts our layout in the Layouts table.
	Layouts[name] = StaticLayouts.Get("map/static_layout/"..name)

	-- We return the name and the layout for later usage.
	return name, Layouts[name]
end


-- This function acts as a wrapper which we will use to add our custom layout as a random set piece.
-- This function requires a Level Identification (LEVELTYPE.ALL, LEVELTYPE.SURVIVAL, LEVELTYPE.CAVE, LEVELTYPE.ADVENTURE, LEVELTYPE.TEST, LEVELTYPE.UNKNOWN, LEVELTYPE.CUSTOM).
local function AddRandomSetPiece(levelid, layout_name)
	-- Check to see if we want it on all level types.
	if levelid == LEVELTYPE.ALL then
		AddLevelPreInitAny(function(level)
			-- Ensure that we have a variable to store our data.
			if not level.random_set_pieces then
				level.random_set_pieces = {}
			end

			table.insert(level.random_set_pieces, layout_name)
		end)

	else -- We want it on a specific level type.
		AddLevelPreInit(levelid, function(level)
			-- Ensure that we have a variable to store our data.
			if not level.random_set_pieces then
				level.random_set_pieces = {}
			end

			table.insert(level.random_set_pieces, layout_name)
		end)
	end
end

-- This function acts as a wrapper which we will use to add our custom layout as a static set piece per level.
-- This function requires Level Identification (LEVELTYPE.ALL, LEVELTYPE.SURVIVAL, LEVELTYPE.CAVE, LEVELTYPE.ADVENTURE, LEVELTYPE.TEST, LEVELTYPE.UNKNOWN, LEVELTYPE.CUSTOM).
-- This function requires a list of tasks which can be located in "scripts/map/tasks.lua" file of the original game.
function env.AddSetPiece(levelid, layout_name, count, tasks, chance)
     
    -- Set chance to chance or 100 to ensure it spawns.
    chance = chance or 100

    -- Set count to count or 1 to ensure it spawns.
    count = count or 1
	
local function RandomChance()
        local _count = 0
 
        for i = 0, count do
            if (chance * 10) >= math.random(1, 1000) then
                _count = _count + 1
            end
        end
 
        return _count
    end
    -- Check to see if we want it on all level types.
    if levelid == LEVELTYPE.ALL then
        AddLevelPreInitAny(function(level)
            -- Ensure that we have a variable to store our data.
            if not level.set_pieces then
                level.set_pieces = {}
            end
 
            -- Initial set up.
            level.set_pieces[layout_name] = { count = 0, tasks = tasks }
 
            -- Add our layout to the room layouts ensuring at least one spawns.
            level.set_pieces[layout_name].count = RandomChance() or 0
        end)
 
    else -- We want it on a specific level type.
        AddLevelPreInit(levelid, function(level)
            -- Ensure that we have a variable to store our data.
            if not level.set_pieces then
                level.set_pieces = {}
            end
 
            -- Initial set up.
            level.set_pieces[layout_name] = { count = 0, tasks = tasks }

            -- Add our layout to the room layouts ensuring at least one spawns.
            level.set_pieces[layout_name].count = RandomChance() or 0
        end)
    end
end

-- This function acts as a wrapper which we will use to add our custom layout as a static set piece per room.
-- This function requires Room Idenficiation (A list of rooms can be found in rooms.lua).
-- The rooms.lua file is located in the root directory of this mod.
function env.AddRoomSetPiece(room_name, layout_name, count, chance)
     
    -- Set chance to chance or 100 to ensure it spawns.
    chance = chance or 100

    -- Set count to count or 1 to ensure it spawns.
    count = count or 1

local function RandomChance()
        local _count = 0
 
        for i = 0, count do
            if (chance * 10) >= math.random(1, 1000) then
                _count = _count + 1
            end
        end
 
        return _count
    end
 
    AddRoomPreInit(room_name, function(room)
        -- Ensure that we have a variable to store our data.
        if not room.contents.countstaticlayouts then
            room.contents.countstaticlayouts = {}
        end
 
        -- Initial set up.
        room.contents.countstaticlayouts[layout_name] = 0
 
        -- Add our layout to the room layouts ensuring at least one spawns.
        room.contents.countstaticlayouts[layout_name] = RandomChance() or 0
    end)
 
end

-- Initialize the task list.
local Tasks = require("map/tasks")


-- Initialize our custom layout.
local hound_warg_coat_layout_name, hound_warg_coat_layout = AddLayout("hound_warg_coat")


AddRoomSetPiece("BGCrappyForest", hound_warg_coat_layout_name, 1, 10)
-- AddSetPiece(LEVELTYPE.ALL, hound_warg_coat_layout_name, math.random(1, 2), GetTaskList(), 100)

 

So i suppose it's related to the static_layout.lua, and probably this part

 

                if not PrefabSwaps.IsPrefabInactive(obj.type) then
                    local prefab = PrefabSwaps.ResolvePrefabProxy(obj.type)

    				if layout.layout[prefab] == nil then
    					layout.layout[prefab] = {}
    				end

 

Since it seems that it's the part where the prefabswaps thing appears.

 

All is working fine in stable branch, it's only on beta branch that the problem appears. I don't understand coding and error message enough to know what is wrong exactly.

Is there a simple fix ? What is the source of the problem ?

 

 

Here is the complete mod if it could help :

 

MermAndWarg.zip
 

Link to comment
Share on other sites

Any clue anyone ?

@Ipsquiggle, @V2C, are you still helping modder to figure what is wrong with code change, like you did when you change world gen ? (I could understand if you don't have time for this)

What is the prefabswaps is supposed to do and how to make set piece compatible with it ?

Link to comment
Share on other sites

I am experiencing the exact same problem with my own mod (Multi-Worlds DST). I get the following error when I subscribe to the beta:

[00:00:43]: [string "scripts/prefabswaps.lua"]:186: attempt to index upvalue '_inactive_prefabs' (a nil value)

However, without the beta, everything works fine. Still, it sucks because it means that sooner or later my mod will stop working when the beta becomes the main branch, and I am already getting some complaints by people that they are no longer able to use my mod (because hey, they want to play with the new features of the beta).

I would love to see a solution for this. I think a lot of other mods are affected too. Probably any mod that does something with setpieces / static_layouts is affected by this, and this somehow relates to the (obsolete?) prefabswaps.

Could anyone look into this? I am pretty sure it is not something I or @Lumina did.

@PeterA, could you help out here?

Lots of love,

Joachim

Edited by Joachim
Link to comment
Share on other sites

I will add my own report on how worldgen mods act. I joined the beta and went to create some servers for the group (since while on the beta branch, your live branch servers are inaccessible).

Any mod which adds new animals gives "Dedicated server failed to load". Examples: Multi-Worlds DST, Winnie the Shepherdess. Joachim identified this as a problem with static layouts. Interested parties can gape in awe look into the log here: http://sta.sh/01ou5q810mml

Most importantly, this does not render the servers broken. They just do not load at the moment. They are generated though and remain in my slots.

Removal causes any world to load.

Link to comment
Share on other sites

  • Developer

Thanks for the report!

This is happening now since the new prefab swap code needs to be initialized before set pieces are generated.  We'll have a hotfix shortly for fixing the crash.

Although this prevents the crash, affected mods will have the side effect of generating set pieces with default prefabs even when variants are chosen during world gen.  (e.g., MooseGoose nest will have regular Berry Bushes even when the rest of the world is populated with Juicy Berry Bushes.)

But fear not! @PeterA will follow up shortly to tell you how to update your mod to fix that =)

Link to comment
Share on other sites

  • Developer

Hey guys!

I looked into the mod, and what we'll want the worldgen mods to change to, is instead of calling StaticLayouts.Get (and require("map/layouts") ) from modworlgenmain.lua, you'll want to add it to the AddRoomPreInit callback function. This will ensure that our function ConvertStaticLayoutToLayout gets called after the prefab swap data is setup. Specifically in your case, the call to AddLayout should be inside AddRoomPreInit(room_name, function(room), as well as requiring in the Layouts and StaticLayouts inside your AddLayout function.

Here's the updated modworldgenmain.lua
 

-- GLOBAL variables which are needed.
local require = GLOBAL.require

--[[	Copyright © 2015 Ysovuka/Kzisor	 ]]
	
-- This LEVELTYPE table is used to indicate the level identification.
-- The file is provided in "scripts/map" of the original game.
require("map/level")
local LEVELTYPE = GLOBAL.LEVELTYPE
LEVELTYPE.ALL = "ALL"


-- This function acts as a wrapper which we will use to add our custom layout to the game.
-- The name of the layout will be identical to the filename.
local function AddLayout(name)
	-- The Layouts table is where we will add our set piece layout.
	-- The file is provided in "scripts/map" of the original game.
	local Layouts = require("map/layouts").Layouts

	-- The StaticLayouts variable is used to get the layout of our set piece.
	-- The file is provided in "scripts/map" of the original game.
	local StaticLayouts = require("map/static_layout")

	-- Puts our layout in the Layouts table.
	Layouts[name] = StaticLayouts.Get("map/static_layout/"..name)

	-- We return the name and the layout for later usage.
	return name, Layouts[name]
end


-- This function acts as a wrapper which we will use to add our custom layout as a random set piece.
-- This function requires a Level Identification (LEVELTYPE.ALL, LEVELTYPE.SURVIVAL, LEVELTYPE.CAVE, LEVELTYPE.ADVENTURE, LEVELTYPE.TEST, LEVELTYPE.UNKNOWN, LEVELTYPE.CUSTOM).
local function AddRandomSetPiece(levelid, layout_name)
	-- Check to see if we want it on all level types.
	if levelid == LEVELTYPE.ALL then
		AddLevelPreInitAny(function(level)
			-- Ensure that we have a variable to store our data.
			if not level.random_set_pieces then
				level.random_set_pieces = {}
			end

			table.insert(level.random_set_pieces, layout_name)
		end)

	else -- We want it on a specific level type.
		AddLevelPreInit(levelid, function(level)
			-- Ensure that we have a variable to store our data.
			if not level.random_set_pieces then
				level.random_set_pieces = {}
			end

			table.insert(level.random_set_pieces, layout_name)
		end)
	end
end

-- This function acts as a wrapper which we will use to add our custom layout as a static set piece per level.
-- This function requires Level Identification (LEVELTYPE.ALL, LEVELTYPE.SURVIVAL, LEVELTYPE.CAVE, LEVELTYPE.ADVENTURE, LEVELTYPE.TEST, LEVELTYPE.UNKNOWN, LEVELTYPE.CUSTOM).
-- This function requires a list of tasks which can be located in "scripts/map/tasks.lua" file of the original game.
function env.AddSetPiece(levelid, layout_name, count, tasks, chance)
     
    -- Set chance to chance or 100 to ensure it spawns.
    chance = chance or 100

    -- Set count to count or 1 to ensure it spawns.
    count = count or 1
	
	local function RandomChance()
        local _count = 0
 
        for i = 0, count do
            if (chance * 10) >= math.random(1, 1000) then
                _count = _count + 1
            end
        end
 
        return _count
    end
    -- Check to see if we want it on all level types.
    if levelid == LEVELTYPE.ALL then
        AddLevelPreInitAny(function(level)
            -- Ensure that we have a variable to store our data.
            if not level.set_pieces then
                level.set_pieces = {}
            end
 
            -- Initial set up.
            level.set_pieces[layout_name] = { count = 0, tasks = tasks }
 
            -- Add our layout to the room layouts ensuring at least one spawns.
            level.set_pieces[layout_name].count = RandomChance() or 0
        end)
 
    else -- We want it on a specific level type.
        AddLevelPreInit(levelid, function(level)
            -- Ensure that we have a variable to store our data.
            if not level.set_pieces then
                level.set_pieces = {}
            end
 
            -- Initial set up.
            level.set_pieces[layout_name] = { count = 0, tasks = tasks }

            -- Add our layout to the room layouts ensuring at least one spawns.
            level.set_pieces[layout_name].count = RandomChance() or 0
        end)
    end
end

-- This function acts as a wrapper which we will use to add our custom layout as a static set piece per room.
-- This function requires Room Idenficiation (A list of rooms can be found in rooms.lua).
-- The rooms.lua file is located in the root directory of this mod.
function env.AddRoomSetPiece(room_name, layout_name, count, chance)
   
    -- Set chance to chance or 100 to ensure it spawns.
    chance = chance or 100

    -- Set count to count or 1 to ensure it spawns.
    count = count or 1

	local function RandomChance()
        local _count = 0
 
        for i = 0, count do
            if (chance * 10) >= math.random(1, 1000) then
                _count = _count + 1
            end
        end
 
        return _count
    end
 
    AddRoomPreInit(room_name, function(room)
		-- Initialize our custom layout.
		AddLayout(layout_name)
		
        -- Ensure that we have a variable to store our data.
        if not room.contents.countstaticlayouts then
            room.contents.countstaticlayouts = {}
        end
	
        -- Initial set up.
        room.contents.countstaticlayouts[layout_name] = 0
 
        -- Add our layout to the room layouts ensuring at least one spawns.
        room.contents.countstaticlayouts[layout_name] = RandomChance() or 0
    end)
 
end


AddRoomSetPiece("BGCrappyForest", "hound_warg_coat", 1, 10)





 

Link to comment
Share on other sites

  • Developer
17 minutes ago, Lumina said:

Sorry @PeterA, english isn't my native langage and if usually i could understand enough, i'm not sure of what you ask exactly here.

I got crash the first time without it, but maybe it wasn't related. Anyway, all is fine, so i'm happy

No worries. I was just trying to understand why "local Tasks = require("map/tasks")" was needed.

I'm glad to hear you got it working!

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
 Share

×
  • Create New...