Developer Cheerio Posted November 14, 2013 Developer Share Posted November 14, 2013 In case you missed it, the Maxwell fight is a cool example of using the Tiled to make a new level. It's also a really cool boss fight . http://steamcommunity.com/sharedfiles/filedetails/?id=194499642 Link to comment Share on other sites More sharing options...
Malacath Posted November 14, 2013 Share Posted November 14, 2013 I was already wondering if I could use a bossfight to spawn the player into any custom world (even if it's not actually a boss fight). So now I don't have to make my own thread Do you think I can do that and make the level I'm spawned in a cave-like level or will that not be possible the way it's set up? Or am I even misunderstanding the code completely and the level mode "bossfight" is a completely arbitrary name nad I could just as well write "super_mario_land" there? (which is not what I'm intending to do btw) Link to comment Share on other sites More sharing options...
simplex Posted November 14, 2013 Share Posted November 14, 2013 I was already wondering if I could use a bossfight to spawn the player into any custom world (even if it's not actually a boss fight). So now I don't have to make my own thread Do you think I can do that and make the level I'm spawned in a cave-like level or will that not be possible the way it's set up? Or am I even misunderstanding the code completely and the level mode "bossfight" is a completely arbitrary name nad I could just as well write "super_mario_land" there? (which is not what I'm intending to do btw) You can. Sorry for not replying to this, there are a few tricky pitfalls regarding mod levels versus losing all mod savedata if the save gets loaded with it disabled, so I was hoping this would be settled before I could give a proper, robust method of doing that. But a temporary level like for a boss fight is a much easier thing to manage. The actual level type used by lost_fragment is LEVELTYPE.CUSTOM, but you can surely use LEVELTYPE.CAVE, like U&A. Link to comment Share on other sites More sharing options...
Malacath Posted November 14, 2013 Share Posted November 14, 2013 @simplexBut I thought that if I create a new level of the type "CAVE" it could be randomly choosen when enetering a cave. Also I'm more confused on how to actually get the player into that new level because as far as I can see this is the only code involved in itfunction self:StartBossfight(cb) local function ongamesaved() self.data.slots[self.current_slot].current_mode = "bossfight" self.data.slots[self.current_slot].modes.bossfight = {} -- Hunt through the survival levels and find ours, then save its index. local Levels = require("map/levels") for i,level in ipairs(Levels.custom_levels) do if level.id == "BOSSFIGHT" then self.data.slots[self.current_slot].modes.bossfight.options = { level_id = i } print("Found a bossfight level:",i) break end end self:Save(cb) end self:SaveCurrent(ongamesaved) endAnd I don't see exactly what puts you in the new level there. Tbh I didn't really dive into the mod yet so I might immediately find something in another file. I should just not ask question before trying to really answer them myself first... EDIT: Also I just want to use "CAVE" for the walls and the darkness, but I guess that is not closely linked to the level type so I might as well use "CUSTOM" Link to comment Share on other sites More sharing options...
simplex Posted November 14, 2013 Share Posted November 14, 2013 @simplexBut I thought that if I create a new level of the type "CAVE" it could be randomly choosen when enetering a cave.No, cave levels are not chosen randomly. There are only two levels (in vanilla), organized by level number (1 for regular caves, 2 for ruins). Adding a new cave level would use another level number (3, unless other mods are doing the same), which wouldn't be used because the cave_entrance only increments the level number until 2. But I have to check what exactly are the details for the CUSTOM level type, because last time I dug into the worldgen code it didn't exist, and for some reason its introduction was not announced in any update notes...Also I'm more confused on how to actually get the player into that new level because as far as I can see this is the only code involved in itfunction self:StartBossfight(cb) local function ongamesaved() self.data.slots[self.current_slot].current_mode = "bossfight" self.data.slots[self.current_slot].modes.bossfight = {} -- Hunt through the survival levels and find ours, then save its index. local Levels = require("map/levels") for i,level in ipairs(Levels.custom_levels) do if level.id == "BOSSFIGHT" then self.data.slots[self.current_slot].modes.bossfight.options = { level_id = i } print("Found a bossfight level:",i) break end end self:Save(cb) end self:SaveCurrent(ongamesaved) endAnd I don't see exactly what puts you in the new level there. Tbh I didn't really dive into the mod yet so I might immediately find something in another file. I should just not ask question before trying to really answer them myself first... EDIT: Also I just want to use "CAVE" for the walls and the darkness, but I guess that is not closely linked to the level type so I might as well use "CUSTOM"It's a bit confusing, because control switches back and forth to the engine, so you can't really track the execution flow just by reading the code. Ipsquiggle's post on Heavenfall's thread about a lava cave mod would be a good place to start (that's how I learned it). You don't need to override game files to do any of that (U&A doesn't override any game files ;P). And you don't need to do any of what StartBossfight does if you're using a cave level, you'd just call SaveIndex.EnterCave.The really important part is in scripts/prefabs/shadowportal.lua (within OnActivate_GoTo). You can see that it passes a callback to StartBossfight, which is run after the game saves. That callback causes the game to "reset" (to start the "next instance", in particular starting from a fresh new global environment), and the engine sends the execution flow to gamelogic.lua. From there you can track what's going on, just note that the entries in the table passed to StartNextInstance get copied to the global table Settings (see DoResetAction in gamelogic.lua for how it affects the execution flow). Link to comment Share on other sites More sharing options...
Malacath Posted November 14, 2013 Share Posted November 14, 2013 @simplexOkay, that is quite some information, thanks ^^Knowing myself though I will not understand all implications here until I try (?and fail?) to code that. I'll bookmark your post for sure so I have some lead when I will try it, should come to that sometime in the next few weeks. That will probably also be the time when I try to grasp what is different for the "CUSTOM" level type.If you're okay with me coming back to you/this forum(which will probably also lead to you again) then I'll do that. But we can also finish this discussion now until I understand what I'm doing ; ) The point is still that I would like to use a custom level rather than caves for not interferring with other mods. And as far as I can see EnterCave and StartBossFight have a similiar structure. So I would even go so far to write my own variant of StartBossFight to ensure I completely know what I'm doing. EDIT: I'm currently digging through this Link to comment Share on other sites More sharing options...
simplex Posted November 14, 2013 Share Posted November 14, 2013 @simplex Okay, that is quite some information, thanks ^^ Knowing myself though I will not understand all implications here until I try (?and fail?) to code that. I'll bookmark your post for sure so I have some lead when I will try it, should come to that sometime in the next few weeks. That will probably also be the time when I try to grasp what is different for the "CUSTOM" level type. If you're okay with me coming back to you/this forum(which will probably also lead to you again) then I'll do that. But we can also finish this discussion now until I understand what I'm doing ; ) The point is still that I would like to use a custom level rather than caves for not interferring with other mods. And as far as I can see EnterCave and StartBossFight have a similiar structure. So I would even go so far to write my own variant of StartBossFight to ensure I completely know what I'm doing. EDIT: I'm currently digging through this Sure, get back to me afterwards. I have to take a look at the custom level type myself, anyway. Link to comment Share on other sites More sharing options...
debugman18 Posted November 14, 2013 Share Posted November 14, 2013 No, cave levels are not chosen randomly. There are only two levels (in vanilla), organized by level number (1 for regular caves, 2 for ruins). Adding a new cave level would use another level number (3, unless other mods are doing the same), which wouldn't be used because the cave_entrance only increments the level number until 2. But I have to check what exactly are the details for the CUSTOM level type, because last time I dug into the worldgen code it didn't exist, and for some reason its introduction was not announced in any update notes...Yeah, I don't remember seeing CUSTOM as a leveltype, either. Only adventure, survival, and cave... Link to comment Share on other sites More sharing options...
simplex Posted November 14, 2013 Share Posted November 14, 2013 Yeah, I don't remember seeing CUSTOM as a leveltype, either. Only adventure, survival, and cave... I'm absolutely certain it didn't exist yet when we were fiddling with this kind of stuff. It's worth a look. I just wonder why there was no announcement of it. Link to comment Share on other sites More sharing options...
Malacath Posted November 15, 2013 Share Posted November 15, 2013 In case you missed it, the Maxwell fight is a cool example of using the Tiled to make a new level. It's also a really cool boss fight . http://steamcommunity.com/sharedfiles/filedetails/?id=194499642So you're saying this is a great example for the use of Tiled but oyu don't provide us with the Tiled file? That's not fair : PI'm currently stuck a this since my layout refuses to work. I'm simply not getting spawned there even though I have the spawnpoint put there in Tiled. And I also get those disturbing Streets crossing over and going over the ocean like magic xDBut anyways, getting the spawn up and running is priority right now, so can you maybe provide the Tiled file for us to take a look at? Would be much appreciated. Side not: My code is fine, really the layout is the problem because replacing only my layout with the maxwell layout will yield good results. Link to comment Share on other sites More sharing options...
simplex Posted November 15, 2013 Share Posted November 15, 2013 @MalacathYou should put something like this {"start_setpeice", "BeanstalkTop"}, {"start_node", "BeanstalkSpawn"},in the overrides table of the level definition to specify the spawn set piece and room. Link to comment Share on other sites More sharing options...
Malacath Posted November 15, 2013 Share Posted November 15, 2013 @MalacathYou should put something like this {"start_setpeice", "BeanstalkTop"}, {"start_node", "BeanstalkSpawn"},in the overrides table of the level definition to specify the spawn set piece and room. That sounds like a good start. But then again, the maxwell fight doesn't have it and it works. Also my mod works with the maxwell layout, and I'm really only replacing the file path, nothing else.EDIT: Also, a setpiece is a room or a layout? Link to comment Share on other sites More sharing options...
simplex Posted November 15, 2013 Share Posted November 15, 2013 That sounds like a good start. But then again, the maxwell fight doesn't have it and it works. Also my mod works with the maxwell layout, and I'm really only replacing the file path, nothing else. EDIT: Also, a setpiece is a room or a layout? I guess there's a way to specify it in the map itself in the case of a completely static map, but I wouldn't know how. The way I posted would be the way to do it in the case of a procedurally generated map, but I see no reason why it wouldn't work here as well. And a set piece is a (static) layout. A room is a biome. Link to comment Share on other sites More sharing options...
Malacath Posted November 15, 2013 Share Posted November 15, 2013 I guess there's a way to specify it in the map itself in the case of a completely static map, but I wouldn't know how. The way I posted would be the way to do it in the case of a procedurally generated map, but I see no reason why it wouldn't work here as well.And a set piece is a (static) layout. A room is a biome.Okay, perfect, thanks. I will try as soon as possible. And by the way, I am making a completely static map similiar to the maxwell fight and I had to find out that even in the maxwell fight there seems to be more procedurally generated landmass far away where you usually can't see it.EDIT: Worked perfectly well, I can just create immense amounts of water around the island to create the feel of an isolated thing. No I'll just need to figure things out like changing waves, ground textures... I think U&A should be a great place to steal some code : PBut enough for today, I'm extremely tired... Nonetheless I'd still be interested in that Tiled file. Link to comment Share on other sites More sharing options...
greenglacier Posted November 16, 2013 Share Posted November 16, 2013 Pretty cool. Love! Link to comment Share on other sites More sharing options...
Malacath Posted November 16, 2013 Share Posted November 16, 2013 @simplex So it seems to me that I need to create a new world prefab to be able to add new waves, because the override for waves only considers "off" as a valid input.I sifted through the U&A forums for what seemed ages to me and I cannot find where you spawn the "cloudrealm" as the world entity. So, I think my question is apparent... How can I link a new world to my level? Link to comment Share on other sites More sharing options...
simplex Posted November 16, 2013 Share Posted November 16, 2013 @simplex So it seems to me that I need to create a new world prefab to be able to add new waves, because the override for waves only considers "off" as a valid input.I sifted through the U&A forums for what seemed ages to me and I cannot find where you spawn the "cloudrealm" as the world entity. So, I think my question is apparent... How can I link a new world to my level?Doesn't just setting new wave parameters override the previous settings? In U&A we use a custom world entity mostly for efficiency (and because this is much more manageable than having to undo a lot of settings in the cave prefab), since listing common prefabs as dependencies for the world entity speeds things up considerably (look as prefabs/forest.lua and prefabs/cave.lua for examples of the game doing that), but it is only relevant if you're adding a lot of custom prefabs.If using a custom world entity really is the only way to achieve custom waves, we use a devilish trick for it:do local oldSpawnPrefab = _G.SpawnPrefab function _G.SpawnPrefab(name) if name == "cave" and Pred.IsCloudLevel() then name = "cloudrealm" end return oldSpawnPrefab(name) endendThe logic in the detection behind Pred.IsCloudLevel() is not that simple, but for a single level it shouldn't be hard to check whether we're in it or not.And oh, mentions are not working. For the time being, it's better to use quotes (even if you're quoting the empty string ;]). Link to comment Share on other sites More sharing options...
Malacath Posted November 16, 2013 Share Posted November 16, 2013 And oh, mentions are not working. For the time being, it's better to use quotes (even if you're quoting the empty string ;]).Really? I got a mention notification yesterday, did it still work then and just doesn't work now? Anyways, on-topic:I don't know yet if I will need a new world, but I didn't see a way to change waves other than that. I think I stupidly thought setting a new wave trexture will replace that wave texture everywhere irreversably... but I can just reset it... So I think that will not be necessary. If I need a custom world for something else I will remeber your sweet trick. But I'd also really like understand why it works, specifically what that "do...end" notation does. But if I want to remove things like "birdspawner" from my world and leave that world I will have a new world enitity which will have thw "birdspawner" again, right? So removing stuff from the world when entering my new world doesn't break anything? Link to comment Share on other sites More sharing options...
simplex Posted November 16, 2013 Share Posted November 16, 2013 Really? I got a mention notification yesterday, did it still work then and just doesn't work now?It seems mentions are triggering notifications sometimes, though not often. I haven't received a single one in a while, myself. Anyways, on-topic:I don't know yet if I will need a new world, but I didn't see a way to change waves other than that. I think I stupidly thought setting a new wave trexture will replace that wave texture everywhere irreversably... but I can just reset it... So I think that will not be necessary. If I need a custom world for something else I will remeber your sweet trick. But I'd also really like understand why it works, specifically what that "do...end" notation does.The do/end block is just to limit the scope of oldSpawnPrefab. What I'm doing is creating a closure, i.e. making oldSpawnPrefab accessible to the modded SpawnPrefab. While a local variable is still in scope, any function in that scope (which includes nested scopes) mentioning it in its body keeps a reference to that variable (in Lua jargon, oldSpawnPrefab is said to be an upvalue of the new SpawnPrefab). When the scope ends, the upvalue "closes", persisting as a shared reference to all function which have it as an upvalue. I explained a bit how upvalues work here, but since the code block was squashed into a single line I reproduce it here:do local upvalue = 1 function f() return upvalue end function g() upvalue = upvalue + 1 endendassert(upvalue == nil)g()assert(f() == 2)debug.setupvalue(g, 1, math.pi/2)assert(math.sin(f()) == 1)debug.setupvalue(g, 1, f)assert(f()()()() == f)The do/end is just a delimiter of scope, so I might as well have written:function h() local upvalue = 1 function f() return upvalue end function g() upvalue = upvalue + 1 endendh()or;(function() local upvalue = 1 function f() return upvalue end function g() upvalue = upvalue + 1 endend)()The leading semi-colon is just to avoid possible parsing ambiguities, since when you write something likea = b(function() print "hello"end)()the code is ambiguous (prompting the Lua interpreter to raise an ambiguity error), since it could also be interpreted as calling b as a function, i.e.a = b(function() print "hello"end)()The Lua manual has some info on that here, but just a bit. The book Programming in Lua, as well as the tutorials at lua-users.org, go into much more detail. The following is a diagram representing open vs. closed upvalues in Lua:It was taken from the article The Implementation of Lua 5.0, which remains largely relevant. But if I want to remove things like "birdspawner" from my world and leave that world I will have a new world enitity which will have thw "birdspawner" again, right? So removing stuff from the world when entering my new world doesn't break anything?A world entity is spawned per level, so any changes you make to it don't propagate to the other levels. You'd remove components from it just like from any other entity, by calling inst:RemoveComponent(). But some components may require additional work (such as calling inst:StopUpdatingComponent(), or cancelling tasks they created). Also, some parts of the game just assume some components are there in the world entity, which may lead to issues (the telelocator staff was a pain to deal with in U&A, since it assumes that if the world entity has the prefab "cave", then it has the Quaker component), so you may want to look for where the game references those components. Link to comment Share on other sites More sharing options...
Malacath Posted November 16, 2013 Share Posted November 16, 2013 [[...]]Wow, I didn't even mean that you should explain me, but it was certainly better than the explanations I found ^^ You're really my star on this forum. Also thanks for that clarification on the world prefab. It's actually really odd to me that removing a component would not include stopping its update... I always try to be extra careful when handling such core elements of the game as the world, even more so now. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.
Please be aware that the content of this thread may be outdated and no longer applicable.