TUG Lua modding guide (TUG Alpha 0.6.3)

tullrichtullrich REGISTERED, Developers Posts: 10 Developer
edited August 2014 in Mods
Lua Modding 101

Modding is an important part of Nerd Kingdom's vision for TUG. We try to build much of our tech with modders and modding in mind. To that end our Lua scripting api has been slowly built up over the last few patches, and we have now released the initial revision of the official documentation, found at http://eternusapi.nerdkingdom.com.

Below is a simple quickstart guide to adding scripted content to TUG.

Making a GameObject.txt

The simplest way to mod TUG is to create new objects in the world for the player to interact with. We do this by adding simple text files into the AssetsDataGameObjects directory. You should be able to find the assets folder next to your TUG.exe.

Let's define a GameObject called Magic Wand in the file TUG/Assets/Data/GameObjects/EquipableObjects/MagicWand.txt:
GameObjects
{

	Placeable
	{

		Magic Wand
		{
			
			StaticGraphics
			{
				model ="Models/PlaceableObjects/Harvestables/woodStaff.obj"	
				dontCastShadows = 1.0				
				Diffuse
				{
					0 = "Character/Weapons/0spearB_WLV_New_diff.tga"
				}
				Normal
				{
					0 = "Character/Weapons/0spearB_norm.tga"
				}				
			}
			
			RigidBody
			{
				activePhysics = 1
				mass = 15.0
				friction = 6.0
			}
		}
	}
}

The first thing that we see here is a section entitled "GameObjects" and another nested section entitled "Placeable", these tell the engine that what follows defines a new object that can appear in the world. The next section "Magic Wand" is where our new object's definition begins, in here we specify the different components that makeup its representation.

The first section "StaticGraphics" adds a StaticGraphicsComponent that gives our object a model and assigns a few Diffuse and Normal textures. There are few other rendering properties this component can provide, but for now this is all we need.

The next component is a RigidBodyComponent which allows this object to exist in the physics simulation and provides a mass and friction. The activePhysics flag indicates that this object will be placed in a dynamic state.

Now, when we run TUG and enter a world, we can use the /spawn "Magic Wand" command to plop down an instance of our new object. We can also use /spawn "Magic Wand" 20 to drop a couple more.

T8IAuNsl.png
LypP8TJl.png


Making our wand slightly more magical.

You might have noticed by now that you can't actually pick up the wands, and that they are certainly not doing anything magical... they are mostly just laying there. If yours ARE doing anything magical at this point, please file a bug report.

So lets redesign our text file and make our wand do something:
GameObjects
{

	Placeable
	{

		Magic Wand
		{

			StaticGraphics
			{
				model ="Models/PlaceableObjects/Harvestables/woodStaff.obj"	
				dontCastShadows = 1.0				
				Diffuse
				{
					0 = "Character/Weapons/0spearB_WLV_New_diff.tga"
				}
				Normal
				{
					0 = "Character/Weapons/0spearB_norm.tga"
				}
			}
			
			RigidBody
			{
				activePhysics = 1
				mass = 15.0
				friction = 6.0
			}

			Equipable
			{
				name = "Magic Wand"
				icon = "UI/MenuIcons/2x_ShroomStem.tga"
				resource = 1
				durability = 1
				damageToCharacters = 1

				
				Equipment Slots
				{
					Tool
				}
			}

			Script
			{
				file = "Scripts/Objects/Wand.lua"
				class = "Wand"

            arguments
				{
				}

			}
		}
	}
}

Above we can see that there are two new components attached to the wand. First is an EquipableComponent, this is a natively implemented component that allows the player to pick up and equip this item into his hand. It will also make this item appear in the Creative Mode inventory. The data here provides an inventory name, an icon, and marks this item as a resource that the player can collect. There are many more fields that can appear here that can give this equipment a lot of different behaviors without writing any script at all (deal damage, increase move speed, etc.). You can find a few examples of these fields in Data/GameObjects/Tools/Crude Axe.txt and others in that folder.

While the EquipableComponent might get our Wand off the ground and into our hand, it won't provide us with the magical behavior that we want. For that we need to add some custom logic. We do this via a ScriptComponent. Here the referenced script Wand.lua is loaded by the engine which registers a new script class Wand, which in turn becomes the script class of this gameobject. The arguments field allows us to pass initial values to our Wand’s constructor, our simple class won’t even need a constructor so we’ll just leave this field blank.

Let’s take a look at TUG/Scripts/Objects/Wand.lua
include("Scripts/Objects/Equipable.lua")

-------------------------------------------------------------------------------
-- Define a new script class Wand that derives from Equipable.
if Wand == nil then
	Wand = Equipable.Subclass("Wand")
end

-------------------------------------------------------------------------------
-- Evaluate if this wand has any effect on a target object 'go'.
-- Overridden from Equipable.
function Wand:CanToolAffectObject( go )
	return true
end

-------------------------------------------------------------------------------
-- Called when this wand is swung at a valid object.
-- Overridden from Equipable.
function Wand:AffectObject( hitObj )
	Eternus.GameState:SpawnGameObject("Goat",   hitObj.gameobject:NKGetWorldPosition(), hitObj.gameobject:NKGetWorldOrientation())
	traceResult.gameobject:NKDeleteMe()
end

-------------------------------------------------------------------------------
-- Register the Wand class with the engine so it can be referenced in our MagicWand.txt. 
EntityFramework:RegisterGameObject(Wand)

Here we are looking at the script that will be attached to our Magic Wand. TUG Lua scripts make use of an OOP framework that allows us to reuse existing logic. We define a new script class Wand that subclasses a different script class Equipable. This provides our wand with some pre-existing logic shared between all Equipables.

First we override an equipable function CanToolAffectObject that is called when this item is swung at another object. We always return true here indicating that our Wand affects everything!

Next we override another equipable function AffectObject which implements exactly what our wand should do when we strike another object. Here the code spawns another GameObject called “Goat”, and destroys the object that we struck. Seems simple enough.

Finally we have one more bit of code necessary to use this script, we must call RegisterGameObject to inform the engine of our newly created class.

When we boot up TUG, we can now play with our new Wand:

WholeAcclaimedIraniangroundjay.gif

Adding some flavor.

Finally, you might have noticed the wand in the above video is a bit more vibrant than the one you created. I’ve added a few particle effects near the tip of the object.

Here is what my completed MagicWand.txt now looks like:
GameObjects
{

	Placeable
	{

		Magic Wand
		{
			
			StaticGraphics
			{
				model = "Models/PlaceableObjects/Harvestables/woodStaff.obj"	
				dontCastShadows = 1.0				
				Diffuse
				{
					0 = "Character/Weapons/0spearB_WLV_New_diff.tga"
				}
				Normal
				{
					0 = "Character/Weapons/0spearB_norm.tga"
				}				
			}
			
			
			RigidBody
			{
				activePhysics = 1
				mass = 15.0
				friction = 6.0
			}

			Equipable
			{
				name = "Magic Wand"
				icon = "UI/MenuIcons/2x_ShroomStem.tga"
				durability = 10
				damageToCharacters = 1

				Equipment Slots
				{
					Tool
				}
			} 

			Script
			{
				file = "Scripts/Objects/Wand.lua"
				class = "Wand"

				arguments
				{
				}
			}
			
			Children
			{

				Wisp Purple Body Emitter
				{
					offset = <2, 0, 0>
				}
				Wisp Green Ribbon Emitter
				{
					offset = <2, 0, 0>
				}
			}
		}
	}
}


The only addition is the section entitled Children. This is a special section that does not add any components to the object, but instead attaches entirely distinct GameObjects to our wand. These child objects will stay attached to the wand when it moves in our gameworld. I’ve attached two objects, a Wisp Purple Body Emitter and a Wisp Green Ribbon Emitter. Both of which are GameObjects with their own set of components. You can find their definitions in Wisp Green Emitter.txt and Wisp Purple Emitter.txt found in the Assets/FX/Emitters/Swarm directory near your TUG.exe.

The offset property allows me to position them relative to the origin of my wand. Here I've placed them right at the end of the stick.

5Mzmh7Il.png
oWZmUsil.png

Things to look forward too.

Modding is really important to us here at Nerd Kingdom and we have number of things that we would like to provide the community in the future.
* Full documentation for the lua exposed native functions (anything prefixed with NK). The initial draft can be found at http://eternusapi.nerdkingdom.com.

* Easier distribution and installation of mods. Right now modders must work directly in the Asset/ directory. We are working on a solution that would allow modders to add and modify content in the game within their own mods folder. This system will also allow many mods to be installed and managed at once.

* Scripted server and client gameplay. The script we wrote today will only work in a single player environment. Future scripting APIs will allow modders to write both client and server logic.

* Full scripting control of the GUI allowing simple modifications and complete overhauls.



If you would like the Wand without doing any work, I've attached both files (MagicWand.txt and Wand.lua) inside the zip below. Simply navigate to your TUG install directory and place them at TUG/Assets/Data/GameObjects/EquipableObjects/MagicWand.txt and TUG/Assets/Scripts/Objects/Wand.lua

Comments

  • PamcakesPamcakes REGISTERED, Moderator Posts: 738 Seed
    Very important! Very awesome! Very cool! Thanks for taking the time to show the modding community this. I'll help share the thread to the modders I know. :D
    That's a really cool shirt you have on.
  • SigilSigil REGISTERED, Developers Posts: 678 Developer
    Break rock, spawn goats.

    I promise not to abuse this.
  • The ArcanianThe Arcanian REGISTERED Posts: 51 Seed
    HAHA! API, now to do cool things... after the next patch. :D
    Nerd? You say that like it's an insult.

    Please excuse any bad spelling...
  • ZakeZake REGISTERED Posts: 216 Seed
    Yay! Now time to find a mod concept that isn't already planned by NK.
    I think more than I say and say more than I do, but I do more than I used to and plan to continue.
    TUG modder (at least in the ounce of free time that occasionally flits by)
  • TeknonickTeknonick REGISTERED Posts: 166 Seed
    Cool, look's like I was on the right track! I was making a Crystal Tools mod, and pretty much figured it all out on my own. All I have to do so far is fix the bug that makes regular rocks look like crystal rocks (wtfudge?) and figure out how to make some cheap models... and find someone who can actually texture. xD
    The mix between the Adventurer and the Trapper yields the Tracker. Living in humble homes to help those in need. Always looking for the right coin, yet never theft is in their eyes.
    21.jpg
    20.jpg
  • Youngy798Youngy798 REGISTERED Posts: 905 Seed
    I have a question. Ive been working on a custom sword:

    lCnV95X.png

    Would it be possible to have an effect where there is a hovering wisp inside the centre of the carved out circle? I want to have a dark blue wisp which is kind of moving very slightly inside the circle.
    Hello there! I am Youngy future owner of Plainhold (hopefully), go read the topic about Plainhold, and the Lemurian Empire, maybe also some of my other posts, like my mining suggestions! :)

    Bye!
  • SigilSigil REGISTERED, Developers Posts: 678 Developer
    Youngy798 wrote:
    I have a question. Ive been working on a custom sword:

    Would it be possible to have an effect where there is a hovering wisp inside the centre of the carved out circle? I want to have a dark blue wisp which is kind of moving very slightly inside the circle.

    You're dealing with particles here. copy the torch code in the data file and change out the type of particles by copying from the wisp data file. then just offset until it fits.
  • Youngy798Youngy798 REGISTERED Posts: 905 Seed
    Thanks Sigil :D I still need to create a high poly sculpt and texture for this (its going to be stone). I will post it as a downloadable mod if I ever finish it
    Hello there! I am Youngy future owner of Plainhold (hopefully), go read the topic about Plainhold, and the Lemurian Empire, maybe also some of my other posts, like my mining suggestions! :)

    Bye!
  • ZakeZake REGISTERED Posts: 216 Seed
    Are custom crafting recipes possible yet? I tried adding a dummy recipe to turn two "Orange" into a "Red Apple" in .AssetsDatacrafting.txt but it took the two oranges and didn't give an apple. Also didn't see anything in the Eternus docs but it seemed like something that could be done outside the api. Thoughts?

    On another note, musing through the documentation it looks like we can't yet add animals and such through the API. Perhaps in the next update when the predators come around?
    I think more than I say and say more than I do, but I do more than I used to and plan to continue.
    TUG modder (at least in the ounce of free time that occasionally flits by)
  • nocarenocare REGISTERED, Tester Posts: 92 Seed
    Custom recipes are possible. You most likely just have the wrong spelling or something. I haven't tested if case is a factor, but I camelCase so as to fit the standard of the api.
    For instance, for testing, my bow item is crafted with one "Vines".

    I thought about investigating the spawn code, because sigil added those geckos and I'm sure they could be spawned along side goats.....
  • ZakeZake REGISTERED Posts: 216 Seed
    Looks like where we really want to be is in the Community/Mods forum. A lot of people have been posting there. With regards to the spawn code, that's something I wanted to look into as well; the crafting was just the first thing I tried. From what I've seen from the devs, Sigil, and the Lua scripts, the code seems to only be set up for one animal. I would expect the next update to really allow us to spawn in animals and such.

    It's funny, at every update I find myself playing and thinking, I'll try it again at the next update, should be more playable then. I can definitely see monumental difference though. We seem to be quite limited at the moment but I think another couple updates down the road we can start doing some amazing things in the mods.
    I think more than I say and say more than I do, but I do more than I used to and plan to continue.
    TUG modder (at least in the ounce of free time that occasionally flits by)
  • tullrichtullrich REGISTERED, Developers Posts: 10 Developer
    Hey Zake,

    You should be able to add crafting recipes via the .AssetsDatacrafting.txt- I'm not sure why yours didn't work. If you want to post exactly what you added I'd be happy to help troubleshoot it.

    As an aside, the recipe modding has undergone a huge overhaul in the upcoming patch. Recipes may be added to the game via independent files (so we don't have a number of modders editing crafting.txt!), and all of the effects of crafting has been moved into Lua. This means that you can script custom logic for when a recipe's requirements have been met, such as complex interaction with a crafter table. You are also provided a hook for when crafting succeeds, which should enable recipes to do far more than just spawning a GameObject.

    If your recipe requires a recently stoked fire and upon success spawns 20 mobs to attack the player, this system will totally enable you write that. =P

    @Youngy798: You absolutely can! Checkout the "Addings some flavor" part of the guide in this post. You will need to add a Children section to your .txt file. Inside this you can put a bunch of child GameObjects that will be attached at a specified point. Checkout Assets/Data/GameObjects/Characters/Wisp/Wisp.txt and you can see the child objects that make up the death wisp.
    			Children
    			{
    				Wisp Blue Body Emitter
    				{
                   offset = <0, 0, 0>
    				}
    
    				Wisp Blue Tail Emitter
    				{
                   offset = <0, 0, 0>
    				}
    				
    				Wisp Blue Ribbon Emitter
    				{
                   offset = <0, 0, 0>
    				}	
    
    				Wisp Attractor
    				{
                   offset = <0, 0, 0>
    					emitter = "Wisp Blue Body Emitter"
    				}
            }
    

    Above is the part in question, and you should be able to copy and paste it into your swords text file. Play around with the offset and rotOffset to place the attachments relative to the exported origin of your model.
  • ZakeZake REGISTERED Posts: 216 Seed
    Thanks for the tips, tullrich. I'm trying to balance the urge to mod with the urge to wait for more support. I'll see what I can do with what's here now; I fear if I wait, all the good ideas will be taken. :roll: So far mostly I've just been poking around, seeing how it all works. Hopefully, my next post will be an actual mod. :D
    I think more than I say and say more than I do, but I do more than I used to and plan to continue.
    TUG modder (at least in the ounce of free time that occasionally flits by)
  • glitch2210glitch2210 REGISTERED Posts: 311
    Looks like its time to dust off the old programing skills and see if i cant start modding =D

    tumblr_nagb0tpdL61tji1iso1_500.png
  • LakkpoppLakkpopp REGISTERED Posts: 15 Seed
    Does this still work?
  • Red AgliatorRed Agliator REGISTERED Posts: 307 Seed
    Lakkpopp said:

    Does this still work?

    The general idea is the same, though some of the details are different. Off the top of my head, things that have changed since this was written:

    - the format for MagicWand.txt has changed slightly
    - adding custom recipes has changed (both the recipe.txt format and the lua you use to register the recipes)
    - the purple glow emitters are disabled in 0.8.4, though the blue versions still exist

    I don't know whether the steps with CanToolAffectObject has changed. (I didn't test that in the Lodestaff mod.) There are probably a few other differences that I haven't remembered.
  • LakkpoppLakkpopp REGISTERED Posts: 15 Seed
    Well, that explains why I never got it to work :P
    Somebody should have made an updated tutorial on modding, cause i think many peple wanna get started.

  • Red AgliatorRed Agliator REGISTERED Posts: 307 Seed
    Lakkpopp said:

    Well, that explains why I never got it to work :P
    Somebody should have made an updated tutorial on modding, cause i think many peple wanna get started.

    It'd be nice. Does that mean you want to write one up if you get help figuring out how to make it work?
  • johnycilohoklajohnycilohokla REGISTERED, Developers Posts: 283 Developer
    We are preparing few new tutorials.

    The tutorials will cover everything you will needed to start modding:
    Setting up the mod
    Folder structure
    Basic ModScriptClass
    Creating basic objects
    Adding new crafting recipes
    Chat commands

    There will also be few more advanced ones.
    My Blog
    jc.png
      yt.png  t.png  
  • LakkpoppLakkpopp REGISTERED Posts: 15 Seed
    edited May 2015

    Lakkpopp said:

    Well, that explains why I never got it to work :P
    Somebody should have made an updated tutorial on modding, cause i think many peple wanna get started.

    It'd be nice. Does that mean you want to write one up if you get help figuring out how to make it work?
    No, but maybe if my English was better.

Sign In or Register to comment.