Jump to content

[Help] World Generation: Rooms


Asiru

Recommended Posts

Hello!

I'm currently developing a Don't Starve mod, and I'm proficient in Java.  However, I'm still quite green to Lua and I'm completely inexperienced in world generation.  From what I've heard, what I'd like to do seems possible.  I want to be able to install the mod, and when generating a new world with the mod, it creates two "rooms" (I believe they're called).

One of the rooms is a custom prefab surrounded by some floor tiles and vanilla prefabs, very similar to the graveyard, beefalo pen, or any of the Things' set pieces.  The other room is simply a custom prefab randomly dropped in the wilderness, much like the generation of Chester's eyebone (except it doesn't spawn the most adorable creature known to all mankind when picked up).

I'm not sure where to put the code for this (or what code), where to look for examples, or how to spawn custom prefabs an exact relative distance away from the others.  Anything you could say to point me in the right direction would be greatly appreciated!

Thanks so much in advance! :)

Link to comment
Share on other sites

Both of these don't necessarily require "rooms". The first one is, as you even said yourself, a set piece (or static layout) that can be spawned by force-adding it to the level (this is the easier approach) or by adding a custom tag to some or all worldgen tasks (see scripts/map/maptags.lua for reference). The second prefab can be spawned when the world loads for the first time (probably what you want for "exact relative distance"), or you could spawn it just like the eyebone using maptags.

On a side note: Level is the entire map, Task is a landbranch, Room is loosely predetermined area in a task, Setpiece is a specific layout and is used for boons and, say, the ruins labyrinth alike.

Many mods use setpieces. Take a look at mine for instance.

@Asiru

Link to comment
Share on other sites

I've made some progress, and two more questions have risen if you don't mind answering them.  When I first got the set piece to work, it spawned nine of them around the whole map.  Could you give me some details about only letting the world generator spawn one?  Another thing, I'm building my set piece in Tiled, and I'm spawning in marble pillars.  Is there a way I can spawn half-broken pillars?  In the Object Properties window, there seems to be an empty list of properties and values, and I'm kinda assuming it has to do with that.

Thanks again!

@Mobbstar

Link to comment
Share on other sites

@Asiru you can find how I did it in my mods "Industrial Resolution" and "Soulful Alchemy". I hope I correctly extracted all important code: (remember to change the setpiece name)

require("map/tasks")
require("map/level")
require("map/levels")

local tasklist = GLOBAL.tasks.sampletasks
local task_names = {}

for _, task in pairs(tasklist) do
	-- Leave the usual starting task out
	if task.id ~= "Make a pick" then
		table.insert(task_names, task.id)
	end
end

AddLevelPreInitAny(function(level)
    -- Try to only spawn on the surface and not in adventure mode
    if GetTypeForLevelID(level.id) == LEVELTYPE.SURVIVAL then
        if not level.set_pieces then
            level.set_pieces = {}
        end
        level.set_pieces["SETPIECE_ID"] = { count = 1, tasks = task_names }
    end
end)

As for changing the worked-ness, you'll find that rocks and such are set not to remember their state. You can give the objects in Tiled the attribute "data.components.workable.workleft" to change their state when initially loaded and use a "PrefabPostInit" in modmain to change the "remember state" boolean in the pillars:

AddPrefabPostInit("marblepillar",function(inst)
inst.components.workable.savestate = true
end)

 

Link to comment
Share on other sites

@Mobbstar  I apologize for my lack of experience, I was unable to find my answers by fiddling or searching so please bear with me. :)  The set piece spawns once, and correctly, save for one detail.  I could be doing it wrong, but I followed the instructions you provided to generate pre-broken marble pillars and the pillars generate non-broken.

This is a screenshot of the object properties for one of the broken marble pillars:

Spoiler

ENuqvFF.png

I'll settle for it being impossible, but is there anything else that might cause this to work/not work?  Thanks for all the help so far!

Link to comment
Share on other sites

This is my fault, the thing should be called data.workable.workleft I think. Some of the games setpieces change wall health the same way.

(Again, you need to also change the Marble Pillars in general to remember their state (using PrefabPostInit), else this would be pointless)

Link to comment
Share on other sites

Hmm, it's strange.  I did some digging as well, and what you said seems like it should work, but I can't seem to get these pillars to break.  Could it be possible to add a sort of dummy property in Tiled, and check for it in the PrefabPostInit?

Link to comment
Share on other sites

11 hours ago, Asiru said:

Hmm, it's strange.  I did some digging as well, and what you said seems like it should work, but I can't seem to get these pillars to break.  Could it be possible to add a sort of dummy property in Tiled, and check for it in the PrefabPostInit?

I forgot that they won't visually change on their own either, you'd have to add that to the PrefabPostInit (taken from prefabs/marblepillar.lua):

if inst.components.workable.workleft < TUNING.MARBLEPILLAR_MINE*(1/3) then
	inst.AnimState:PlayAnimation("low")
elseif inst.components.workable.workleft < TUNING.MARBLEPILLAR_MINE*(2/3) then
	inst.AnimState:PlayAnimation("med")
else
	inst.AnimState:PlayAnimation("full")
end

If that doesn't help, you might find hints in scripts/map/graphnode.lua

Link to comment
Share on other sites

Alright, so.  After generating the world, the pillars look fully intact.  To make sure it really was just a visual thing, I hit them all with a pickaxe once, and they played the animation I wanted them to be showing after generation.  So I had to assume it was something about the animation I had wrong.  To poke even further, I commented out the "...savestate = true" line, and tested again...with the same results.  Tested again, completely commenting out the modmain.lua, and the same thing happens again.

It looks like simply putting the data in the static layout script is enough to give it that workleft (I tried setting the workleft to 1, and the pillar behaved as expected - dropping marble and disappearing after one hit of the pickaxe, even though it displayed the "full" animation).  I really don't even have any evidence to support that the PrefabPostInit is being run at all.

Link to comment
Share on other sites

6 hours ago, Asiru said:

I really don't even have any evidence to support that the PrefabPostInit is being run at all

add the following line if you want to check if code runs:

print("Running PrefabPostInit for:".. inst .."\t You can read these messages in the in-game log using CTRL+L or in log.txt")

"savestate" is so after save/loading, the state doesn't reset.

Link to comment
Share on other sites

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.

×
  • Create New...