Jump to content

[Documentation] Understanding Prefabs


Hornete
 Share

Recommended Posts

Understanding Prefabs

If you’ve taken a look at the game's source code, or even saw people just talking about modding in general, you’ve probably heard the term “Prefab”.

But what is a prefab? Well, to say it most simply. A prefab is like a blueprint the game reads to create an entity. The game might be asked to spawn a “rabbit” prefab. So it checks to see the “rabbit” prefab data and reads it as if it is a blueprint to construct a “rabbit” entity. Nearly every other entity in the game works like this. There are prefabs for characters, mobs, bosses, items, structures and pretty much everything!

Prefab("acorn", fn, assets, prefabs)

Prefabs are created through the Prefab class(as seen in the code snippet above). There are 4 main parameters to the class. The first parameter is the name of the prefab, the second parameter is the constructor function for the prefab. This function handles the creation of the prefab when the game tries to spawn it in. The third parameter is a table of assets that are used for the entity. This is necessary to define so the game can load in those assets so that the prefab is able to use them. The 4th parameter is a table of other prefabs, so they may be loaded in/ready to be used when our prefab needs them.

The constructor functions for prefabs generally look something like this:

local function fn()
      local inst = CreateEntity()

	--Code here is run on the server AND clients

      if not TheWorld.ismastersim then
	return inst
      end

	--Code here is run ONLY on the server side

      return inst
end

 

An entity is created by calling the CreateEntity function which is then assigned to a local variable named “inst” (Short for Instance). If you look at some prefabs in the game (Prefabs can be found in the Dont Starve Together/data/databundles/scripts/prefabs folder) you will commonly see snippets of code like these.
 

inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddSoundEmitter()
inst.entity:AddNetwork()

Right after the inst variable is assigned. These C functions(functions that are defined in the game engine) are extremely fundamental bases for pretty much every entity in the game. AddTransform allows your entity to have an x, y, and z position in the world, have a rotation and able to be scaled, AddAnimState allows your entity to have an animated model, AddSoundEmitter allows your entity to emit and play sounds, AddNetwork is necessary for networking the entity to clients. There are much more C functions like these (AddPhysics, AddMiniMapEntity, AddLight) which you can find being used in other prefabs.

After client and server data is initialized(C functions, etc) we reach this check

if not TheWorld.ismastersim then
	return inst
end

This is just a simple check to see if it’s the client or server side running this code. If it’s the client we return the inst variable. This is because the code ahead is meant for only the server and should not be run on the client, so we make sure only the server side is passing ahead.

Now we are on the server-side of the constructor function where code that only affects the server-side is added and other things like components will be added. What are components? I plan to make a separate post for them but to summarise components are things that an entity can do. For example the “acorn” prefab (Birchnuts) can be looked at, is an inventory item, can be stacked, can be cooked, can be eaten, can be planted. So components are added to the prefab like the “inspectable”, “inventoryitem”, “stackable”, “cookable”, “edible”, “deployable” components. These help to accomplish the things we might want the entity to do. There are tons and tons of components in the game that all do different things. They can be found in the Dont Starve Together/data/databundles/scripts/components folder.

That’s a basic explanation of how the constructor function for prefabs works. I urge you to check out the constructor functions of prefabs in the game and see how they work and what they do to accomplish their mechanics and features! But now let’s talk about how assets tables are defined.


The assets table will contain instances of the “Asset” class. The Asset class will generally look something like this:

Asset(“ANIM”, anim/acorn.zip”)

The first parameter is the type of asset we’re loading in. Is it an animation? If so, then its “ANIM”, is it an image? Then it’s “IMAGE”, if it’s an atlas, “ATLAS” and so on. There are many types of asset types and those can be found just by scouring through the game’s lua code and see how some instances of the Asset class name their asset types.

The second parameter is the file path to the asset we’d like to load in. Simple enough.

local assets = {
      Asset(“ANIM”, anim/acorn.zip”),
      Asset(“ANIM”, anim/pinecone.zip”),
}

The game will then initialize and load in the assets you have put in the assets table and now you’re able to use them in the game! If you try to use an asset that hasn’t been put in an assets table, and thus hasn’t been loaded in, then simply nothing will happen, if you’re trying to use a unloaded visual asset your entity will simply just appear invisible, trying to use an unloaded sound will result in no sound at all coming out, etc.

 

Let’s talk about the last and final thing in the Prefab class, the prefabs table! Now, to be honest i’m not completely sure how the prefabs table works and what it’s used for. But I believe the prefabs table is used to load in prefabs ahead of time that are used for our prefab. For example, a perishable food item might need to put “spoiled_food” (the prefab name for rot) in their prefabs table so the game can know that this prefab is needed for when the food item spoils and rot needs to be put in place of the food item.

So the prefabs table for a perishable food item would look like this

local prefabs = {
	spoiled_food”,
}

Fairly simple, and you can add as many prefabs as you want. The prefabs table isn’t necessary, prefabs can work without it, but it seems to help in some way so i’d recommend making sure you have one. (If your custom prefab isn’t linked to any other prefabs in any way then you can leave it blank).

 

And that’s how prefabs and the Prefab class is defined! I hope you found this documentation useful in some way, i’m a bit worried i’m not explaining some parts in enough detail or even if I'm maybe over explaining things. If you have any feedback or questions please let me know/ask away! I hope to make posts on understanding components, brains, stategraphs and UI some time soon : )

  • Like 11
  • Thanks 3
  • Big Ups 2
Link to comment
Share on other sites

If you're worried about not explaining things in enough detail or in too much detail, I recommend using spoiler tags to compress some information that seems like it'd be a lot of detail. 

This way people who would like to know more can read up on things, while those who would just like to take a small peak can keep the flow of reading going.

Awesome work by the way!

 

  • Thanks 1
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...