Jump to content

[Tutorial] Adventure, add your own worlds


Recommended Posts

Hi,

I recently released the adventure mod (load preconfigured worlds in specific order one after the other), which is based on my teleportato mod:
Adventure Mode
Teleportato
This tutorial will tell you, how you can add either additional worlds for the adventure mod or even create your own adventure.
I will only explain how to use my mods as base, I wont explain how to create own tasks/rooms/setpieces, see existing mods for example code or use stuff that already exist in DST.

Basically you only need 2 things, to add your world to the loading order of teleportato:
in modworldgenmain:

Spoiler

 


local _G = GLOBAL
if not _G.TUNING.TELEPORTATOMOD then
    _G.TUNING.TELEPORTATOMOD = {}
end
if not _G.TUNING.TELEPORTATOMOD.WORLDS then
    _G.TUNING.TELEPORTATOMOD.WORLDS = {}
end				
local function AlwaysTinyCave(tasksetdata) -- even if cave was enabled, make it always very tiny, cause we dont need it
    tasksetdata.tasks = {"CaveExitTask1"}
            tasksetdata.numoptionaltasks = 0
            tasksetdata.optionaltasks = {}
            tasksetdata.set_pieces = {}
            tasksetdata.valid_start_tasks = {"CaveExitTask1"}
            tasksetdata.overrides={
                world_size  =  "small",
                wormhole_prefab = "tentacle_pillar",
                layout_mode = "RestrictNodesByKey",
                }
    return tasksetdata
end				
local function SampleForestWorld(tasksetdata) -- A Cold Reception
    tasksetdata.numoptionaltasks = 4
    tasksetdata.tasks = {"Make a pick","Easy Blocked Dig that rock","Great Plains","Guarded Speak to the king",} -- always have this tasks
    tasksetdata.optionaltasks = {"Waspy Beeeees!","Guarded Squeltch","Guarded Forest hunters","Befriend the pigs","Guarded For a nice walk","Walled Kill the spiders","Killer bees!",
        "Make a Beehat","Waspy The hunters","Hounded Magic meadow","Wasps and Frogs and bugs","Guarded Walrus Desolate",} -- choose randomly numoptionaltasks from this list
    tasksetdata.set_pieces = { -- adfine some setpieces and where they should spawn
            ["ResurrectionStoneWinter"] = { count=1, tasks={"Make a pick","Easy Blocked Dig that rock","Great Plains","Guarded Speak to the king",}},
        }
    tasksetdata.required_setpieces = {} -- this makes it empty, so also deletes DST settings for this.
    tasksetdata.numrandom_set_pieces = 0
    tasksetdata.random_set_pieces = {} -- this makes it empty, so also deletes DST settings for this.
    tasksetdata.add_teleportato = true -- add teleportato within teleportato mod. ypu can set up _G.TUNING.TELEPORTATOMOD.teleportato_layouts to change the setpieces of them
    tasksetdata.overrides={
        world_size  =  "default",
        day  =  "default",
        season_start  =  "default",
        deerclops  =  "default",
        dragonfly  =  "default",
        bearger  =  "default",
        goosemoose  =  "default",
        antlion = "default",
        hounds  =  "default",
        mactusk  =  "default",
        leifs  =  "default",
        trees  = "default",
        carrot  =  "default",
        berrybush  =  "default",
        wormhole_prefab = "wormhole",
        layout_mode = "LinkNodesByKeys",
        start_location = "default",
        autumn = "default",
        winter = "default",
        spring = "default",
        summer = "default",
        keep_disconnected_tiles = true,
        no_joining_islands = true,
        no_wormholes_to_disconnected_tiles = false,
        has_ocean = true,
        -- see more settings in scripts\map\customise.lua
    }
    return tasksetdata
end				
table.insert(_G.TUNING.TELEPORTATOMOD.WORLDS, {name="Sample World", taskdatafunctions={forest=SampleForestWorld, cave=AlwaysTinyCave}, defaultpositions={2,3,4}, positions="2,3,4"})

 


This is some sample code.
The last line adds the SampleForestWorld with name "Sample World" to the WORLDS list. This list will be used within teleportato mod, when loading the world.

table.insert(_G.TUNING.TELEPORTATOMOD.WORLDS, {name="Sample World", taskdatafunctions={forest=SampleForestWorld, cave=AlwaysTinyCave}, defaultpositions={2,3,4}, positions="2,3,4"})


name is a custom name to identify your world. It should be unique and will be shown in the title of the world.
In taskdatafunctions you put the worldgen functions for forest and cave. If you dont want to change eg. cave, just make it nil instead.
defaultposition and position define at which chapter your world should/can be loaded. An adventure has in total 7 chapters: Prologue, chapter1-5, Epilogue.
positions is for use with modsettings, it is a string, because we can not used lists within modinfo. users should be able to set it to different values.
defaultposition is a list made by you, it is only used if one position/chapter got no world (eg. because user set all worlds to "2" or so, and no worlds for the other chapters).
The last fallback, if also defaultpositions fail, you should define this fallback within modworldgenmain:

-- in case the positions choosen by usr and also defaultpositions chosen by level creator fail to assign one unique level to every chapter, use this fallback level list:
_G.TUNING.TELEPORTATOMOD.LEVEL_LIST_FALLBACK = {"Maxwells Door","King of Winter","A Cold Reception","Archipelago","Two Worlds","Darkness","Checkmate"}

simply enter 7 (the number of chapters) names of your worlds. This is only necessary if you create your own adventure. If you rely on my adventure mod, you dont need it since the advenutre mod already defines it.

Of course you can define several worlds and add them to the list within one mod (like I did in adventure mod)


Now about the SampleForestWorld function. It will receive the tasksetdata (via AddTaskSetPreInitAny in teleportato mod), which includes all the forest data set from DST. We will change/overwrite this tasksetdata to design our own world instead.

Lets first talk about the easiest part, tasksetdata.overrides:
These are mostly the worldsettings you can set up ingame, like daylenght, seasons and so on.
You can read all possible settings and values within scripts\map\customise.lua.
You always have to declare wormhole_prefab and layout_mode, all other values are optional and will be default if not set.
Unfortunately I dont know a way to only change some of them and let the rest unchanged.

Then we have tasks and setpieces. You can imagine tasks as an area with predefined content, but kind of randomly generated.
And setpieces are 100% predefined collection of things, eg. used for the teleportato parts and base and others.
You can find some default values of this in scripts\map\tasksets forest.lua and caves.lua and also in scripts\map\levels forest.lua
The world will always include every task in "tasks", but will choose randomly from the optionaltasks list numoptionaltasks times.
You can also add random setpieces with random_set_pieces list and numrandom_set_pieces (works the same like optionaltasks).
Use required_setpieces list if you want a setpieces to spawn with 100% chance in a random area.
You can find a list of all already existing tasks and setpieces in: scripts\map\tasks (eg forest.lua) and scripts/map layouts.lua.
With these already existing tasks/setpieces and the overrides you can already create your own interesting worlds, by combining them in your own way.

I added the entry "tasksetdata.add_teleportato" , which you can set to true/false. If it is true, my teleportato mod will automatically add the teleportato parts/base in random areas. if you want your own setpieces for them you can create a list _G.TUNING.TELEPORTATOMOD.teleportato_layouts["forest"] and put your setpieces=layouts into it (see adventure mod for example). You can also set add_teleportato to false and add the tele setpieces/parts yourself, if you want them to spawn in specific location.
And if you are a real expert, you can use ordered_story_setpieces to spawn them, but I dont know how this works, but it is used for the DS adventure to make sure you always find the base last. I guess you have to add story-values to your tasks or something like this.
So if you are no expert, the best is to simply set tasksetdata.add_teleportato to true and you are fine.

Important:
The game may already fill some of the lists like tasks or optionaltasks or random_set_pieces with its content. If you want to remove this and only add your own, simply overwrite the list. But if you want to keep previous content and only add your stuff to it, use:
table.insert(tasksetdata.tasks,"yourtaskname")
or to add setpieces (the table looks a bit different, so we can not use table.insert)
tasksetdata.set_pieces["mysetpiecename"] = {count=x,tasks={...}}

I can't tell you how to create your own tasks/setpieces/rooms, because I dont know everything about it and it would be too much. Simply study the game code and you will find out. But even with the existing stuff, you can already create nice worlds.

Some sample mods:

Thats all about creating your own world! :)

 

I also added 2 functions to modmain:
-- functionatplayerfirstspawn(player) -- will be executed for every players first spawn and can eg. be used to spawn some starter items or lit some fires around him and so on.
-- functionpostloadworldONCE(world) -- will be executed at world start ONCE (only the first time directly after generating the world).  eg. you could add some stuff around startposition
-- in addition you can use AddPrefabPostinit in your modmain, but LEVEL and CHAPTER will need ~0.1 seconds to be set, so do DoTaskInTime within your AddPrefabPostInit if you need them! (only continue after _G.TUNING.TELEPORTATOMOD.LEVELINFOLOADED was set to true by teleportato mod)
To not overwrite thsese functions for other mods, you should do:

Spoiler

		local _G = GLOBAL
		if not _G.TUNING.TELEPORTATOMOD then
		    _G.TUNING.TELEPORTATOMOD = {}
		end
		local functionatplayerfirstspawn = _G.TUNING.TELEPORTATOMOD.functionatplayerfirstspawn -- save already exisiting functions from other mods
		local functionpostloadworldONCE = _G.TUNING.TELEPORTATOMOD.functionpostloadworldONCE -- save already exisiting functions from other mods
		_G.TUNING.TELEPORTATOMOD.functionatplayerfirstspawn = function(player) -- called for server and client
		    if functionatplayerfirstspawn~=nil then -- call a previous function from another mod, if there is one
		        functionatplayerfirstspawn(player)
		    end
		    -- now do your stuff. it should be save to use LEVEL and CHAPTER, since it was already loaded
		end
		_G.TUNING.TELEPORTATOMOD.functionpostloadworldONCE = function(world) -- only called for server and after everything is loaded
		    if functionpostloadworldONCE~=nil then -- call a previous function from another mod, if there is one
		        functionpostloadworldONCE(world)
		    end
		    -- now do your stuff. it should be save to use LEVEL and CHAPTER, since it was already loaded
		end


More explanation/tips:

  • you can use _G.TUNING.TELEPORTATOMOD.LEVEL and _G.TUNING.TELEPORTATOMOD.CHAPTER to get the current level/chapter in your modmain, but only use them after the game was initilaized (_G.TUNING.TELEPORTATOMOD.LEVELINFOLOADED will then be true).
  • Level is the number of chosen map. There can be unlimited maps. starts at 1
  • Chapter: starts at 1. max number is 7. ->Only 7 maps are randomly chosen from the level list (depending on their positions values)
  • for testing you can do TheWorld.components.adventurejump:DoJump() within console
  • to see what overrides you can choose for your world, see scripts\map\customise.lua
  • mods can add their worlds to the WORLDS list, so players could also use several such mods and the teleoprtato mod will choose randomly between those levels to fill the chapters.
  • those mods must load before the teleportato mod, so priority must be higher than 8888 (no clue why I chose this value)
  • add_teleportato at caves will only add the parts here. the base will always be at mastershard (forest), only forest will have the worldjump component, so only forest should have a teleportato_base.
  • currently it only supports two worlds: forest and cave, but you can change them to your liking. If you want to add more worlds with different names, the teleportato mod code has to be adjusted, although I already made sure to use "forest" and "cave" as less as possible.
  • do not use "_G.TUNING.TELEPORTATOMOD.LEVEL == x" within your code, use instead _G.TUNING.TELEPORTATOMOD.WORLDS[_G.TUNING.TELEPORTATOMOD.LEVEL].name=="mylevelname"
  • The Maxwell-stuff you see in my adventure currently belongs to the adventure. So only with this mod active, there will be maxwell. If you dont want to add worlds to the adventure, but create your own adventure, you currently wont have a maxwell. If you still really want it, tell me and I will see what I can do.

 

Edited by Serpens
  • Thanks 1
Link to comment
Share on other sites

How to save your custom mod data for teleportato worldjumping (so eg save recipes of player and load them again after the new world was generated. In case of recipes this is already done in teleportato mod, but you can add your custom mod data this way):

Simply put code like this into your modmain:

-- ##################
-- example usage of saving and loading data from other mods when worldjumping/after worldjumping with teleportato
-- ##################
local functionsavewithteleportato = GLOBAL.TUNING.TELEPORTATOMOD.functionsavewithteleportato
GLOBAL.TUNING.TELEPORTATOMOD.functionsavewithteleportato = function(player) -- called for server
    local mods_data = {}
    if functionsavewithteleportato~=nil then -- call a previous funtion from another mod, if there is one
        mods_data = functionsavewithteleportato(player)
    end
    mods_data["myuniquemodname"] = player.components.mycomponent:OnSave() -- you can use onsave, or use other values from your mod, to save them
    return mods_data
end

AddPlayerPostInit(function(player)
    player:ListenForEvent("teleportatojumpLoadData", function(player,mods_data) -- load the mods_data
        if mods_data~=nil and mods_data["myuniquemodname"]~=nil and GetModConfigData("mysettingname") then -- you can add a modsetting if sth should be loaded or not
            player.components.mycomponent:OnLoad(mods_data["myuniquemodname"])
        end
    end)
end)
-- ##################
-- ##################

 

Edited by Serpens
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...