Legend of Grimrock 1 Modding

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
User avatar
Sir Tawmis
Posts: 980
Joined: Mon Jul 30, 2012 8:15 am
Contact:

Re: Legend of Grimrock 1 Modding

Post by Sir Tawmis »

Creating Custom Assets
Using customized assets opens Legend of Grimrock for more in-depth modding than is possible by just using the Dungeon Editor. Using existing Grimrock assets as the basis and changing a few parameters to come up with new item or monster variants is relatively straightforward to do but if you want to take full advantage of the system it is possible for you to use your own graphics, animation and audio for creating a dungeon crawl experience that will look and sound completely different to Legend of Grimrock.

When you create a new project in the dungeon editor, a few folders and .lua files are created into the project’s location. Any .lua, .model, .dds, .animation, .wav or .ogg files within these folders will be packaged along with the dungeons when you export from the Dungeon Editor. Custom assets are defined using .lua scripts and the init.lua (under “mod_assets\scripts\” subfolder) will always be run when the custom dungeon is started. To refresh the changes made to these files, you can reload them in the editor from the File-menu using “Reload Project”. By default the init.lua will import a few other scripts (such as items.lua, monsters.lua as well as standard_assets.lua which contains all the original Legend of Grimrock assets) which serve as the basis for adding your own custom assets.

Note that any new graphics you add to your custom dungeon will consume extra memory so if you have a total conversion mod that doesn’t use any of the original Legend of Grimrock assets, it can be a good idea to comment out the line which imports the standard assets.

Defining a New Item
Let’s start off with something simple by cloning a pre-existing Legend of Grimrock asset. Let’s open the items.lua (which can be found under the project’s scripts subfolder) with a text editor and start off with a pre-existing weapon that we will modify slightly to get a new asset so that we can get familiar with how custom assets are handled. Let’s add the following to items.lua:

Code: Select all

cloneObject{
	name = "super_machete",
	baseObject = "machete",
	uiName = "Super Machete",
	attackPower = 12,
	damageType = "shock",
	description = "This machete radiates with strange energy.",
}
Using the cloneObject-function we can take an existing asset, in this case the machete, and create a new asset with new or changed parameters. Any parameters that we don’t define in cloneObject will be left in its original shape. For instance, we didn’t define a weight parameter so our new asset will still weight as much as the original asset did. So, let’s go through the changes we made to the original machete to come up with our new super cool super machete item!

Probably the most essential change to the parameters we made was the name: if we would have retained the original machete name, this item definition would have overridden the original machete item (which is completely fine if that is what you want to do). By changing the name to super_machete, we now have a new asset type instead which will show up in the Dungeon Editor’s asset browser after saving the .lua file and loading the project in the editor. The name parameter is only visible to the modder and the player will only ever see the uiName. You can safely change the uiName at any time but a little more consideration is needed if you want to change the name itself since the dungeon refers to the items by using this name and the dungeon (or its save games) won’t work if the objects spawned into it are not found.

To differentiate the super machete from the normal one, we increased its attack power and added the damageType = "shock", line to turn the damage dealt by the machete into electrical attacks. I also added a description for extra flavor. If you’re curious about what kinds of parameters you can add to items, or to the other assets, they can all be seen in the asset definitions reference. Of course, there’s nothing stopping you from completely changing the parameters of the object or even turning it into a magical staff or a food item but at that point it would be wise to change the graphics too which we will detail in the following guides.

Using Custom Graphics
Graphics in Legend of Grimrock come in a few different flavors. There’s 2D graphics, such as images for cinematics or item icons and then there’s 3D graphics that are used for item meshes, environment objects and monsters. 2D graphics are the more simple case by a wide margin so let’s start off with them.

2D graphics in Legend of Grimrock use DDS (DirectDraw Surface) format which can be saved from Photoshop and GIMP by using 3rd party plug-ins. Standalone converters are available as well. DDS supports compression which is recommended for textures that will be used on 3D models (use D3DFMT_DXT1 for textures without alpha and D3DFMT_DXT5 for textures with alpha) but user interface graphics, such as item icons, should be left uncompressed (use D3DFMT_A8R8G8B8). Mipmaps should be used with all textures and the dimensions of the textures should be to the power of two (16, 32, 64 …) to ensure compatibility.

Image

Let’s say we want to introduce some new item icons in the game. A single item icon is 75*75 pixels in size but we can keep several icons in a single texture (called an atlas texture). Thus, a 512*512 atlas texture, for example, can contain a grid of 6*6, or a total of 36, item icons in it as illustrated by the template image on the right (notice that there is also some padding on the edges since the size of 75 does not divide evenly to fill out the entire 512*512 texture). The item texture also needs an alpha channel for the transparency and, like mentioned earlier, the DDS should be uncompressed.

Once you have a texture with one or more icons in it, you can save the DDS to the textures-subfolder in your project folder and, for this example, let’s name the file “mod_items.dds”. Then all we need to do is to is to modify items.lua a little to make a custom item to use the new texture by adding gfxAtlas = "mod_assets/textures/mod_items.tga", to the item definition (when the gfxAtlas parameter is not defined for an item, it uses the default Legend of Grimrock item atlas). Note that forward slashes, instead of backslashes, are used in the path and that we replaced the .dds with .tga. But don’t rename the file itself: we here at Almost Human use .tga as an intermediate format (which we then automatically convert to DDS which the game engine uses) and the formatting of the item definitions follow this convention. To put it simply: keep the file as a .dds but use .tga in its stead in the item definition.

Now, since the atlas texture is sliced into grid cells of 75*75 size, we just need to pick the right index number for the icon. If you placed the icon graphics into the top left slot, its index is 0 and the slot to the right from it is 1 and so on. Once you have located the right index number, we can replace the number for the gfxIndex parameter in the item definition and now everything should be in place and the new icon is good to go.

3D objects
3D objects in Legend of Grimrock are built out of a few components: a 3D model, material definitions and (optionally) animations. The models and animations use custom file formats (.model and .animation) and we don’t provide exporters for these files (since there are just too numerous software packages out there for us to support) but instead, we provide the specifications for these formats that should enable the community to create plug-ins or converters for creating the assets. The materials for the 3D models are defined by scripting.

When creating 3D models, it is advisable to collapse the mesh into a single object unless it has animated moving parts.

The animation files are separated from the models to make it easier to update the 3D model without needing to re-export all the animations. Each animation file contains the data for a single animation only: for example monsters have separate .animation files for turning left and right and pit trapdoors have separate animations for opening and closing.

The material definitions can be made in the materials.lua script file. The materials are very simple in Legend of Grimrock:

Code: Select all

defineMaterial{
	name = "spider",
	diffuseMap = "assets/textures/monsters/spider_dif.tga",
	specularMap = "assets/textures/monsters/spider_spec.tga",
	normalMap = "assets/textures/monsters/spider_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 40,
	depthBias = 0,
}
For most assets, the only parameters you need to modify are name, texture maps and sometimes glossiness. A lower glossiness value means more diffuse/softer specular highlights and higher values produce more glossy/sharper highlights and the values we used were usually in the range of 20-80. The specular map, however, is more important for the overall feel of the material: this texture defines the amount of specular as well as its color (if you want to make the whole object less shiny overall, just make the texture darker). You can also leave any of these textures undefined (just delete or comment out the line). Leaving a diffuse or specular map undefined produces the same result as using a blank white texture. For materials with alpha, it is recommendable to use alpha test (also known as “alpha clip”) since alpha blend is not lighted correctly and therefore the material may appear too bright in dark surroundings.

These materials are referred by their name from models/meshes and there can be more than one material per object. In our pipeline we defined the materials by using material names in the 3D modeling software (so if I would have defined the polygons in my object to use a material with the name “moose”, a material definition of the same name would be used from materials.lua in the game) but the exact way how materials are assigned may vary depending on how the exporters or converters will handle it. It is also possible to override materials that the standard assets use (just define a new material with the same name) so if you want to create an albino snail, it is possible to do it without touching the 3D model itself.

Probably the easiest approach to getting started in creating new assets that use new 3D objects would be to take a pre-existing asset definition from the Legend of Grimrock asset pack and to start replacing its models and animations in its definition with new files one by one and checking that it still works after each new addition.

Note that in the asset definitions you frequently need to refer to asset names using .tga or .fbx file extensions even though your files actually need to actually have .dds, .model or .animation file extensions. Tga and fbx are intermediate formats we use here with our asset pipeline and the asset definition file names follow this convention. So you shouldn’t rename your actual files as .tga or .fbx but in the asset definitions you need to replace any .model with .fbx and any .dds with .tga. It’s a little counterintuitive but the system was built on how our in-house asset pipeline and automatic asset conversion system works.

Audio
When creating custom sounds, care needs to be taken when choosing the correct formats. The looping background soundscape is an .ogg-file but all the other samples are 16bit 44100Hz .wav-files. You need to be careful that you use the correct sampling rate and bit depth since other values might work on your computer but not on other platforms.

When creating sounds that are played from the 3d environment (like monsters or spells), the samples need to be mono so that they can be panned correctly according to the position of the source of the sound. Sounds for things that do not come from the environment, such as interface sounds etc., can be in stereo.
Define ... 'Lost.' Neverending Nights - The Neverwinter Machinima that WILL make you laugh!
Also read: Legend of Grimrock: Destiny's Chance here on the forum! Check out the site I made for Legend of Grimrock: Destiny's Chance.
User avatar
Sir Tawmis
Posts: 980
Joined: Mon Jul 30, 2012 8:15 am
Contact:

Re: Legend of Grimrock 1 Modding

Post by Sir Tawmis »

Scripting Hooks
Scripting hooks are Lua functions that can be added to asset definitions. Hooks can be used to extend and customize behavior of assets that support hooks. Hooks are called when certain events occur in the engine and before the corresponding action is executed. Most actions can be cancelled by returning false from the hooks. For example, the onPickUpItem hook in Party class is called when an item is about to be picked up. If the hook returns false, the pick up action is cancelled.

For example, the following script when placed in dungeon’s init.lua will add onMove and onTurn hooks to party class:

Code: Select all

cloneObject{
   name = "party",
   baseObject = "party",

   onMove = function(self, dir)
       print("party moves in direction", dir)
   end,

   onTurn = function(self, dir)
       print("party turns", dir)
       return false -- returning false cancels the action, so the party is unable to turn!
   end,
}
See Asset Definition Reference for supported hooks.
Define ... 'Lost.' Neverending Nights - The Neverwinter Machinima that WILL make you laugh!
Also read: Legend of Grimrock: Destiny's Chance here on the forum! Check out the site I made for Legend of Grimrock: Destiny's Chance.
User avatar
Sir Tawmis
Posts: 980
Joined: Mon Jul 30, 2012 8:15 am
Contact:

Re: Legend of Grimrock 1 Modding

Post by Sir Tawmis »

How to Create Hatching Spider Eggs
In this how-to we’ll take a look at how we can create spider eggs which, when destroyed, spawn a spider. With this tutorial we’ll get to know how scripting hooks work in practice and how to pass parameters to functions in other script entities. I hope you’re prepared to take your scripting skills to the next level!

First, let’s create a clone of the spider eggs asset by adding this to the objects.lua under your custom dungeon’s “mod_assets\scripts” folder with a text editor:

Code: Select all

cloneObject{
	name = "spider_eggs_hatching",
	baseObject = "spider_eggs",
	onDie = function(object)
		eggScript.breakEggs(object.level, object.x, object.y)
	end,
}
We clone a new asset based on the old spider eggs and add a new function into its onDie scripting hook (for all the hooks, see the asset definition reference). Scripting hooks can be used to run any Lua script when a certain event happens (in this case when the eggs break) and it can be used in creating customized item and prop functionality or even altered monster behavior.

We could implement the whole script here but to make iterating the script faster, we’re going to refer to a script in the dungeon instead: to refresh the changes from objects.lua, the project needs to be reloaded whereas script entities in the dungeon can be instantly refreshed. To do this, we refer to a function called breakEggs in an script entity with the ID of eggScript. We also pass a few parameters to the function: the level and coordinates of the object being killed so that we can spawn the spider into the correct location.

This was just the first half of the work. To get the rest of it up and running, we now need to switch back to the dungeon editor (but remember to save the objects.lua and reopen the project in the dungeon editor!). Let’s start off by adding a few of our new spider_eggs_hatching entities to the map, as well as a script_entity whose ID we set to eggScript. Into this script entity, we will implement what actually happens when the eggs are smashed:

Code: Select all

function breakEggs(level, x, y)
	local facing = (party.facing + 2)%4
	spawn("spider", level, x, y, facing)
end
It’s a pretty short and simple script since we essentially need to do one thing only: to spawn a spider where the eggs were. To get the spider to the correct location, we use the parameters we passed from the onDie-hook in the spawn command. To spice it up a little, we also set his facing parameter to always automatically face the player by using a small math trick: the facing values go from 0 (north) to 3 (west) so by adding 2 to the facing of the player party, we can essentially rotate the spider by 180 degrees. After the addition the range of the numbers is 2…5 so we use modulo (the % operator) to put the values back into the range of 0…3.

This script will print a warning on console about an invalid spawn location when the eggs are broken. This is due to the fact that the onDie event happens right before the eggs are destroyed (since the event needs to be able to also prevent the object from being destroyed if necessary) so the spiders are very briefly on top of the eggs. However, we know that the eggs will be gone so we know the overlapping entities won’t cause any problems and thus we can safely ignore the warning.

And there you have it: actual working spider eggs that hatch. It’s easy to take this script and adapt it into, for example, a stack of barrels and crates (barrel_crate_block) from where you could find some randomized loot with increasingly rare items found on lower floors by referring to the level parameter of the object.
Define ... 'Lost.' Neverending Nights - The Neverwinter Machinima that WILL make you laugh!
Also read: Legend of Grimrock: Destiny's Chance here on the forum! Check out the site I made for Legend of Grimrock: Destiny's Chance.
User avatar
Sir Tawmis
Posts: 980
Joined: Mon Jul 30, 2012 8:15 am
Contact:

Re: Legend of Grimrock 1 Modding

Post by Sir Tawmis »

How to Create Cinematics

Cinematics in Legend of Grimrock are simple slideshow-like sequences. Currently they can be used only in the beginning and the end of a dungeon. The game looks for a file called intro.lua under your “mod_assets\cinematics” folder and, if it is found, it is played back when the game is started. Ending cinematics can be started by using the completeGame() -function and giving the filename as its parameter, for example: completeGame("mod_assets/cinematics/ending.lua"). You can actually even make multiple endings to the dungeon if you have different completeGames that the player can accomplish, each of which refers to a different cinematics file. Do note that cinematics are not played back while in the editor so you need to export the dungeon to test it out in the game itself.

Cinematics are Lua-scripts that the game reads from top to the bottom and with the script you can display images and fade them in and out, print text to the screen and play music. Let’s start off with something simple and create a cinematic with just a single image in it that fades in and out while some music plays in the background:

Code: Select all

-- simple one image cinematic
enableUserInput()
startMusic("assets/samples/music/intro.ogg")

-- show the image
showImage("assets/textures/cinematic/intro/page01.tga")
fadeIn(2)
sleep(4)
fadeOut(4)
In the first line we enable the user input (clicking with the mouse or using the keys on a keyboard) so that the player can skip the cinematic if he wants to. The startMusic-line should be pretty self explanatory. Here we use pre-existing music from Grimrock but if you would want to use your own, you could place the file in your sounds-folder and alter the line to read startMusic("mod_assets/sounds/my_music.ogg").

The last four lines are where the juicy stuff happens! This is where we first start drawing the image using the showImage-function (if you would want to use your own pictures here, they need to be in DDS-format: take a look at the custom asset guide for instructions) but at this point it is not actually visible yet since we need to fade in the picture too using the fadeIn() function. The function takes a number as its parameter which tells, in seconds, how long the effect should last. If you want the image to pop in immediately, you can use 0.

The sleep-command just pauses the playback for four seconds after the fade-in is completed and then, in the end, we just fade out the picture again. You could follow this up with another picture, for example, by using the same showImage-fadeIn-sleep-fadeOut structure if you want to but what we’re gonna try out next is to add some texts into our cinematic!

Code: Select all

-- cinematic with a title and story text
enableUserInput()
startMusic("assets/samples/music/intro.ogg")

showImage("assets/textures/cinematic/intro/page01.tga")
fadeIn(2)

-- show the title text
sleep(1)
setFont("IntroTitle")
showText("The Sinister Bannister", 3)
sleep(2)
fadeOutText(1)

-- show the story text
sleep(1)
setFont("Intro")
textWriter([[
Some folks call it the Evil Railing. Or the Vile Balustrade.
However, no matter what you decide to call it, it is certain that
the Sinister Bannister is an ancient source of distraught and ill fortune.

You must venture forth and disassemble the nefarious inanimate object!
]])
click()
fadeOutText(0.5)

fadeOut(4)
fadeOutMusic(3)
Alright, let me break down what is going on in this script so it’s easier for you to tell what each line of the script is trying to accomplish:

Enable input and start the music
Fade in the background image
Show the title text and fade it out
Print the story text on screen and wait for the user to click and then fade it out
Fade out the background image and the music
I think you should now be able to see for the most part what is happening. If you’re not familiar with Lua, the multiline string might be a new thing for you. We could have accomplished the same with formatting it using the more familiar quotation marks and line breaks like this:textWriter("This is the first line.\nAnd this is the second.") but for long chunks of text, the multiline string is much clearer to read. I also added a fadeOutMusic() function to the end so that the audio won’t cut off abruptly.

And this is essentially all that you need to know to create cinematics of your own. If you place the above script into a “mod_assets/cinematics/intro.lua” file under your custom dungeon’s folder and export the dungeon, you should have a nifty new intro cinematic you can start modifying to tell a story of your own (because I’m totally keeping the tale of the Sinister Bannister as my own)!
Define ... 'Lost.' Neverending Nights - The Neverwinter Machinima that WILL make you laugh!
Also read: Legend of Grimrock: Destiny's Chance here on the forum! Check out the site I made for Legend of Grimrock: Destiny's Chance.
User avatar
Sir Tawmis
Posts: 980
Joined: Mon Jul 30, 2012 8:15 am
Contact:

Re: Legend of Grimrock 1 Modding

Post by Sir Tawmis »

Asset Definition Reference
This document is intended as a reference to asset definition scripts. The focus is on completeness rather than brevity. Refer to the tutorials for more detailed examples on how to use the material described here.

The Lua functions described here follow the “define*” naming convention and they can be accessed from your dungeon’s init scripts. All assets must be created when loading the dungeon. It is not possible define assets after the dungeon has been initialized.

Basic Terminology
A 3d vector refers to an object returned by the global function vec. For example, a new 3d vector can be created with vec(1,2,3).

A valid asset reference means a filename that starts with either “assets/” or “mod_assets/”. Filenames starting with “assets/” are assets that are contained in the main game’s data archive grimrock.dat. Files starting with “mod_assets/” are included and packaged with your mod when the dungeon is exported from the Dungeon Editor.

The following file types are supported:

*.lua containing Lua source code in text format,
*.dds texture files containing textures in DDS format,
*.model files containing 3d models in a custom file format,
*.animation files containing animation data in custom file format,
*.wav files containing sound effects in wave format and
*.ogg files containing background music.
Animation Events
defineAnimationEvent{…}
Defines a new animation event. Animation events are used to trigger footstep sounds and attack methods for monsters. The function takes the following named parameters:

animation: the filename of the animation to attach the event to. The filename must be a valid asset reference ending with “.fbx”.
event: an event name to attach. Typical event names used are “footstep”, “attack” and “ranged_attack”.
frame: a frame number in the animation to attach the event to (one frame equals 1/30th of a second).
Dungeon Objects
cloneObject{…}
Clones an existing object and overrides its properties. The function takes the following unnamed parameters:

name: the name of the new object to define.
baseObject: the name of the base-object to clone.
Additionally any number of override parameters can be added. The list of additional parameters that can be added depends on base-object’s class. See defineObject() for a details about supported properties for each class.

For example, the following script will define a new type of spider with an overridden move sound and increased health.

Code: Select all

cloneObject{
	name = "strange_spider",
	baseObject = "spider",
	moveSound = "snail_walk",
	health = 250,
}
defineObject{…}
Defines a new dungeon object or replaces an existing object definition. It is recommended to use cloneObject() if you want to change only a few properties of an existing object. The function takes the following named parameters:

name: the name of the object to define or replace.
class: the class name of the object.
model: the filename of the model for rendering. The filename must be a valid asset reference ending with “.fbx”.
editorIcon: index of the icon in Dungeon Editor.
The remaining parameters depend on the class of the object as follows.

Alcove:

replacesWall: a boolean, if true the alcove model replaces the entire wall model. Typically set to true.
anchorPos: a 3d vector specifying the item anchor position in model’s local space.
anchorRotation: a 3d vector specifying the item anchor rotation in model’s local space.
targetPos: a 3d vector specifying the center position of the click box in model’s local space.
targetSize: a 3d vector specifying the extents of the click box.
placement: must always be set to “wall”.
onInsertItem: a hook which is called when an item is being placed on the alcove. The function receives two parameters: the alcove itself and the item being placed. If the function returns false, the alcove rejects the item.
Altar:

anchorPos: a 3d vector specifying the item anchor position in model’s local space.
anchorRotation: a 3d vector specifying the item anchor rotation in model’s local space.
targetPos: a 3d vector specifying the center position of the click box in model’s local space.
targetSize: a 3d vector specifying the extents of the click box.
placement: must always be set to “floor”.
Blockage:

brokenModel: the filename of the model that is swapped in when the blockage is destroyed.The filename must be a valid asset reference ending with “.fbx”.
health: the amount of damage it takes to destroy the blockage.
evasion: the evasion statistic of the blockage. Usually set to something very small, such as -1000.
hitSound: the name of the sound to play when the blockage is hit.
hitEffect: the name of the particle system to play when the blockage is hit.
repelProjectiles: a boolean, if set the blockage pushes all projectiles out from blockage’s square on impact.
placement: must always be set to “floor”.
onDamage: a hook which is called when the blockage is damaged. The function gets the following parameters: the blockage itself, amount of damage and the damage type (e.g. “physical”, “fire”, etc.). If the function returns false, the blockage receives no damage.
onProjectileHit: a hook which is called when a projectile hits the blockage. The function gets the following parameters: the blockage itself, the projectile which hit the blockage, amount of damage and damage type. If the function returns false, the blockage receives no damage and the projectile drops to ground.
onDie: a hook which is called when the blockage is destroyed. The function gets one parameter, the blockage itself. If the function returns false, the blockage is not destoyed.
Blocker:

This class has no additional properties.
Button:

pressAnim: the filename of the button press animation. The filename must be a valid asset reference ending with “.fbx”.
replacesWall: a boolean, if true the button model replaces the entire wall model. Typically set to true.
placement: must always be set to “wall”.
Counter:

This class has no additional properties.
Crystal:

animation: the filename of the spinning animation. The filename must be a valid asset reference ending with “.fbx”.
particleSystem: the name of the particle system to play when the crystal is spinning.
placement: must always be set to “floor”.
Decoration:

replacesWall: a boolean, if true the decoration model replaces the entire wall model.
replacesFloor: a boolean, if true the decoration model replaces the entire floor model.
placement: either “floor”, “ceiling” or “wall”.
Door:

doorFrameModel: the filename of the door frame model. The filename must be a valid asset reference ending with “.fbx”.
pullChainModel: the filename of the door pullchain model. The filename must be a valid asset reference ending with “.fbx”.
pullChainAnim: the filename of the door pullchain animation. The filename must be a valid asset reference ending with “.fbx”.
openSound: the name of the sound to play when the door is opened.
closeSound: the name of the sound to play when the door is closed.
lockSound:the name of the sound to play when the door locks into place after opening or closing.
killPillars: a boolean which removes pillars next to the door frame. Typically this is set to true.
openVelocity: door opening velocity in metres/second.
closeVelocity: initial door closing velocity in metres/second.
closeAcceleration: door closing acceleration in metres/second^2.
sparse: a boolean which controls whether items can be picked through the door.
placement: must always be set to “wall”.
onOpen: a hook which is called when the door is opened. The function gets one parameter, the door itself. If the function returns false, the action is cancelled.
onClose: a hook which is called when the door is closed. The function gets one parameter, the door itself. If the function returns false, the action is cancelled.
FX:

This class has no additional properties.
Item:

uiName: the name of the item as display to the player.
model: the filename of the model for rendering. The filename must be a valid asset reference ending with “.fbx”.
gfxIndex: index of the item graphics in texture atlas.
gfxAtlas: filename of the texture atlas containing the item icon. The filename must be a valid asset reference ending with “.tga”.
slot: (optional) a protective inventory slot where the item can be inserted. Must be one of the following: “Head”, “Torso”, “Legs”, “Feet”, “Cloak”, “Neck”, “Gauntlets”, “Bracers”
armorSet: (optional) the name of armor set where the item belongs to.
reachWeapon: a boolean flag which enables reach attacks with melee weapons from the back row.
throwingWeapon: a boolean flag which indicates that the item is a throwing weapon.
rangedWeapon: a boolean flag which indicates that the item is a ranged weapon, i.e. a weapon that shoots ammo items.
shield: a boolean flag which indicates that the item is a shield.
stackable: a boolean flag which enables stacking.
key: a boolean flag which indicates that the item is a key.
scroll: a boolean flag which indicates that the item is a scroll.
sharpProjectile: a boolean flag which causes the item to get stuck to monsters on impact.
treasure: a boolean flag which indicates that the item is counted as a treasure.
consumable: a boolean flag which indicates that the item can be consumed.
nutritionValue: the amount of food gained when the item is consumed.
potion: a boolean flag which indicates that the item is a potion. Potions are turned into empty flasks when consumed.
container: a boolean flag which indicates that the item can hold other items.
containerType: must be one of the predefined values: “sack”, “chest”, “mortar”.
capacity: the maximum number of items that can be placed in the container.
torch: a boolean flag which indicates that the item is a torch.
fuel: fuel for torches in seconds.
ammo: the type of ammunition needed by a ranged weapon.
ammoType: the ammunition type of the item.
bombType: causes the item to explode on impact. Must be one of the following: “fire”, “frost”, “shock”, “poison”.
bombPower: attack power for exploding bomb.
attackPower: attack power bonus for weapons.
accuracy: accuracy bonus for weapons.
protection: projection bonus for armors.
evasion: evasion bonus for projective gear.
energy: energy bonus.
strength: strength bonus.
dexterity: dexterity bonus.
vitality: vitality bonus.
willpower: willpower bonus.
resistFire: fire resistance bonus.
resistCold: cold resistance bonus.
resistShock: shock resistance bonus.
resistPoison: poison resistance bonus.
damageType: (optional) damage type. Must be one of the following: “physical”, “fire”, “cold”, “shock”, “poison”.
coolDownTime: cool down time in seconds.
weight: weight in kilograms.
skill: the weapon skill to use when attacking.
requiredLevel: the number of skill points needed to use the item.
armorSkill: (optional) armor skill that is required to use the armor. Must be either “light_armor” or “heavy_armor”.
attackMethod: the method to be called when the item is used. Must be one of the following: “meleeAttack”, “throwAttack”, “rangedAttack”, “castWandSpell” or “castRuneSpell”.
spell: the spell to be cast for wands or the spell explained by a scroll.
wandPower: the power of spell for wands which roughly corresponds to attack power of melee weapons.
charges: number of charges for wands.
emptyItem: the name of the empty version of the item which the item is swapped to when charges run out.
attackSwipe: the swipe effect to be played when attacking with the item. Must be one of the following: “vertical”, “horizontal”.
attackSound: the sound effect to be played when attacking with the item. Typically set to “swipe”.
impactSound: the sound effect to be played when the weapon hits an obstacle such as a wall. Typically set to “impact_blade” or “impact_blunt”.
projectileRotationSpeed: the speed of rotation for projectile items.
projectileRotationX: rotation angle around x-axis in degrees for projectile items.
projectileRotationY: rotation angle around y-axis in degrees for projectile items.
projectileRotationZ: rotation angle around z-axis in degrees for projectile items.
description: the description of the item that is display in tooltips.
gameEffect: additional game effect description for tooltips.
scrambleText: text that is display using the scramble text effect in the tooltip.
glitterEffect: (optional) name of the particle system attached to the item model.
onUseItem: a hook which is called when the item is used (e.g. by right-clicking on it). The function gets two parameters: the item used and the champion who used the item. If the function returns true, the item is consumed when it is used.
onEquipItem: a hook which is called when the item is equipped, i.e. placed in an inventory slot. The function gets two parameters: the champion and inventory slot.
onUnequipItem: a hook which is called when the item is unequipped, i.e. removed from an inventory slot. The function gets two parameters: the champion and inventory slot.
Lever:

activateAnim: the filename of the lever activate animation. The filename must be a valid asset reference ending with “.fbx”.
deactivateAnim: the filename of the lever deactivate animation. The filename must be a valid asset reference ending with “.fbx”.
placement: must always be set to “wall”.
LightSource:

lightPosition: a 3d vector specifying the origin of the light source in entity’s local space.
lightRange: the range of the light source in meters.
lightColor: a 3d vector specifying the RGB color of the light source in range 0-1.
brightness: scales the intensity of the light source.
castShadow: a boolean which turns dynamic shadow rendering on and off.
flicker: a boolean which turns flickering effect on and off. Default is on.
particleSystem: (optional) name of a particle system to attach to the light source.
placement: must always be set to “floor”.
Lock:

height: y-coordinate of the lock from the floor.
placement: must always be set to “wall”.
MapMarker:

This class has no additional properties.
Monster:

model: the filename of the monster model. The filename must be a valid asset reference ending with “.fbx”.
meshName: the name of the monster mesh in the model file.
animations: a table of animations to load. The keys in the table corresponds to animation slots and values to animation filenames. Animation file names must be valid asset references ending with “.fbx”. The animations slots are: “idle”, “moveForward”, “turnLeft”, “turnRight”, “strafeLeft”, “strafeRight”, “attack”, “attack2”, “attackBack”, “attackMove”, “attackLeft”, “attackRight”, “turnAttackLeft”, “turnAttackRight”, “rushBegin”, “rushContinue1”, “rushContinue2”, “rushHit1”, “rushHit2”, “getHitFrontLeft”, “getHitFrontRight”, “getHitBack”, “getHitLeft”, “getHitRight”, and “fall”.
turnAnimSpeed: (optional) animation speed multiplier for turning animations.
attackAnimSpeed: (optional) animation speed multiplier for attack animations.
moveSound: the sound to play when the monster moves.
footstepSound: the sound to play when “footstep” animation event is triggered.
attackSound: the sound to play when the monster attacks.
impactSound: the sound to play when the monster’s attack hits.
hitSound: the sound to play when the monster attack hits the target.
dieSound: the sound to play when the monster dies.
rushBeginSound: the sound to play when the monster begins charging.
soundClipDistance: (optional) sound clipping distance in squares. Sounds are clipped off if the distance from the monster to the party is larger than sound clipping distance.
hitEffect: the name of the particle system to play when the monster is hit.
capsuleHeight: the height of the capsule used for placing hit particle effects.
capsuleRadius: the radius of the capsule used for placing hit particle effects.
collisionRadius: TODO
health: the health of the monster when it’s spawned.
sight: the sight range of the monster in squares.
allAroundSight: a boolean which indicates that the monster can see in all directions.
seeInvisible: a boolean which indicates that the monster can see invisible targets.
attackPower: the attack power of the monster’s attack.
rangedAttack: the ranged attack to perform when “ranged_attack” animation event is triggered. Must be one of the following: “lightning_bolt”, “lightning_bolt_greater”, “ice_shards”, “fireball”, “fireball_greater”, “poison_bolt”, “frost_arrow”.
movementCoolDown: TODO
flying: if set the monster can fly over pits.
coolDown: a table with two number values, the min and max cool down for monster’s attack in seconds.
noRecoilInterval: a table with two number values between 0 and 1, the fractional start and end values of monster’s “no recoil interval”, the span of time when monster’s attack animation can’t be interrupted.
protection: monster’s protection statistic
evasion: monster’s evasion statistic
immunities: a list of effecst the monster is immune to. Available immunities are: “poison”, “fire”, “cold”, “shock”, “backstab” and “assassination”.
exp: the amount of experience points awarded when the monster is killed.
lootDrop: a random loot table containing (chance,item) pairs. For example { 75, “snail_slice”, 25, “snail_slice” } indicates that there is a 75% chance of generating a snail_slice and an additional 25% chance of generating another snail_slice.
healthIncrement: the amount of health gained when the monster gains levels.
attackPowerIncrement: the amount of attack power gained the monster gains levels.
protectionIncrement: the amount of protection gained the monster gains levels.
brain: the AI class to use. Must be one of the following: “Melee”, “Ranged”, “HerderSmall”, “HerderBig”, “Ogre”, “SkeletonArcher”, “Goromorg”, “Tentacle”, “Uggardian”, “Crab”, “Slime”, “Warden”, “Cube”
particleSystem: (optional) particle system filename to attach to the monster.
particleSystemNode: (optional) the node in the monster model for attaching particle systems.
lightName: (optional) the node in the monster model for light attachment.
lightColor: (optional) a 3d vector specifying the color of the light carried by the monster.
lightBrightness: (optional) a scalar intensity of the light carried by the monster.
lightRange: (optional) the range of the light carried by the monster.
onMove: a hook which is called when the monster moves. The function gets two parameters: the monster itself and the direction it is moving, 0 = north, 1 = east, 2 = south, 3 = west. If the function returns false, the move is cancelled.
onTurn: a hook which is called when the monster turns. The function gets two parameters: the monster itself and the direction it is turning, -1 for counterclockwise and 1 for clockwise turns. If the function returns false, the turn is cancelled.
onAttack: a hook which is called when the monster attacks. The function gets two parameters: the monster itself and the name of the attack (e.g. “attack” or “attack_left”). Most monsters can only do frontal attacks. If the function returns false, the attack is cancelled.
onRangedAttack: a hook which is called when the monster performs a ranged attack. The function receives a single parameter, the monster itself. If the function returns false, the ranged attack is cancelled.
onDealDamage: a hook which is called when monster’s attack hits and deals damage. The function gets the following parameters: the monster itself, the champion receiving the attack and the amount of damage. If the function returns false, damage is not dealt to the target.
onDamage: a hook which is called when the monster is damaged. The function gets the following parameters: the monster itself, amount of damage and the damage type (e.g. “physical”, “fire”, etc.). If the function returns false, the monster receives no damage.
onProjectileHit: a hook which is called when a projectile hits the monster. The function gets the following parameters: the monster itself, the projectile which hit the monster, amount of damage and damage type. If the function returns false, the monster receives no damage and the projectile drops to ground.
onDie: a hook which is called when the monster dies. The function gets one parameter, the monster itself. If the function returns false, the monster is resurrected to life.
MonsterGroup:

monsterType: the name of base monster that forms the group.
count: number of monsters in the group, must be either 2 or 4.
Party:

onMove: a hook which is called when the party moves. The function gets two parameters: the party itself and the numeric compass direction it is moving: 0 (north), 1 (east), 2 (south) or 3 (west). If the function returns false, the move is cancelled.
onTurn: a hook which is called when the party turns. The function gets two parameters: the party itself and the direction it is turning, -1 for counterclockwise and 1 for clockwise turn. If the function returns false, the turn is cancelled.
onUseItem: a hook which is called when an item is used by clicking on an attack icon, right clicking on an inventory item or clicking a champion’s portrait while holding a mouse item. The function gets the following parameters: the champion who uses the item, the item to use and the numeric inventory slot. The slot parameter is nil if the a champion portrait was clicked. If the function returns false, the action is cancelled.
onAttack: a hook which is called when a champion attacks. The function gets two parameters: the attacking champion and the weapon used to attack. The weapon parameter is nil for unarmed attacks. If the function returns false, the attack is cancelled.
onDamage: a hook which is called when a champion is damaged. The function gets the following parameters: the champion who receives the damage, amount of damage and the damage type (e.g. “physical”, “fire”, etc.). If the function returns false, the champion receives no damage.
onProjectileHit: a hook which is called when a champion is hit by a projectile. The function gets the following parameters: the champion who was hit, the projectile hitting the champion, amount of damage and damage type. If the function returns false, the champion receives no damage and the projectile drops to ground.
onDie: a hook which is called when a champion dies. The function gets one parameter, the dying champion. If the function returns false, the champion is resurrected back to life.
onRest: a hook which is called when the party starts resting. The function gets one parameter, the party itself. If the function returns false, resting is cancelled.
onWakeUp: a hook which is called when the party wakes up. The function gets one parameter, the party itself. If the function returns false, waking up is cancelled.
onReceiveCondition: a hook which is called when a champion receives a condition. The function gets the following parameters, the champion, the name of the condition and the numeric value of the condition. If the function returns false, setting the condition is cancelled.
onCastSpell: a hook which is called when a champion casts a spell. The function gets two parameters, the casting champion and the name of the spell. If the function returns false, the casting is cancelled.
onLevelUp: a hook which is called when a champion gains a level. The function gets one parameters, the champion.
onPickUpItem: a hook which is called when an item is picked up. The function gets two parameters, the party itself and the item. If the function returns false, the pick up action is cancelled.
onDrawGui: a hook which is called after the dungeon view has been rendered. The function gets one parameter, a gui context object (see below).
onDrawInventory: a hook which is called after a champion’s inventory screen has been rendered. The function gets one parameter, a gui context object (see below).
onDrawStats: a hook which is called after a champion’s stats screem has been rendered. The function gets one parameter, a gui context object (see below).
onDrawSkills: a hook which is called after a champion’s skills screen has been rendered. The function gets one parameter, a gui context object (see below).
The gui context has the following functions and properties:

width: returns the width of the screen.
height returns the height of the screen.
mouseX: x-coordinate of the mouse cursor.
mouseY: y-coordinate of the mouse cursor.
color(red, green, blue, alpha): sets the pen color. Alpha parameter is optional (defaults to 255).
font(font): sets the typeface (font must be “tiny”, small”, “medium” or “large”).
drawRect(x, y, width, height): draws a filled rectangle with current pen color.
drawImage(filename, x, y): draws an image modulated with current pen color.
drawText(text, x, y): draws a line of text with current typeface and pen color.
button(id, x, y, width, height): returns true if the mouse was clicked in the given button rectangle. id must be a unique string identifier.
mouseDown(button): returns true if a mouse button is down (0=left, 1=middle, 2=right).
keyDown(key): returns true if the given key is down.
Pit:

trapDoorModel: the filename of the trap door model. The filename must be a valid asset reference ending with “.fbx”.
openAnim: the filename of the pit open animation. The filename must be a valid asset reference ending with “.fbx”.
closeAnim: the filename of the pit close animation. The filename must be a valid asset reference ending with “.fbx”.
placement: must always be set to “floor”.
PressurePlate:

activateAnim: the filename of the pressure plate activate animation. The filename must be a valid asset reference ending with “.fbx”.
deactivateAnim: the filename of the pressure plate deactivate animation. The filename must be a valid asset reference ending with “.fbx”.
hidden: a boolean which makes the pressure plate invisible if set to true.
silent: a boolean which makes the pressure plate silent if set to true.
placement: must always be set to “floor”.
Receptor:

hidden: a boolean which makes the receptor invisible if set to true.
replacesWall: a boolean, if true the receptor model replaces the entire wall model.
placement: must always be set to “wall”.
ScriptEntity:

This class has no additional properties.
Secret:

This class has no additional properties.
Spawner:

This class has no additional properties.
Stairs:

down: a boolean indicating whether the stairway leads down (true) or up (false).
StartingLocation:

This class has no additional properties.
Teleporter:

particleSystem: the name of the particle system attached to the teleporter.
placement: must always be set to “floor”.
Timer:

This class has no additional properties.
TorchHolder:

anchorPos: a 3d vector specifying the anchoring position for an attached torch in model’s local space.
anchorRotation: a 3d vector specifying the rotation around x,y and z axis of an attached torch.
placement: must always be set to “wall”.
WallTapestry:

brokenModel: the filename of the model that is swapped in when the wall tapestry is teared down.The filename must be a valid asset reference ending with “.fbx”.
placement: must always be set to “wall”.
WallText:

replacesWall: a boolean, if true the wall text model replaces the entire wall model. Typically set to true.
placement: must always be set to “wall”.
Materials
defineMaterial{…}
Defines a new material or replaces an existing material definition. The function takes the following named parameters:

name: the name of the material to define or replace.
diffuseMap: the filename of the diffuse texture. The filename must be valid asset reference ending with “.tga”. If no texture is specified a built-in white texture is used.
specularMap: the filename of the specular texture. The filename must be valid asset reference ending with “.tga”. If no texture is specified a built-in white texture is used.
normalMap: the filename of the normal map. The filename must be valid asset reference ending with “.tga”. If no texture is specified normal mapping is turned off.
doubleSided: a boolean specifying whether the surface using the material can be seen from both sides.
lighting: a boolean which turns on and off dynamic lighting.
alphaTest: a boolean which turns on and off alpha testing.
blendMode: the alpha blending mode, must be one of the following: “Opaque”, “Translucent”, “Additive”, “Modulative”.
textureAddressMode: texture addressing mode, either “Wrap” or “Clamp”.
glossiness: the glossiness parameter for specular lighting. Typical values range between 1 and 100.
depthBias: depth bias value. It is recommended to set this always to zero.
Particle Systems
defineParticleSystem{…}
Defines a new particle system or replaces an existing particle system definition. The function takes the following named parameters:

name: the name of the particle system to define or replace.
emitters: a table of emitter descriptors. See below.
An emitter descriptor is a table which contains the parameters for a particle emitter. The following parameters are supported:

emissionRate: number of particles to emit per second.
emissionTime: duration of emission in seconds. If set to zero, emission time is infinite.
maxParticles: maximum number of active particles. Sensible values are between 100 and 1000.
spawnBurst: if enabled maximum number of particles are emitted in a single burst when the particle system is started.
boxMin: a 3D vector defining the minimum extents for particle emission.
boxMax: a 3D vector defining the maximum extents for particle emission.
sprayAngle: a table whose first and second elements set the minimum and maximum spraying angle in degrees.
velocity: a table whose first and second elements set the minimum and maximum velocity in units per second.
size: a table whose first and second elements set the minimum and maximum size for for emitted particles.
lifeTime: a table whose first and second elements set the minimum and maximum lifetime for emitted particles.
texture: a valid texture asset reference. The texture may contain multiple frames laid out on a grid.
frameSize: (optional) pixel size of a frame in the particle animation sequence. Typically 32 or 64.
frameCount: (optional) total number of frames in the particle animation sequence.
frameRate: (optional) frame rate of the particle animation sequence.
color0: a table containing R,G,B values in range 0-1 for initial particle color.
color1,color2,color3: (optional) particle color sequence. These parameters have no effect if colorAnimation is not enabled.
colorAnimation: a boolean which enables particle color animation.
opacity: particle opacity value between 0 and 1.
fadeIn: particle’s fade in time in seconds.
fadeOut: particle’s fade out time in seconds.
gravity: a 3D gravity vector.
airResistance: air resistance parameter. Sensible values are between 0 and 10.
rotationSpeed: rotation speed of particles in degrees.
blendMode: blending mode for particle rendering. Must be either “Additive” or “Translucent”.
objectSpace: a boolean flag, if enabled particles are emitted to object space rather than world space.
Sounds
defineSound{…}
Defines a new sound or replaces an existing sound definition. The samples used need to be 16bit 44100Hz .wav-files. The function takes the following named parameters:

name: the name of the sound to define or replace.
filename: the filename of the sample in wave format. The filename must be a valid asset reference ending with “.wav”. Optionally the filename may be a table containing multiple filenames for random sound variations.
loop: a boolean which turns on and off looping.
volume: a number between 0 and 1 which controls the amplitude of the sound.
minDistance: the minimum distance in squares for sound falloff. The sound plays at max volume if it is closer than min distance to the listener.
maxDistance: the maximum distance in squares for sound falloff. The sound is not audible after max distance.
Wallsets
defineWallSet{…}
Defines a new wallset or replaces an existing wallset. The function takes the following named parameters:

name: the name of the wallset to define or replace.
randomFloorFacing: a boolean flag which enables random floor model rotation.
floors: a table of floor models and their relative probabilities. See below.
walls: a table of wall models and their relative probabilities. See below.
pillars: a table of pillar models and their relative probabilities. See below.
ceilings: a table of ceiling models and their relative probabilities. See below.
ceilingShafts: a table of ceiling shaft models and their relative probabilities. See below.
floorDecorations: a table of floor decoration models and their relative probabilities. See below.
wallDecorations: a table of wall decoration models and their relative probabilities. See below.
pillarDecorations: a table of pillar decoration models and their relative probabilities. See below.
The tables referred above contain lists of models and their probabilities that are used to randomly pick up pieces for generating the levels. At every odd table index there must be a valid asset reference ending with a “.fbx”. At every even table index there must be a number that indicates the relative probability of the model.

For example,

Code: Select all

walls = {
	"assets/models/env/dungeon_wall_01.fbx", 50,
	"assets/models/env/dungeon_wall_drainage.fbx", 1,
}
Would indicate that statistically every 50th generated wall would be a wall drainage.

Floors, walls, pillars, ceilings and ceilingShafts are the basic building blocks of a dungeon. FloorDecorations, wallDecorations, pillarDecorations are additional decorative objects that are placed after floors, walls and pillars have been placed.

Recipes
defineRecipe{…}
Defines a new crafting recipe or replaces an existing recipe. The function takes the following named parameters:

item: the name of the item to craft.
craftingTool: the name of the crafting item needed for this recipe. Defaults to “mortar”.
ingredients: a table of count,item pairs. For example { 1, "flask", 2, "grim_cap" }.
Spells
defineSpell{…}
Defines a new spell or replaces an existing spell. The function takes the following named parameters:

name: the name of the spell to define.
uiName: the name shown to the user (e.g. in spell scrolls).
skill: the name of the skill required to cast the spell.
level: the required level in the skill.
runes: an alphabetical string of runes: A = top-left rune (fire), B = top rune (creation), C = top-right rune (air), and so on. So e.g. the rune string for fireball spell is “ACF”.
manaCost: number of mana points to spend when casting the spell.
onCast: this function is called when the spell is cast. The function receives the following parameters: the champion casting the spell, x, y, direction, skill.
Define ... 'Lost.' Neverending Nights - The Neverwinter Machinima that WILL make you laugh!
Also read: Legend of Grimrock: Destiny's Chance here on the forum! Check out the site I made for Legend of Grimrock: Destiny's Chance.
User avatar
Sir Tawmis
Posts: 980
Joined: Mon Jul 30, 2012 8:15 am
Contact:

Re: Legend of Grimrock 1 Modding

Post by Sir Tawmis »

Model and Animation File Formats
Legend of Grimrock 3D models are little endian binary files which contain a hierarchy of nodes. Each node has a transformation and a parent node (except the root node which has no parent). Optionally mesh entities and skeletons may be attached to nodes. Mesh entities are further split into segments. Each segment is a renderable triangle list which refers to a material by its name. Materials themselves are defined outside the model file in Lua script.

The simplest model file contains just a single node with a mesh attached and no skeleton. For example, items in the game are built like this. Monsters and other animated objects are more complex containing skeletons and skinning data.

In addition to model files, complex 3D objects such as monsters need animations. An animation file stores animation data for each bone in a model. However, separate animations such as “walk” and “attack” are stored in separate animation files.

The following basic data types are used in the animation and model files.

Code: Select all

// A String is a variable length 8-bit string
struct String
{
	int32	length;
	byte	data[length];
}

// A FourCC is a four character code string used for headers
struct FourCC
{
	byte	data[4];
}

// A Vec3 is a 3D vector
struct Vec3
{
	float32	x, y, z;
}

// A Mat4x3 is a transformation matrix split into 3x3 rotation and 3D rotation parts
struct Mat4x3
{
	Vec3	baseX;
	Vec3	baseY;
	Vec3	baseZ;
	Vec3	translation;
}

// A Quaternion represents a rotation in 3D space
struct Quaternion
{
	float32 x, y, z, w;
};
Model Files
A model file simply contains a header and a variable number of nodes:

Code: Select all

struct ModelFile
{
	FourCC magic;		// "MDL1"
	int32 version;		// always two
	int32 numNodes;		// number of nodes following
	Node nones[numNodes];
}

struct Node
{
	String name;
	Mat4x3 localToParent;
	int32 parent;		// index of the parent node or -1 if no parent
	int32 type;		// -1 = no entity data, 0 = MeshEntity follows
	(MeshEntity)		// not present if type is -1	
}
The first node is the root node and its parent field must be set to -1. A Node may or may not contain a MeshEntity. Nodes without a mesh entity are used as bones for skeletal animation or as intermediate nodes in transformation chains.

Code: Select all

struct MeshEntity
{
	MeshData meshdata;
	int32 numBones;		// number of bones for skeletal animation
	Bone bones[numBones];
	Vec3 emissiveColor;	// deprecated, should be set to 0,0,0
	byte castShadow;	// 0 = shadow casting off, 1 = shadow casting on
}

struct Bone
{
	int32 boneNodeIndex;	// index of the node used to deform the object
	Mat4x3 invRestMatrix;	// transform from model space to bone space
}

struct MeshData
{
	FourCC magic;		// "MESH"
	int32 version;		// must be two
	int32 numVertices;	// number of vertices following
	VertexArray vertexArrays[15];
	int32 numIndices;	// number of triangle indices following
	int32 indices[numIndices];
	int32 numSegments;	// number of mesh segments following
	MeshSegment segments[numSegments];
	Vec3 boundCenter;	// center of the bound sphere in model space
	float32 boundRadius;	// radius of the bound sphere in model space
	Vec3 boundMin;		// minimum extents of the bound box in model space
	Vec3 boundMax;		// maximum extents of the bound box in model space
}
MeshData struct contains the vertices, index lists (also called triangle lists), mesh segments and bounding volumes of a mesh. Historically meshes used to be stored separately from models, so MeshData has its own header and versioning information.

The vertex data is split into vertex arrays. Up to 15 vertex arrays may be used. The vertex array indices are:

Code: Select all

VERTEX_ARRAY_POSITION = 0
VERTEX_ARRAY_NORMAL = 1
VERTEX_ARRAY_TANGENT = 2
VERTEX_ARRAY_BITANGENT = 3	
VERTEX_ARRAY_COLOR = 4
VERTEX_ARRAY_TEXCOORD0 = 5
VERTEX_ARRAY_TEXCOORD1 = 6
VERTEX_ARRAY_TEXCOORD2 = 7
VERTEX_ARRAY_TEXCOORD3 = 8
VERTEX_ARRAY_TEXCOORD4 = 9
VERTEX_ARRAY_TEXCOORD5 = 10
VERTEX_ARRAY_TEXCOORD6 = 11
VERTEX_ARRAY_TEXCOORD7 = 12
VERTEX_ARRAY_BONE_INDEX = 13
VERTEX_ARRAY_BONE_WEIGHT = 14
Unused vertex arrays should have its dataType, dim and stride fields set to zero. Tangent and binormal vertex arrays are only used for normal mapped models. Position, normal, tangent and bitangent vertex arrays contain three dimensional data and should have its dim field set to 3. Texcoords are two dimensional data and bone indices and weights are four dimensional data. Bone indices and weights should use the byte data type while all other vertex arrays should use the float32 data type. Vertex colors are currently unsupported.

Code: Select all

struct VertexArray
{
	int32 dataType;		// 0 = byte, 1 = int16, 2 = int32, 3 = float32
	int32 dim;		// dimensions of the data type (2-4)
	int32 stride;		// byte offset from vertex to vertex
	byte rawVertexData[numVertices*stride];
}
Finally MeshSegment defines a contiguous segment of the index list that is rendered with a given material.

Code: Select all

struct MeshSegment
{
	String material;	// name of the material defined in Lua script
	int32 primitiveType;	// always two
	int32 firstIndex;	// starting location in the index list
	int32 count;		// number of triangles
}
Animation Files
Animation files contain a header and a number of animated items. Each item is bound to a node in a model file at runtime. Animation data is stored as keyframes which are linearly interpolated. Typically animation data is stored at 30 frames per second. Due to nature of the interpolation quaternion data must be preprocessed so that the interpolation follows the shortest arc in quaternion space.

Code: Select all

struct AnimationFile
{
	FourCC magic;		// "ANIM"
	int32 version;		// always one
	String name;		// name of the animation
	float32 framesPerSecond;
	int32 numFrames;	// length of the animation in frames
	int32 numItems;		// number of animation items following
	Item items[numItems];
}

struct Item
{
	String node;		// name of the node to be animated
	int32 numKeys;		// number of key frames following
	KeyFrame keys[numKeys];
}

struct KeyFrame
{
	Vec3 position;
	Quaternion rotation;
	Vec3 scale;
}
Define ... 'Lost.' Neverending Nights - The Neverwinter Machinima that WILL make you laugh!
Also read: Legend of Grimrock: Destiny's Chance here on the forum! Check out the site I made for Legend of Grimrock: Destiny's Chance.
User avatar
Sir Tawmis
Posts: 980
Joined: Mon Jul 30, 2012 8:15 am
Contact:

Re: Legend of Grimrock 1 Modding

Post by Sir Tawmis »

List of Predefined Sounds
Sound Refers to wav file
party_move assets/samples/characters/party_move_01.wav,assets/samples/characters/party_move_01.wav,assets/samples/characters/party_move_01.wav,assets/samples/characters/party_move_02.wav,assets/samples/characters/party_move_06.wav
party_move_blocked assets/samples/characters/party_move_blocked_01.wav
party_move_overloaded assets/samples/characters/party_move_overloaded_01.wav
party_move_burdened assets/samples/characters/party_move_burdened_01.wav
party_enter_stairs assets/samples/characters/party_enter_stairs_01.wav
party_fall assets/samples/characters/party_fall_01.wav
party_land assets/samples/characters/party_land_01.wav
party_crushed assets/samples/characters/party_crushed_01.wav
projectile_hit_party assets/samples/weapons/hit_wood_01.wav
swipe assets/samples/weapons/whoosh_melee_01.wav
swipe_light assets/samples/weapons/whoosh_light_01.wav
swipe_heavy assets/samples/weapons/whoosh_heavy_01.wav
swipe_thrown assets/samples/weapons/whoosh_thrown_01.wav
swipe_special assets/samples/weapons/whoosh_special_attack_01.wav
swipe_bow assets/samples/weapons/whoosh_bow_01.wav
damage_human_male assets/samples/characters/damage_male_01.wav
damage_human_female assets/samples/characters/damage_female_01.wav,assets/samples/characters/damage_female_02.wav,assets/samples/characters/damage_female_03.wav,assets/samples/characters/damage_female_04.wav
damage_minotaur_male assets/samples/characters/damage_minotaur_01.wav,assets/samples/characters/damage_minotaur_02.wav
damage_minotaur_female assets/samples/characters/damage_minotaur_01.wav,assets/samples/characters/damage_minotaur_02.wav
damage_lizardman_male assets/samples/characters/damage_lizardman_01.wav
damage_lizardman_female assets/samples/characters/damage_lizardman_01.wav
damage_insectoid_male assets/samples/characters/damage_insectoid_01.wav,assets/samples/characters/damage_insectoid_02.wav,assets/samples/characters/damage_insectoid_03.wav
damage_insectoid_female assets/samples/characters/damage_insectoid_01.wav,assets/samples/characters/damage_insectoid_02.wav,assets/samples/characters/damage_insectoid_03.wav
champion_die assets/samples/characters/party_fall_01.wav
heal_party assets/samples/magic/heal_party_01.wav
level_up assets/samples/characters/level_up_01.wav
secret assets/samples/characters/secret_01.wav
discover_spell assets/samples/characters/discover_spell.wav
game_over assets/samples/characters/game_over.wav
click_down assets/samples/interface/click_down_01.wav
click_up assets/samples/interface/click_up_01.wav
read_tome assets/samples/interface/read_scroll_01.wav
read_scroll assets/samples/interface/read_scroll_01.wav
map_turn_page assets/samples/interface/read_scroll_01.wav
consume_food assets/samples/characters/consume_food_01.wav
consume_potion assets/samples/characters/consume_potion_01.wav
scramble_writer assets/samples/interface/scramble_writer.wav
item_pick_up assets/samples/items/item_pick_up_01.wav
item_drop assets/samples/items/item_drop_01.wav
item_equip assets/samples/items/item_equip_01.wav
impact_generic assets/samples/weapons/impact_blunt_01.wav
impact_blade assets/samples/weapons/impact_blade_01.wav
impact_blunt assets/samples/weapons/impact_blunt_01.wav
impact_punch assets/samples/weapons/impact_punch_01.wav
impact_arrow assets/samples/weapons/impact_arrow_01.wav
pressure_plate_pressed assets/samples/env/pressure_plate_down_01.wav
pressure_plate_released assets/samples/env/pressure_plate_up_01.wav
gate_open assets/samples/env/gate_open_01.wav
gate_close assets/samples/env/gate_close_01.wav
gate_iron_open assets/samples/env/gate_iron_open_01.wav
gate_iron_close assets/samples/env/gate_iron_open_01.wav
gate_lock assets/samples/env/gate_lock_01.wav
button assets/samples/env/button_01.wav
lever assets/samples/env/lever_01.wav
key_lock assets/samples/env/lock_01.wav
wall_sliding assets/samples/env/wall_sliding_01.wav
wall_sliding_lock assets/samples/env/wall_sliding_lock_01.wav
teleporter_ambient assets/samples/env/teleporter_ambient_01.wav
crystal_ambient assets/samples/env/crystal_ambient_01.wav
teleport assets/samples/magic/teleport_01.wav
torch_burning assets/samples/env/torch_burning_01.wav
pit_open assets/samples/env/pit_open_01.wav
pit_close assets/samples/env/pit_close_01.wav
earthquake assets/samples/env/earthquake_01.wav
barrel_hit assets/samples/weapons/hit_wood_01.wav
spider_eggs_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_bone_02.wav,assets/samples/weapons/hit_flesh_01.wav
wall_tapestry_tear assets/samples/env/wall_tapestry_tear.wav
monster_item_drop assets/samples/monsters/monster_item_drop.wav
ice_hit assets/samples/weapons/hit_ice_01.wav
spider_walk assets/samples/monsters/spider_walk_01.wav
spider_attack assets/samples/monsters/spider_attack_01.wav
spider_die assets/samples/monsters/spider_die_01.wav
spider_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_bone_02.wav,assets/samples/weapons/hit_flesh_01.wav,assets/samples/monsters/spider_hit_01.wav
ogre_attack assets/samples/monsters/ogre_attack_01.wav
ogre_whoosh assets/samples/monsters/ogre_whoosh_01.wav
ogre_impact assets/samples/monsters/ogre_impact_01.wav
ogre_die assets/samples/monsters/ogre_die_01.wav
ogre_walk assets/samples/monsters/ogre_walk_01.wav
ogre_footstep assets/samples/monsters/ogre_footstep_01.wav
ogre_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_bone_02.wav,assets/samples/weapons/hit_flesh_01.wav
ogre_rush_begin assets/samples/monsters/ogre_rush_begin.wav
skeleton_attack assets/samples/monsters/skeleton_attack_01.wav
skeleton_archer_attack assets/samples/monsters/skeleton_archer_attack_01.wav
skeleton_die assets/samples/monsters/skeleton_die_01.wav
skeleton_walk assets/samples/monsters/skeleton_walk_01.wav
skeleton_footstep assets/samples/monsters/skeleton_footstep_01.wav
skeleton_archer_footstep assets/samples/monsters/skeleton_archer_footstep_01.wav
skeleton_hit assets/samples/weapons/hit_armor_01.wav,assets/samples/weapons/hit_armor_02.wav,assets/samples/weapons/hit_bone_02.wav
snail_walk assets/samples/monsters/snail_walk_01.wav
snail_attack assets/samples/monsters/snail_attack_01.wav
snail_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_bone_02.wav,assets/samples/weapons/hit_flesh_01.wav
snail_die assets/samples/monsters/snail_die_01.wav
slime_walk assets/samples/monsters/slime_walk_01.wav
slime_attack assets/samples/monsters/slime_attack_01.wav
slime_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_flesh_01.wav
slime_die assets/samples/monsters/slime_die_01.wav
crowern_walk assets/samples/monsters/crowern_walk_01.wav
crowern_footstep assets/samples/monsters/crowern_footstep_01.wav
crowern_attack assets/samples/monsters/crowern_attack_01.wav
crowern_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_flesh_01.wav,assets/samples/monsters/crowern_hit_01.wav,assets/samples/monsters/crowern_hit_02.wav
crowern_die assets/samples/monsters/crowern_die_01.wav
wyvern_walk assets/samples/monsters/crowern_walk_01.wav
wyvern_footstep assets/samples/monsters/crowern_footstep_01.wav
wyvern_attack assets/samples/monsters/wyvern_attack_01.wav
wyvern_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_flesh_01.wav,assets/samples/monsters/wyvern_hit_01.wav,assets/samples/monsters/wyvern_hit_02.wav
wyvern_die assets/samples/monsters/wyvern_die_01.wav
goromorg_walk assets/samples/monsters/goromorg_walk_01.wav
goromorg_footstep assets/samples/monsters/goromorg_footstep_01.wav
goromorg_attack assets/samples/monsters/goromorg_attack_01.wav,assets/samples/monsters/goromorg_attack_02.wav,assets/samples/monsters/goromorg_attack_03.wav
goromorg_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_flesh_01.wav,assets/samples/monsters/goromorg_hit_01.wav,assets/samples/monsters/goromorg_hit_02.wav
goromorg_shield_hit assets/samples/monsters/goromorg_shield_hit.wav
goromorg_shield_break assets/samples/monsters/goromorg_shield_break.wav
goromorg_die assets/samples/monsters/goromorg_die_01.wav
uggardian_walk assets/samples/monsters/uggardian_walk_01.wav
uggardian_attack assets/samples/monsters/uggardian_attack_01.wav
uggardian_hit assets/samples/monsters/uggardian_hit_01.wav,assets/samples/weapons/hit_armor_01.wav
uggardian_die assets/samples/monsters/uggardian_die_01.wav
tentacles_attack assets/samples/monsters/tentacles_attack_01.wav
tentacles_walk assets/samples/monsters/tentacles_walk_01.wav
tentacles_rise assets/samples/monsters/tentacles_rise_01.wav
tentacles_retreat assets/samples/monsters/tentacles_retreat_01.wav
tentacles_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_bone_02.wav,assets/samples/weapons/hit_flesh_01.wav
tentacles_die assets/samples/monsters/tentacles_die_01.wav
crab_attack assets/samples/monsters/crab_attack_01.wav
crab_walk assets/samples/monsters/crab_walk_01.wav
crab_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_bone_02.wav,assets/samples/weapons/hit_flesh_01.wav
crab_die assets/samples/monsters/crab_die_01.wav
scavenger_walk assets/samples/monsters/scavenger_walk_01.wav
scavenger_attack assets/samples/monsters/scavenger_attack_01.wav,assets/samples/monsters/scavenger_attack_02.wav,assets/samples/monsters/scavenger_attack_03.wav
scavenger_die assets/samples/monsters/scavenger_die_01.wav
scavenger_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_flesh_01.wav,assets/samples/monsters/scavenger_hit_01.wav,assets/samples/monsters/scavenger_hit_02.wav
shrakk_torr_fly assets/samples/monsters/shrakk_torr_fly_01.wav
shrakk_torr_attack assets/samples/monsters/shrakk_torr_attack_01.wav,assets/samples/monsters/shrakk_torr_attack_02.wav
shrakk_torr_die assets/samples/monsters/shrakk_torr_die_01.wav
shrakk_torr_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_flesh_01.wav,assets/samples/monsters/scavenger_hit_01.wav,assets/samples/monsters/scavenger_hit_02.wav
ice_lizard_attack assets/samples/monsters/ice_lizard_attack_01.wav
ice_lizard_walk assets/samples/monsters/ice_lizard_walk_01.wav
ice_lizard_footstep assets/samples/monsters/ice_lizard_footstep_01.wav
ice_lizard_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_bone_02.wav,assets/samples/weapons/hit_flesh_01.wav,assets/samples/monsters/ice_lizard_hit_01.wav,assets/samples/monsters/ice_lizard_hit_02.wav
ice_lizard_die assets/samples/monsters/ice_lizard_die_01.wav
herder_walk assets/samples/monsters/herder_walk_01.wav
herder_footstep assets/samples/monsters/herder_footstep_01.wav
herder_attack assets/samples/monsters/herder_attack_01.wav
herder_hit assets/samples/weapons/hit_bone_01.wav,assets/samples/weapons/hit_flesh_01.wav,assets/samples/monsters/herder_hit_01.wav,assets/samples/monsters/herder_hit_02.wav
herder_die assets/samples/monsters/herder_die_01.wav
herder_big_attack assets/samples/monsters/herder_big_attack_01.wav
herder_big_die assets/samples/monsters/herder_big_die_01.wav
herder_small_attack assets/samples/monsters/herder_small_attack_01.wav
herder_small_die assets/samples/monsters/herder_small_die_01.wav
warden_attack assets/samples/monsters/warden_attack_01.wav
warden_whoosh_01 assets/samples/monsters/warden_whoosh_01.wav
warden_whoosh_02 assets/samples/monsters/warden_whoosh_02.wav
warden_impact assets/samples/monsters/ogre_impact_01.wav
warden_rush_begin assets/samples/monsters/warden_rush_begin_01.wav
warden_rush_hit assets/samples/monsters/warden_rush_hit_01.wav
warden_die assets/samples/monsters/warden_die_01.wav
warden_walk assets/samples/monsters/warden_walk_01.wav
warden_footstep assets/samples/monsters/warden_footstep_01.wav
warden_hit assets/samples/weapons/hit_metal_01.wav
generic_spell assets/samples/magic/enchantment_01.wav
fireburst assets/samples/magic/fireburst_01.wav
shockburst assets/samples/magic/lightning_hit_01.wav
frostburst assets/samples/magic/frostbolt_hit_01.wav
fireball assets/samples/magic/fireball_01.wav
fireball_launch assets/samples/magic/spell_launch_01.wav
fireball_hit assets/samples/magic/fireball_hit_01.wav
poison_bolt assets/samples/magic/frostbolt_01.wav
poison_bolt_launch assets/samples/magic/poison_bolt_launch_01.wav
poison_bolt_hit assets/samples/magic/poison_bolt_hit_01.wav
frostbolt assets/samples/magic/frostbolt_01.wav
frostbolt_launch assets/samples/magic/spell_launch_01.wav
frostbolt_hit assets/samples/magic/frostbolt_hit_01.wav
ice_shard assets/samples/magic/ice_shard_01.wav
lightning_bolt assets/samples/magic/lightning_01.wav
lightning_bolt_launch assets/samples/magic/lightning_launch_01.wav
lightning_bolt_hit assets/samples/magic/lightning_hit_01.wav
lightning_bolt_hit_small assets/samples/magic/lightning_hit_small_01.wav
poison_cloud assets/samples/magic/poison_cloud_01.wav
blob assets/samples/magic/blob_01.wav
blob_launch assets/samples/magic/blob_launch_01.wav
blob_hit assets/samples/magic/blob_hit_01.wav
blob_hit_receptor assets/samples/magic/blob_hit_receptor_01.wav
cube_start assets/samples/monsters/cube_start.wav
cube_hit_wall assets/samples/monsters/cube_hit_wall.wav
cube_break_free assets/samples/monsters/cube_break_free.wav
cube_move assets/samples/monsters/cube_walk.wav
cube_freeze assets/samples/monsters/cube_freeze.wav
cube_restart1 assets/samples/monsters/cube_restart_01.wav
cube_restart2 assets/samples/monsters/cube_restart_02.wav
cube_restart3 assets/samples/monsters/cube_restart_03.wav
cube_restart4 assets/samples/monsters/cube_restart_04.wav
cube_die assets/samples/monsters/cube_die.wav
Define ... 'Lost.' Neverending Nights - The Neverwinter Machinima that WILL make you laugh!
Also read: Legend of Grimrock: Destiny's Chance here on the forum! Check out the site I made for Legend of Grimrock: Destiny's Chance.
User avatar
Sir Tawmis
Posts: 980
Joined: Mon Jul 30, 2012 8:15 am
Contact:

Re: Legend of Grimrock 1 Modding

Post by Sir Tawmis »

List of Predefined Particle Systems
blob
blob_hit
blob_hit_receptor
crystal
cube_break_free
cube_die
cube_explode
damage_screen
death_dust
earthquake_dust
fireball
fireball_hit
fireball_screen
fireball_greater
fireball_hit_greater
fireburst
frost_arrow
frostbolt
frostbolt_hit
frostburst
glitter_gold
glitter_silver
glitter_toorum
goromorg_lantern
hit_wood
hit_blood
hit_dust
hit_flame
hit_goo
hit_slime
ice_shards
lightning_bolt
lightning_bolt_hit
lightning_bolt_greater
lightning_bolt_hit_greater
party_crush
poison_bolt
poison_bolt_hit
poison_bolt_screen
poison_cloud
prison_ceiling_lamp
shockburst
teleporter
teleport_screen
torch
Define ... 'Lost.' Neverending Nights - The Neverwinter Machinima that WILL make you laugh!
Also read: Legend of Grimrock: Destiny's Chance here on the forum! Check out the site I made for Legend of Grimrock: Destiny's Chance.
User avatar
Sir Tawmis
Posts: 980
Joined: Mon Jul 30, 2012 8:15 am
Contact:

Re: Legend of Grimrock 1 Modding

Post by Sir Tawmis »

List of Predefined Spells
fireburst
shockburst
frostburst
fireball
fireball_greater
poison_bolt
poison_bolt_greater
frostbolt
improved_frostbolt
ice_shards
lightning_bolt
lightning_bolt_greater
powerbolt
poison_cloud
blob
Define ... 'Lost.' Neverending Nights - The Neverwinter Machinima that WILL make you laugh!
Also read: Legend of Grimrock: Destiny's Chance here on the forum! Check out the site I made for Legend of Grimrock: Destiny's Chance.
User avatar
Sir Tawmis
Posts: 980
Joined: Mon Jul 30, 2012 8:15 am
Contact:

Re: Legend of Grimrock 1 Modding

Post by Sir Tawmis »

Predefined Material Definitions
Here is a listing of predefined materials. You can easily override these by copy pasting the desired material definition to your dungeon’s materials.lua and change the parameters. If you want to add a new texture it has to be placed in your dungeon’s mod_assets folder and files must be in dds format. But remember that the engine still accepts only filenames with tga extension (tga extension is substituted with dds when loading the texture).

Code: Select all


defineMaterial{
	name = "brick_wall01",
	diffuseMap = "assets/textures/env/brickwall_stone_root_dif.tga",
	specularMap = "assets/textures/env/brickwall_stone_root_spec.tga",
	normalMap = "assets/textures/env/brickwall_stone_root_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 15,
	depthBias = 0,
}

defineMaterial{
	name = "brick_ceiling01",
	diffuseMap = "assets/textures/env/dungeon_ceiling_dif.tga",
	specularMap = "assets/textures/env/dungeon_ceiling_spec.tga",
	normalMap = "assets/textures/env/dungeon_ceiling_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "brick_rubble01",
	diffuseMap = "assets/textures/env/brick_rubble_dif.tga",
	specularMap = "assets/textures/env/brick_rubble_spec.tga",
	normalMap = "assets/textures/env/brick_rubble_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "brick_pillar01",
	diffuseMap = "assets/textures/env/brick_pillar_dif.tga",
	specularMap = "assets/textures/env/brick_pillar_spec.tga",
	normalMap = "assets/textures/env/brick_pillar_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "floor_stone_slabs01",
	diffuseMap = "assets/textures/env/dungeon_floor_dif.tga",
	specularMap = "assets/textures/env/dungeon_floor_spec.tga",
	normalMap = "assets/textures/env/dungeon_floor_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "broken_floor_panels",
	diffuseMap = "assets/textures/env/broken_floor_panel_dif.tga",
	specularMap = "assets/textures/env/broken_floor_panel_spec.tga",
	normalMap = "assets/textures/env/broken_floor_panel_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "wood_barrel01",
	diffuseMap = "assets/textures/props/wood_barrel_dif.tga",
	specularMap = "assets/textures/props/wood_barrel_spec.tga",
	normalMap = "assets/textures/props/wood_barrel_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 60,
	depthBias = 0,
}

defineMaterial{
	name = "skull_human01",
	diffuseMap = "assets/textures/props/human_skull_dif.tga",
	specularMap = "assets/textures/props/human_skull_spec.tga",
	normalMap = "assets/textures/props/human_skull_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "dungeon_pressure_plate",
	diffuseMap = "assets/textures/env/dungeon_presure_plate_dif.tga",
	specularMap = "assets/textures/env/dungeon_presure_plate_spec.tga",
	normalMap = "assets/textures/env/dungeon_presure_plate_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "daemon_head",
	diffuseMap = "assets/textures/env/daemon_head_dif.tga",
	specularMap = "assets/textures/env/daemon_head_spec.tga",
	normalMap = "assets/textures/env/daemon_head_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "dungeon_arch_door",
	diffuseMap = "assets/textures/env/dungeon_arch_door_dif.tga",
	specularMap = "assets/textures/env/dungeon_arch_door_spec.tga",
	normalMap = "assets/textures/env/dungeon_arch_door_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 75,
	depthBias = 0,
}

defineMaterial{
	name = "dungeon_arch",
	diffuseMap = "assets/textures/env/dungeon_arch_dif.tga",
	specularMap = "assets/textures/env/dungeon_arch_spec.tga",
	normalMap = "assets/textures/env/dungeon_arch_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "spider",
	diffuseMap = "assets/textures/monsters/spider_dif.tga",
	specularMap = "assets/textures/monsters/spider_spec.tga",
	normalMap = "assets/textures/monsters/spider_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 40,
	depthBias = 0,
}

defineMaterial{
	name = "shaman_staff",
	diffuseMap = "assets/textures/items/shaman_staff_dif.tga",
	specularMap = "assets/textures/items/shaman_staff_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "scimitar",
	diffuseMap = "assets/textures/items/scimitar_dif.tga",
	specularMap = "assets/textures/items/scimitar_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "ringmail_01",
	diffuseMap = "assets/textures/items/ringmail_01_dif.tga",
	specularMap = "assets/textures/items/ringmail_01_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "iron_basinet",
	diffuseMap = "assets/textures/items/iron_basinet_dif.tga",
	specularMap = "assets/textures/items/iron_basinet_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "brick_wall_secret_button",
	diffuseMap = "assets/textures/env/brickwall_secret_button_dif.tga",
	specularMap = "assets/textures/env/brickwall_secret_button_spec.tga",
	normalMap = "assets/textures/env/brickwall_secret_button_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "lever_frame",
	diffuseMap = "assets/textures/props/dungeon_lever_dif.tga",
	specularMap = "assets/textures/props/dungeon_lever_spec.tga",
	normalMap = "assets/textures/props/dungeon_lever_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "tunnel_ogre",
	diffuseMap = "assets/textures/monsters/ogre_dif.tga",
	specularMap = "assets/textures/monsters/ogre_spec.tga",
	normalMap = "assets/textures/monsters/ogre_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 50,
	depthBias = 0,
}

defineMaterial{
	name = "iron_porticullis",
	diffuseMap = "assets/textures/env/dungeon_porticullis_dif.tga",
	specularMap = "assets/textures/env/dungeon_porticullis_spec.tga",
	normalMap = "assets/textures/env/dungeon_porticullis_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 100,
	depthBias = 0,
}

defineMaterial{
	name = "dungeon_door_lock",
	diffuseMap = "assets/textures/props/dungeon_key_lock_dif.tga",
	specularMap = "assets/textures/props/dungeon_key_lock_spec.tga",
	normalMap = "assets/textures/props/dungeon_key_lock_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 80,
	depthBias = 0,
}

defineMaterial{
	name = "wall_keyhole",
	diffuseMap = "assets/textures/env/dungeon_wall_keyhole_dif.tga",
	specularMap = "assets/textures/env/dungeon_wall_keyhole_spec.tga",
	normalMap = "assets/textures/env/dungeon_wall_keyhole_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 25,
	depthBias = 0,
}

defineMaterial{
	name = "morning_star",
	diffuseMap = "assets/textures/items/morning_star_dif.tga",
	specularMap = "assets/textures/items/morning_star_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "swipe01",
	diffuseMap = "assets/textures/swipes/swipe01.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Additive",
	textureAddressMode = "Clamp",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "key_brass",
	diffuseMap = "assets/textures/items/key_brass_dif.tga",
	specularMap = "assets/textures/items/key_brass_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "peasant_clothes",
	diffuseMap = "assets/textures/items/peasant_clothes_dif.tga",
	specularMap = "assets/textures/items/peasant_clothes_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "nomad_boots",
	diffuseMap = "assets/textures/items/nomad_boots_dif.tga",
	specularMap = "assets/textures/items/nomad_boots_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "ringmail_02",
	diffuseMap = "assets/textures/items/ringmail_02_dif.tga",
	specularMap = "assets/textures/items/ringmail_02_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "dagger",
	diffuseMap = "assets/textures/items/dagger_dif.tga",
	specularMap = "assets/textures/items/dagger_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "great_axe",
	diffuseMap = "assets/textures/items/great_axe_dif.tga",
	specularMap = "assets/textures/items/great_axe_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "skeleton_warrior",
	diffuseMap = "assets/textures/monsters/skeleton_warrior_dif.tga",
	specularMap = "assets/textures/monsters/skeleton_warrior_spec.tga",
	normalMap = "assets/textures/monsters/skeleton_warrior_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 75,
	depthBias = 0,
}

defineMaterial{
	name = "shuriken",
	diffuseMap = "assets/textures/items/shuriken_dif.tga",
	specularMap = "assets/textures/items/shuriken_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "crowern",
	diffuseMap = "assets/textures/monsters/crowern_dif.tga",
	specularMap = "assets/textures/monsters/crowern_spec.tga",
	normalMap = "assets/textures/monsters/crowern_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = true,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 15,
	depthBias = 0,
}

defineMaterial{
	name = "short_bow",
	diffuseMap = "assets/textures/items/short_bow_dif.tga",
	specularMap = "assets/textures/items/short_bow_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "torch",
	diffuseMap = "assets/textures/items/torch_dif.tga",
	specularMap = "assets/textures/items/torch_spec.tga",
	normalMap = "assets/textures/items/torch_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "dungeon_torch_holder",
	diffuseMap = "assets/textures/props/dungeon_torch_holder_dif.tga",
	specularMap = "assets/textures/props/dungeon_torch_holder_spec.tga",
	normalMap = "assets/textures/props/dungeon_torch_holder_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 100,
	depthBias = 0,
}

defineMaterial{
	name = "skeleton_warrior_weapons",
	diffuseMap = "assets/textures/monsters/skeleton_warrior_weapons_dif.tga",
	specularMap = "assets/textures/monsters/skeleton_warrior_weapons_spec.tga",
	normalMap = "assets/textures/monsters/skeleton_warrior_weapons_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 50,
	depthBias = 0,
}

defineMaterial{
	name = "arrow",
	diffuseMap = "assets/textures/items/arrow_dif.tga",
	specularMap = "assets/textures/items/arrow_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "scroll",
	diffuseMap = "assets/textures/items/scroll_dif.tga",
	specularMap = "assets/textures/common/black.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "rock",
	diffuseMap = "assets/textures/items/rock_dif.tga",
	specularMap = "assets/textures/items/rock_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "dungeon_stairs",
	diffuseMap = "assets/textures/env/dungeon_stairs_dif.tga",
	specularMap = "assets/textures/env/dungeon_stairs_spec.tga",
	normalMap = "assets/textures/env/dungeon_stairs_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "heavy_shield",
	diffuseMap = "assets/textures/items/heavy_shield_dif.tga",
	specularMap = "assets/textures/items/heavy_shield_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "healing_crystal",
	diffuseMap = "assets/textures/env/healing_crystal_dif.tga",
	specularMap = "assets/textures/env/healing_crystal_spec.tga",
	normalMap = "assets/textures/env/healing_crystal_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "dungeon_button",
	diffuseMap = "assets/textures/props/dungeon_button_dif.tga",
	specularMap = "assets/textures/props/dungeon_button_spec.tga",
	normalMap = "assets/textures/props/dungeon_button_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 40,
	depthBias = 0,
}

defineMaterial{
	name = "dungeon_iron_door",
	diffuseMap = "assets/textures/env/dungeon_iron_door_dif.tga",
	specularMap = "assets/textures/env/dungeon_iron_door_spec.tga",
	normalMap = "assets/textures/env/dungeon_iron_door_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 75,
	depthBias = 0,
}

defineMaterial{
	name = "key_iron",
	diffuseMap = "assets/textures/items/key_iron_dif.tga",
	specularMap = "assets/textures/items/key_iron_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "leather_brigandine",
	diffuseMap = "assets/textures/items/leather_brigandine_dif.tga",
	specularMap = "assets/textures/items/leather_brigandine_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "leather_greaves",
	diffuseMap = "assets/textures/items/leather_greaves_dif.tga",
	specularMap = "assets/textures/items/leather_greaves_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "leather_clothes",
	diffuseMap = "assets/textures/items/leather_clothes_dif.tga",
	specularMap = "assets/textures/items/leather_clothes_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "leather_cap",
	diffuseMap = "assets/textures/items/leather_cap_dif.tga",
	specularMap = "assets/textures/items/leather_cap_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "chain_metal_dark",
	diffuseMap = "assets/textures/env/chain_metal_dif.tga",
	specularMap = "assets/textures/env/chain_metal_spec.tga",
	normalMap = "assets/textures/env/chain_metal_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 60,
	depthBias = 0,
}

defineMaterial{
	name = "ogre_hammer",
	diffuseMap = "assets/textures/monsters/ogre_hammer_dif.tga",
	specularMap = "assets/textures/monsters/ogre_hammer_spec.tga",
	normalMap = "assets/textures/monsters/ogre_hammer_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "machete",
	diffuseMap = "assets/textures/items/machete_dif.tga",
	specularMap = "assets/textures/items/machete_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "snail",
	diffuseMap = "assets/textures/monsters/snail_dif.tga",
	specularMap = "assets/textures/monsters/snail_spec.tga",
	normalMap = "assets/textures/monsters/snail_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 100,
	depthBias = 0,
}

defineMaterial{
	name = "cudgel",
	diffuseMap = "assets/textures/items/cudgel_dif.tga",
	specularMap = "assets/textures/items/cudgel_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "hand_axe",
	diffuseMap = "assets/textures/items/hand_axe_dif.tga",
	specularMap = "assets/textures/items/hand_axe_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "frostbite_necklace",
	diffuseMap = "assets/textures/items/frostbite_necklace_dif.tga",
	specularMap = "assets/textures/items/frostbite_necklace_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "snail_shell",
	diffuseMap = "assets/textures/monsters/snail_dif.tga",
	specularMap = "assets/textures/monsters/snail_spec.tga",
	normalMap = "assets/textures/monsters/snail_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 40,
	depthBias = 0,
}

defineMaterial{
	name = "hardstone_bracelet",
	diffuseMap = "assets/textures/items/hardstone_bracelet_dif.tga",
	specularMap = "assets/textures/items/hardstone_bracelet_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "huntsman_clothes",
	diffuseMap = "assets/textures/items/huntsman_clothes_dif.tga",
	specularMap = "assets/textures/items/huntsman_clothes_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "serpent_bracer",
	diffuseMap = "assets/textures/items/serpent_bracer_dif.tga",
	specularMap = "assets/textures/items/serpent_bracer_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 15,
	depthBias = 0,
}

defineMaterial{
	name = "secret_button_easy",
	diffuseMap = "assets/textures/env/secret_button_easy_dif.tga",
	specularMap = "assets/textures/env/secret_button_easy_spec.tga",
	normalMap = "assets/textures/env/secret_button_easy_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "goromorg_statue",
	diffuseMap = "assets/textures/env/goromorg_statue_dif.tga",
	specularMap = "assets/textures/env/goromorg_statue_spec.tga",
	normalMap = "assets/textures/env/goromorg_statue_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 15,
	depthBias = 0,
}

defineMaterial{
	name = "goromorg_statue_base",
	diffuseMap = "assets/textures/env/marble_generic_dif.tga",
	specularMap = "assets/textures/env/marble_generic_spec.tga",
	normalMap = "assets/textures/env/marble_generic_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "goromorog1",
	diffuseMap = "assets/textures/monsters/goromorg_dif.tga",
	specularMap = "assets/textures/monsters/goromorg_spec.tga",
	normalMap = "assets/textures/monsters/goromorg_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = true,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "garomorg_candle",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 50,
	depthBias = 0,
}

defineMaterial{
	name = "blue_clothes",
	diffuseMap = "assets/textures/items/blue_clothes_dif.tga",
	specularMap = "assets/textures/items/blue_clothes_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "purple_clothes",
	diffuseMap = "assets/textures/items/purple_clothes_dif.tga",
	specularMap = "assets/textures/items/blue_clothes_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "sandals",
	diffuseMap = "assets/textures/items/sandals_dif.tga",
	specularMap = "assets/textures/items/sandals_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "leather_boots",
	diffuseMap = "assets/textures/items/leather_boots_dif.tga",
	specularMap = "assets/textures/items/leather_boots_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 25,
	depthBias = 0,
}

defineMaterial{
	name = "flarefeather_cap",
	diffuseMap = "assets/textures/items/flarefeather_cap_dif.tga",
	specularMap = "assets/textures/items/flarefeather_cap_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "throwing_knife",
	diffuseMap = "assets/textures/items/throwing_knife_dif.tga",
	specularMap = "assets/textures/items/throwing_knife_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "throwing_axe",
	diffuseMap = "assets/textures/items/throwing_axe_dif.tga",
	specularMap = "assets/textures/items/throwing_axe_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "altar",
	diffuseMap = "assets/textures/env/dungeon_altar_dif.tga",
	specularMap = "assets/textures/env/dungeon_altar_spec.tga",
	normalMap = "assets/textures/env/dungeon_altar_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "gobelin",
	diffuseMap = "assets/textures/env/dungeon_gobelin_dif.tga",
	specularMap = "assets/textures/env/dungeon_gobelin_spec.tga",
	normalMap = "assets/textures/env/dungeon_gobelin_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = true,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "uggardian",
	diffuseMap = "assets/textures/monsters/uggardian_dif.tga",
	specularMap = "assets/textures/monsters/uggardian_spec.tga",
	normalMap = "assets/textures/monsters/uggardian_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 60,
	depthBias = 0,
}

defineMaterial{
	name = "uggardian_fire",
	diffuseMap = "assets/textures/monsters/uggardian_fire_dif.tga",
	doubleSided = true,
	lighting = false,
	alphaTest = true,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "drainage_tentacles",
	diffuseMap = "assets/textures/monsters/drain_tentacles_dif.tga",
	specularMap = "assets/textures/monsters/drain_tentacles_spec.tga",
	normalMap = "assets/textures/monsters/drain_tentacles_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 35,
	depthBias = 0,
}

defineMaterial{
	name = "tome",
	diffuseMap = "assets/textures/items/tome_dif.tga",
	specularMap = "assets/textures/common/black.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "cave_grab",
	diffuseMap = "assets/textures/monsters/cave_crab_dif.tga",
	specularMap = "assets/textures/monsters/cave_crab_spec.tga",
	normalMap = "assets/textures/monsters/cave_crab_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 55,
	depthBias = 0,
}

defineMaterial{
	name = "gobelin_torn",
	diffuseMap = "assets/textures/env/dungeon_gobelin_torn_dif.tga",
	specularMap = "assets/textures/env/dungeon_gobelin_torn_spec.tga",
	normalMap = "assets/textures/env/dungeon_gobelin_torn_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = true,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "ice_lizard",
	diffuseMap = "assets/textures/monsters/ice_lizard_dif.tga",
	specularMap = "assets/textures/monsters/ice_lizard_spec.tga",
	normalMap = "assets/textures/monsters/ice_lizard_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 65,
	depthBias = 0,
}

defineMaterial{
	name = "snail_slice",
	diffuseMap = "assets/textures/items/snail_slice_dif.tga",
	specularMap = "assets/textures/items/snail_slice_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 60,
	depthBias = 0,
}

defineMaterial{
	name = "temple_wall",
	diffuseMap = "assets/textures/env/temple_wall_dif.tga",
	specularMap = "assets/textures/env/temple_wall_spec.tga",
	normalMap = "assets/textures/env/temple_wall_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "temple_pillar",
	diffuseMap = "assets/textures/env/temple_pillar_dif.tga",
	specularMap = "assets/textures/env/temple_pillar_spec.tga",
	normalMap = "assets/textures/env/temple_pillar_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "temple_ceiling",
	diffuseMap = "assets/textures/env/temple_ceiling_dif.tga",
	specularMap = "assets/textures/env/temple_ceiling_spec.tga",
	normalMap = "assets/textures/env/temple_ceiling_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "temple_floor",
	diffuseMap = "assets/textures/env/temple_floor_dif.tga",
	specularMap = "assets/textures/env/temple_floor_spec.tga",
	normalMap = "assets/textures/env/temple_floor_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "knife",
	diffuseMap = "assets/textures/items/knife_dif.tga",
	specularMap = "assets/textures/items/knife_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 50,
	depthBias = 0,
}

defineMaterial{
	name = "temple_arch",
	diffuseMap = "assets/textures/env/temple_arch_dif.tga",
	specularMap = "assets/textures/env/temple_arch_spec.tga",
	normalMap = "assets/textures/env/temple_arch_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "temple_easy_button",
	diffuseMap = "assets/textures/env/temple_easy_button_dif.tga",
	specularMap = "assets/textures/env/temple_easy_button_spec.tga",
	normalMap = "assets/textures/env/temple_easy_button_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "temple_hard_button",
	diffuseMap = "assets/textures/env/temple_hard_button_dif.tga",
	specularMap = "assets/textures/env/temple_hard_button_spec.tga",
	normalMap = "assets/textures/env/temple_hard_button_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "chitin_mail",
	diffuseMap = "assets/textures/items/chitin_mail_dif.tga",
	specularMap = "assets/textures/items/chitin_mail_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "chitin_greaves",
	diffuseMap = "assets/textures/items/chitin_greaves_dif.tga",
	specularMap = "assets/textures/items/chitin_greaves_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "chitin_mask",
	diffuseMap = "assets/textures/items/chitin_mask_dif.tga",
	specularMap = "assets/textures/items/chitin_mask_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "nomad_clothes",
	diffuseMap = "assets/textures/items/nomad_clothes_dif.tga",
	specularMap = "assets/textures/common/black.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "small_shield",
	diffuseMap = "assets/textures/items/small_shield_dif.tga",
	specularMap = "assets/textures/items/small_shield_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "whitewood_wand",
	diffuseMap = "assets/textures/items/whitewood_wand_dif.tga",
	specularMap = "assets/textures/items/whitewood_wand_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "temple_pressure_plate",
	diffuseMap = "assets/textures/env/temple_pressureplate_dif.tga",
	specularMap = "assets/textures/env/temple_pressureplate_spec.tga",
	normalMap = "assets/textures/env/temple_pressureplate_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "temple_medium_button",
	diffuseMap = "assets/textures/env/temple_medium_button_dif.tga",
	specularMap = "assets/textures/env/temple_medium_button_spec.tga",
	normalMap = "assets/textures/env/temple_medium_button_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "metal_door",
	diffuseMap = "assets/textures/env/metal_door_dif.tga",
	specularMap = "assets/textures/env/metal_door_spec.tga",
	normalMap = "assets/textures/env/metal_door_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 70,
	depthBias = 0,
}

defineMaterial{
	name = "circle_keyhole",
	diffuseMap = "assets/textures/props/circle_key_lock_dif.tga",
	specularMap = "assets/textures/props/circle_key_lock_spec.tga",
	normalMap = "assets/textures/props/circle_key_lock_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "scavenger",
	diffuseMap = "assets/textures/monsters/scavenger_dif.tga",
	specularMap = "assets/textures/monsters/scavenger_spec.tga",
	normalMap = "assets/textures/monsters/scavenger_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 25,
	depthBias = 0,
}

defineMaterial{
	name = "shrakk_torr",
	diffuseMap = "assets/textures/monsters/shrakk_torr_dif.tga",
	specularMap = "assets/textures/monsters/shrakk_torr_spec.tga",
	normalMap = "assets/textures/monsters/shrakk_torr_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 45,
	depthBias = 0,
}

defineMaterial{
	name = "key_round",
	diffuseMap = "assets/textures/items/key_round_dif.tga",
	specularMap = "assets/textures/items/key_round_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "key_gear",
	diffuseMap = "assets/textures/items/key_gear_dif.tga",
	specularMap = "assets/textures/items/key_gear_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "key_ornate",
	diffuseMap = "assets/textures/items/key_ornate_dif.tga",
	specularMap = "assets/textures/items/key_ornate_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 50,
	depthBias = 0,
}

defineMaterial{
	name = "bone_amulet",
	diffuseMap = "assets/textures/items/bone_amulet_dif.tga",
	specularMap = "assets/textures/items/bone_amulet_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "fire_torc",
	diffuseMap = "assets/textures/items/fire_torc_dif.tga",
	specularMap = "assets/textures/items/fire_torc_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "bracelet_tirin_fortitude",
	diffuseMap = "assets/textures/items/bracelet_tirin_fortitude_dif.tga",
	specularMap = "assets/textures/items/bracelet_tirin_fortitude_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 30,
	depthBias = 0,
}

defineMaterial{
	name = "apprentice_orb",
	diffuseMap = "assets/textures/items/apprentice_orb_dif.tga",
	specularMap = "assets/textures/items/apprentice_orb_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "conjurers_hat",
	diffuseMap = "assets/textures/items/conjurers_hat_dif.tga",
	specularMap = "assets/textures/common/black.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "circlet_war",
	diffuseMap = "assets/textures/items/circlet_war_dif.tga",
	specularMap = "assets/textures/items/circlet_war_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "spirit_mirror_pendant",
	diffuseMap = "assets/textures/items/spirit_mirror_pendant_dif.tga",
	specularMap = "assets/textures/items/spirit_mirror_pendant_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 40,
	depthBias = 0,
}

defineMaterial{
	name = "herder",
	diffuseMap = "assets/textures/monsters/herder_dif.tga",
	specularMap = "assets/textures/monsters/herder_spec.tga",
	normalMap = "assets/textures/monsters/herder_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = true,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 40,
	depthBias = 0,
}

defineMaterial{
	name = "pitroot_bread",
	diffuseMap = "assets/textures/items/pitroot_bread_dif.tga",
	specularMap = "assets/textures/common/black.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "blooddrop_blossom",
	diffuseMap = "assets/textures/items/blooddrop_blossom_dif.tga",
	specularMap = "assets/textures/items/blooddrop_blossom_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "grimcap",
	diffuseMap = "assets/textures/items/grimcap_dif.tga",
	specularMap = "assets/textures/items/grimcap_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "wooden_box",
	diffuseMap = "assets/textures/items/wooden_box_dif.tga",
	specularMap = "assets/textures/items/wooden_box_spec.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "sack_full",
	diffuseMap = "assets/textures/items/sack_full_dif.tga",
	specularMap = "assets/textures/common/black.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 20,
	depthBias = 0,
}

defineMaterial{
	name = "ornament_door",
	diffuseMap = "assets/textures/env/ornament_door_dif.tga",
	specularMap = "assets/textures/env/ornament_door_spec.tga",
	normalMap = "assets/textures/env/ornament_door_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 60,
	depthBias = 0,
}

defineMaterial{
	name = "ornament_lock",
	diffuseMap = "assets/textures/env/ornament_lock_dif.tga",
	specularMap = "assets/textures/env/ornament_lock_spec.tga",
	normalMap = "assets/textures/env/ornament_lock_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 60,
	depthBias = 0,
}

defineMaterial{
	name = "cube",
	diffuseMap = "assets/textures/monsters/mechnical_cube_dif.tga",
	specularMap = "assets/textures/monsters/mechnical_cube_spec.tga",
	normalMap = "assets/textures/monsters/mechnical_cube_normal.tga",
	doubleSided = false,
	lighting = true,
	alphaTest = false,
	blendMode = "Opaque",
	textureAddressMode = "Wrap",
	glossiness = 70,
	depthBias = 0,
}

NOTE: Code continues in next post. The code was too large for a single post.
Define ... 'Lost.' Neverending Nights - The Neverwinter Machinima that WILL make you laugh!
Also read: Legend of Grimrock: Destiny's Chance here on the forum! Check out the site I made for Legend of Grimrock: Destiny's Chance.
Locked