Primitive Asset Definition Reference

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
User avatar
JohnWordsworth
Posts: 1397
Joined: Fri Sep 14, 2012 4:19 pm
Location: Devon, United Kingdom
Contact:

Primitive Asset Definition Reference

Post by JohnWordsworth »

Well, with all of these useful lists and posts going around - I couldn't resist contributing... I've written a bit of lua code that runs in a mod and scrapes all of the "standard asset" definitions. It doesn't (can't?) scrape the contents of the functions in the asset definitions, but I think it grabs all of the rest of the properties. Anyway, it should give you an idea of what properties are available on certain components!

https://drive.google.com/file/d/0B2rfBg ... ZibFk/view

Something to tide you over until the asset definition reference / the asset pack comes out! Note. For things like "size" and "offset", the engine shows tables, but I think you should probably be defining some of these properties using the vec() function. For anyone interested, here is the script used to grab the data: https://drive.google.com/file/d/0B2rfBg ... hhZlk/view

Enjoy!
My Grimrock Projects Page with links to the Grimrock Model Toolkit, GrimFBX, Atlas Toolkit, QuickBar, NoteBook and the Oriental Weapons Pack.
User avatar
Prozail
Posts: 158
Joined: Mon Oct 27, 2014 3:36 pm

Re: Primitive Asset Definition Reference

Post by Prozail »

Very nice work! Thanks alot!
NutJob
Posts: 426
Joined: Sun Oct 19, 2014 6:35 pm

Re: Primitive Asset Definition Reference

Post by NutJob »

I'm pretty new when it comes to making my own asset, never tried before, other then doing through scripts. If I wanted to make a dungeon wall entity have collision how would I do it?

I just tried this (added the Obstacle Class):

Code: Select all

defineObject{
	baseObject = "base_wall",
	name = "dungeon_wall_03",
	components = {
		{
			name = "model",
			class = "Model",
			staticShadow = true,
			model = "assets/models/env/dungeon_wall_02.fbx"
		},
		{
			model = "assets/models/env/dungeon_wall_01_occluder.fbx",
			name = "occluder",
			class = "Occluder"
		},
		{
			name = "obstacle",
			class = "Obstacle"
		},
	},
	minimalSaveState = true
}
It adds collision but for the entire block. I want the wall itself only to have collision (like a door).

Edit: and thanks John, this is wonderful work/OP.
User avatar
Prozail
Posts: 158
Joined: Mon Oct 27, 2014 3:36 pm

Re: Primitive Asset Definition Reference

Post by Prozail »

NutJob wrote:If I wanted to make a dungeon wall entity have collision how would I do it?
Sorry to say, you can't. The only option is the "Door" entity.
viewtopic.php?f=22&t=8308
User avatar
QuintinStone
Posts: 72
Joined: Sat Nov 01, 2014 9:58 pm

Re: Primitive Asset Definition Reference

Post by QuintinStone »

I don't think you'll want base_wall for something that doesn't take up a full tile.

For example, the forest_ruins_wall_01:

Code: Select all

defineObject{
	components = {
		{
			name = "model",
			class = "Model",
			staticShadow = true,
			model = "assets/models/env/forest_ruins_wall_01.fbx"
		},
		{
			name = "door",
			class = "Door"
		},
		{
			model = "assets/models/env/forest_ruins_wall_01_occluder.fbx",
			name = "occluder",
			class = "Occluder"
		}
	},
	minimalSaveState = true,
	automapIcon = 88,
	name = "forest_ruins_wall_01",
	editorIcon = 160,
	placement = "wall"
}
They seem to be doors that can't be opened.
Crypt of Zulfar
GoldenShadowGS
Posts: 168
Joined: Thu Oct 30, 2014 1:56 am

Re: Primitive Asset Definition Reference

Post by GoldenShadowGS »

They can still be opened, it looks funny too. Just don't connect a button, etc.. to one and it would never open for the player.
NutJob
Posts: 426
Joined: Sun Oct 19, 2014 6:35 pm

Re: Primitive Asset Definition Reference

Post by NutJob »

I see, thanks Quintin. That wall is actually what I have been using , with the model disabled, when I generate certain parts of my dungeon. Then I just place the wall I actually want to use at the same coordinates.

Oh well, the gate node gating my way to how I want use walls in my tightly created mazes.
User avatar
Doridion
Posts: 256
Joined: Tue Jun 10, 2014 9:23 pm

Re: Primitive Asset Definition Reference

Post by Doridion »

First, many, many, many thanks JohnW !!!!
QuintinStone wrote:I don't think you'll want base_wall for something that doesn't take up a full tile.

For example, the forest_ruins_wall_01:

Code: Select all

defineObject{
	components = {
		{
			name = "model",
			class = "Model",
			staticShadow = true,
			model = "assets/models/env/forest_ruins_wall_01.fbx"
		},
		{
			name = "door",
			class = "Door"
		},
		{
			model = "assets/models/env/forest_ruins_wall_01_occluder.fbx",
			name = "occluder",
			class = "Occluder"
		}
	},
	minimalSaveState = true,
	automapIcon = 88,
	name = "forest_ruins_wall_01",
	editorIcon = 160,
	placement = "wall"
}
They seem to be doors that can't be opened.
Totally normal Quintin, i'm using the same trick to make "thin" wall. It's the only way to have wall as thin as a door. If you see in the ODS the wood walls, it's exactly the same thing ( already used in log1 in my dungeons ).
Last edited by Doridion on Fri Nov 21, 2014 12:30 am, edited 1 time in total.
User avatar
Doridion
Posts: 256
Joined: Tue Jun 10, 2014 9:23 pm

Re: Primitive Asset Definition Reference

Post by Doridion »

JohnW, for who could be interessed, i'm actually reorganising this awesome bank of informations to be more readable, and I actually inderstand more in few minutes than in one week of coding ..... and more else, why most of our assets where not working well.

AH declares objects in 2 times :
- First stage => Declaring "general" element
- Second stage => Cloning the general element, and adding part of classes to specify it.

Below are all the objects basis definitions reorderer :
SpoilerShow

Code: Select all

-- In order : Ceiling, Wall, Floor, Pillar, Alcove, Altar, Pressure plate, Wall decoration, Floor decoration, Pillar decoration, Wall text, Stair down, Stair Up, Pit, Pit trapdoor, Ceiling shaft, Obstacle, Door

defineObject{
	name = "base_ceiling",
	replacesCeiling = true,
	placement = "ceiling"
	editorIcon = 100,
}

defineObject{
	name = "base_wall",
	replacesWall = true,
	placement = "wall"
	editorIcon = 120,
}

defineObject{
	name = "base_floor",
	replacesFloor = true,
	killHeightmap = true,
	placement = "floor"
	editorIcon = 100,
}

defineObject{
	name = "base_pillar",
	placement = "pillar",
	automapIcon = 92
	editorIcon = 108,
}

defineObject{
	name = "base_alcove",
	components = {
		{
			class = "Surface"
			name = "surface",
			offset = { 0, 0.85, 0.2, 0 },
			size = { 1.3, 0.65, 0, 0 },
		},
		{
			class = "Clickable"
			name = "clickable",
			offset = { 0, 1.25, 0.2, 0 },
			size = { 1.3, 0.8, 0.65, 0 },
		}
	},
	replacesWall = true,
	placement = "wall"
	editorIcon = 8,
}

defineObject{
	name = "base_altar",
	components = {
		{
			class = "Surface"
			name = "surface",
			offset = { 0, 0.88, 0, 0 },
			size = { 2.1, 1.2, 0, 0 },
		},
		{
			class = "Clickable",
			name = "clickable"
			offset = { 0, 0.88, 0, 0 },
			size = { 2.1, 1.76, 1.2, 0 },
			maxDistance = 1,
		},
		{
			class = "Obstacle"
			name = "obstacle",
		},
		{
			class = "ProjectileCollider"
			name = "projectilecollider",
		}
	},
	placement = "floor"
	editorIcon = 52,
}

defineObject{
	name = "base_pressure_plate",
	components = {
		{
			class = "FloorTrigger",
			name = "floortrigger",
			pressurePlate = true,
			activateSound = "pressure_plate_pressed",
			deactivateSound = "pressure_plate_released"
		}
	},
	replacesFloor = true,
	killHeightmap = true,
	placement = "floor"
	automapIcon = 112,
	editorIcon = 0,
}

defineObject{
	name = "base_wall_decoration",
	placement = "wall"
	editorIcon = 120,
}

defineObject{
	name = "base_floor_decoration",
	placement = "floor"
	editorIcon = 100,
}

defineObject{
	name = "base_pillar_decoration",
	placement = "pillar"
	editorIcon = 120,
}

defineObject{
	name = "base_wall_text",
	components = {
		{
			class = "WallText"
			name = "walltext",
		},
		{
			class = "Clickable"
			name = "clickable",
			offset = { 0, 1.5, 0, 0 },
			size = { 1.2, 0.8, 0.2, 0 },
			frontFacing = true,
		}
	},
	replacesWall = true,
	placement = "wall"
	editorIcon = 28,
}

defineObject{
	name = "base_stairs_down",
	components = {
		{
			class = "Stairs"
			name = "stairs",
			direction = "down",
		},
		{
			blockParty = false,
			blockMonsters = true,
			class = "Obstacle",
			blockItems = false,
			name = "obstacle"
		}
	},
	killHeightmap = true,
	placement = "floor"
	automapIcon = 100,
	editorIcon = 48,
}

defineObject{
	name = "base_stairs_up",
	components = {
		{
			class = "Stairs"
			name = "stairs",
			direction = "up",
		},
		{
			class = "Obstacle",
			name = "obstacle"
			blockParty = false,
			blockMonsters = true,
			blockItems = false,
		}
	},
	killHeightmap = true,
	automapIcon = 96,
	placement = "floor"
	editorIcon = 44,
}

defineObject{
	name = "base_pit",
	components = {
		{
			class = "Pit"
			name = "pit",
		}
	},
	replacesFloor = true,
	killHeightmap = true,
	automapIcon = 108,
	placement = "floor"
	editorIcon = 40,
}

defineObject{
	name = "base_pit_trapdoor",
	components = {
		{
			class = "Pit"
			name = "pit",
		},
		{
			class = "Platform"
			name = "platform",
		},
		{
			class = "Controller",
			name = "controller",
			onOpen = function() print('Cannot Scrape Functions'); end,
			onClose = function() print('Cannot Scrape Functions'); end,
			onToggle = function() print('Cannot Scrape Functions'); end
		}
	},
	replacesFloor = true,
	killHeightmap = true,
	placement = "floor"
	automapIcon = 108,
	editorIcon = 40,
}

defineObject{
	name = "base_ceiling_shaft",
	replacesCeiling = true,
	placement = "ceiling"
	editorIcon = 104,
}

defineObject{
	name = "base_obstacle",
	tags = { "obstacle" },
	components = {
		{
			class = "Obstacle"
			name = "obstacle",
			hitSound = "impact_blunt",
		},
		{
			class = "ProjectileCollider"
			name = "projectilecollider",
		}
	},
	placement = "floor"
	editorIcon = 56,
}

defineObject{
	name = "base_door",
	tags = { "door" },
	components = {
		{
			class = "Door",
			name = "door",
			openVelocity = 1.3,
			closeVelocity = 0,
			closeAcceleration = -10,
			killPillars = true
		},
		{
			class = "Controller",
			name = "controller",
			onOpen = function() print('Cannot Scrape Functions'); end,
			onClose = function() print('Cannot Scrape Functions'); end,
			onToggle = function() print('Cannot Scrape Functions'); end
		},
		{
			class = "ItemConstrainBox",
			name = "cbox1",
			offset = { -1.5, 1.5, 0, 0 },
			size = { 0.7, 3, 0.7, 0 }
		},
		{
			class = "ItemConstrainBox",
			name = "cbox2",
			offset = { 1.5, 1.5, 0, 0 },
			size = { 0.7, 3, 0.7, 0 }
		}
	},
	placement = "wall",
	automapIcon = 84
	editorIcon = 124,
}
PS : Excellent discover ! We can now sort elements by adding them tags = { "XXXX" }, !!!!! Loving you JohnW ! :mrgreen:

*Crazy mode : Activated*

Example of door definition :
SpoilerShow
Basis door definition

Code: Select all

defineObject{
	name = "base_door",
	tags = { "door" },
	components = {
		{
			class = "Door",
			name = "door",
			openVelocity = 1.3,
			closeVelocity = 0,
			closeAcceleration = -10,
			killPillars = true
		},
		{
			class = "Controller",
			name = "controller",
			onOpen = function() print('Cannot Scrape Functions'); end,
			onClose = function() print('Cannot Scrape Functions'); end,
			onToggle = function() print('Cannot Scrape Functions'); end
		},
		{
			class = "ItemConstrainBox",
			name = "cbox1",
			offset = { -1.5, 1.5, 0, 0 },
			size = { 0.7, 3, 0.7, 0 }
		},
		{
			class = "ItemConstrainBox",
			name = "cbox2",
			offset = { 1.5, 1.5, 0, 0 },
			size = { 0.7, 3, 0.7, 0 }
		}
	},
	placement = "wall",
	automapIcon = 84
	editorIcon = 124,
}
+

Code: Select all

defineObject{
	baseObject = "base_door",
	name = "base_door_sparse",
	components = {
		{
			class = "Door",
			name = "door",
			killPillars = true,
			openVelocity = 1.3,
			closeVelocity = 0,
			closeAcceleration = -10,
			sparse = true
		}
	}
}
Why ? Simply because to specify a door, it's more simple to only add specialised elements and not repeating all first common classes ! So clever !!! Raaahhh !! I go learning guys ( and girls of course ) !
NutJob
Posts: 426
Joined: Sun Oct 19, 2014 6:35 pm

Re: Primitive Asset Definition Reference

Post by NutJob »

Nevermind this question.

Looking for a correct way to redefine every monsters loot table (have no loot) while keeping everything else the same. I'll use a Skeletal Trooper for this example:


All its base assets.
SpoilerShow

Code: Select all

defineObject{
	baseObject = "base_monster",
	name = "skeleton_trooper",
	components = {
		{
			name = "model",
			class = "Model",
			storeSourceData = true,
			model = "assets/models/monsters/skeleton_knight_trooper.fbx"
		},
		{
			animations = {
				turnRightNormal = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_turn_right.fbx",
				fall = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_get_hit_front_left.fbx",
				attack = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_attack.fbx",
				turnRight = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_turn_right.fbx",
				turnLeftNormal = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_turn_left.fbx",
				getHitFrontLeft = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_get_hit_front_left.fbx",
				turnAttackLeft = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_turn_attack_left.fbx",
				turnAttackRight = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_turn_attack_right.fbx",
				getHitBack = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_get_hit_back.fbx",
				getHitFrontRight = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_get_hit_front_right.fbx",
				moveForward = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_walk.fbx",
				turnLeft = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_turn_left.fbx",
				idle = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_idle.fbx",
				getHitLeft = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_get_hit_left.fbx",
				getHitRight = "assets/animations/monsters/skeleton_knight_trooper/skeleton_knight_trooper_get_hit_right.fbx"
			},
			class = "Animation",
			name = "animation",
			currentLevelOnly = true
		},
		{
			lootDrop = {
				50,
				"skullcleave",
				50,
				"skeleton_knight_helmet",
				50,
				"skeleton_knight_shield"
			},
			hitSound = "skeleton_hit",
			health = 150,
			immunities = {
				"sleep",
				"blinded"
			},
			hitEffect = "hit_dust",
			capsuleRadius = 0.25,
			protection = 5,
			resistances = {
				poison = "immune",
				shock = "weak"
			},
			class = "Monster",
			footstepSound = "skeleton_footstep",
			traits = {
				"undead"
			},
			onUnlinkMonsterGroup = function() print('Cannot Scrape Functions'); end,
			evasion = 0,
			capsuleHeight = 0.7,
			exp = 100,
			meshName = "skeleton_knight_trooper_mesh",
			dieSound = "skeleton_die",
			name = "monster",
			collisionRadius = 0.6
		},
		{
			morale = 100,
			class = "MeleeBrain",
			name = "brain",
			sight = 4
		},
		{
			sound = "skeleton_walk",
			class = "MonsterMove",
			name = "move",
			cooldown = 6
		},
		{
			sound = "skeleton_walk",
			class = "MonsterTurn",
			name = "turn"
		},
		{
			onBeginAction = function() print('Cannot Scrape Functions'); end,
			cooldown = 4,
			sound = "skeleton_trooper_attack",
			class = "MonsterAttack",
			name = "basicAttack",
			attackPower = 20
		},
		{
			turnToAttackDirection = true,
			cooldown = 4,
			sound = "skeleton_trooper_attack",
			class = "MonsterAttack",
			name = "turnAttack",
			attackPower = 20
		}
	}
}
So if wanted redefine this monster all I'd have to do is keep the 1) same name, 2) base_object and 3) remove all Classes I want to stay the same?
SpoilerShow

Code: Select all

defineObject{
	baseObject = "base_monster",
	name = "skeleton_trooper",
		{
			lootDrop = {},
			hitSound = "skeleton_hit",
			health = 150,
			immunities = {
				"sleep",
				"blinded"
			},
			hitEffect = "hit_dust",
			capsuleRadius = 0.25,
			protection = 5,
			resistances = {
				poison = "immune",
				shock = "weak"
			},
			class = "Monster",
			footstepSound = "skeleton_footstep",
			traits = {
				"undead"
			},
			onUnlinkMonsterGroup = function() print('Cannot Scrape Functions'); end,
			evasion = 0,
			capsuleHeight = 0.7,
			exp = 100,
			meshName = "skeleton_knight_trooper_mesh",
			dieSound = "skeleton_die",
			name = "monster",
			collisionRadius = 0.6
		}
	}
}
I want to do this because I prefer monster to never drop items and I'll generate them myself (will just use addItem through scripts when needed).



---- Edit ----

Doridion, tags puts the item in to a category inside the left panel drop down filter? Can any tag be used? This would be helpful only if it can be user made in my opinion (or I just got used to what's available). I'll give it a try. Hopefully tags = { "Weapons, Level 1", "Club", "Melee" } will work. If not, not very useful.
Last edited by NutJob on Fri Nov 21, 2014 1:23 am, edited 1 time in total.
Post Reply