"From Earth" takes place close to the year 3,000 when one woman and one man, Zenaida and Anthony, are sent to a remote alien planet. After fifty years in cold sleep, they find themselves on a recently industrialised world being hunted by an alien government. They have only their wits, athleticism and the remains of their equipment to keep them alive. In this first person singleplayer experience, the player takes control of Zenaida Liu upon arriving on the planet. From Earth's gameplay is very much about your relationship to this world and its technology, requiring you to figure out how it all works and encouraging cooperation with the local population. Nothing about the alien technology is explained to players. It's about experimentation and learning what's what and how things on this planet work. The player also has some athletic abilities, such as climbing, wall running, hanging on ledges and so on.

Report RSS Merging Items

If you missed the previous article about Custom Items consider reading it first, as it explains some of how the items work in From Earth. Item Merging or the "Crafting System" is one of those features that I feel like shouldn't have been added, or I should have had the self-control not to add. It adds some value, but I feel like it's still too limited, or not explored enough to add enough value.

Posted by on


If you missed the previous article about Custom Items consider reading it first, as it explains some of how the items work in From Earth. Item Merging or the "Crafting System" is one of those features that I feel like shouldn't have been added, or I should have had the self-control not to add. It adds some value, but I feel like it's still too limited, or not explored enough to add enough value.

Here's how merging items works in From Earth.

Tehnical

There's two type of item merging. Either two entities/models can merge into a new entity or a child item can attach into a host item. Both versions have benefits.

Merging entities into one
This is more rare. Currently only few items do this. It's more complicated to set up. Currently I don't allow this for custom items. The problem would not only be ensuring that the resulted item has the same value as the combination of the values of the previous two items, but also just setting up the code for it. I might add it later as an update.

The benefit from this is not only that is saves in entity count, but it's a bit cheaper when you don't need to calculate the item attachment positions and the child item positions.

Attaching items into each other
This works by having items merge to each other by attachments ("merge01" to "merge08"). This is still limited. The host item needs to be defined to allow be used as a host. The child item needs to be defined to allow to be used as a child. Currently only a handful of items are allowed to be used as a host, mostly weapons.

There's a list of merge points. The attachment for the specific merge point need be defined in both models or they wont merge. For example, rifle has a "gun barrel" merge point. You wouldn't want something that is meant to attach to the front of the armour to attach into the barrel. The attaching model can replace part of the host model (part of the model is hidden by bodygroups).

By default custom items can only be used as a child item. In they "hlss_settings" $keyvalues section you can define one of the merge points to be used as a host. If a merge point is used as a host, it can't be used as a child point as well on that model.

So, this is still kind of limited system, though it would help with just simply starting to add the attachments on more models.

Functions

So what does merging items together do? Merged items can affect all sort of values and even functions in its child or parent items. Some of them can only be done by hardcoded items, but big part of them are available for custom items.

So here's a list of some of the things you can modify:

  • Changing damage type or adding damage types into melee attacks
  • Removing or enabling effects from existing weapons
  • Neutralizing type of damage when the item is worn
  • Light color (for existing items that have lights/glows in them)
  • Color of the muzzle effect
  • Settings on an item
  • Rifle aim cone
  • Rifle ammo type
  • Adding or removing how much energy there is
  • Changing the required energy
  • Blade length (if the item replaces a sword blade)
  • Range and melee damage
  • Fire rate and delay
  • User damage
  • Increasing how much melee attacks do damage when the user is wearing the host item
  • Adding or removing predefined effects
  • How fast the item should detoriate (if it's a breakable model)
  • Increasing or decreasing how much wearables shield damage
  • Increasing or decreasing how much goggles zoom

Values can be changed by few different ways: "set", "multiply", "add", "subtract", "divide", "reverse". Some values have minimum and maximum values.

Now this is kind of a limited list right now. Like said before, some items also have hardcoded functions that are modified by other items, and those are not mentioned here. A lot of these are also hardcoded into the existing non-custom items.

In my previous article I talked about custom items and buttons and how I am not sure how I should define functions for buttons. The problem is the same here, I am not sure how I can add a lot of interesting modifiable functions without adding some kind of scripting language. I have never really tried LuA myself since I haven't seen any point in it when I can program everything with C++ myself. I suppose the benefit would be that all of the code would not be loaded at the same time?

Anyway, I am still thinking of how I could improve the merging system. Right now it revolves around few usable items. When I started the system, I was hoping for something that could result in unforseen results, something where items could interact with each other in unpredictable ways. I am not sure if this would be really something could happen with this system. I suppose one problem is that the list of modifiable values is still quite short.

I started adding more merging options for items, though I am not sure if it will just create noise and make it harder to recognize the actually useful items. I was also thinking of player ability to see what the item abilities were when examining the item, but it would be a bit work (basically I would need to hook up each merge variable change function with a piece of code that describes it, and program an UI that draws those on the screen). It would help with players having to try every item aimlessly, but at the same time it would be against the philosophy of the game: Zenaida doesn't know the alien technology and wouldn't know what the item would do.

With some items like armour Zenaida can tell how good it's protecting against damage just by looking at the material it is made of (you can see the armour value when examining). When you look at something like a rifle, you can see the buttons and which mouse key activates, but there's no descriptions what the buttons do. The player has to experiment to find out. But with merging items, it's slower to try merge items together and see what the effect is, so I am thinking of something that would make it easier to figure out what combinations are possible and even what they do.

Physics

When merging objects together the physics can be a bit complicated. The item can get bigger or smaller depending how the items are attached to the host. The rifle for example, can have a barrel replacement that is shorter than the normal barrel. The sword can also have blade replacements, and can also break. So, I wanted the item physics object to match the size of the new merged item. First I thought this was nearly impossible, but there's surprisingly lot of access to the physics object creation.


Creating physics from hitboxes.
This is probably the easiest to do. I can access the hitbox data from the CStudioHdr class and iterate through them. I can then calculate the world positions of those boxes and create convex physics pieces out of them. I can use hitbox groups to determine which merge attachment point it belongs to. If the bodygroup mesh for that attachment point is hidden, then that hitbox should be ignored. For each child item, I need to calculate the hit box positions in respect to the host item.

Creating physics from the model physics.
This is slightly more complicated. I need to fetch the data about all the convex pieces in the model physics. Good example of this is in UTIL_CreateScaledPhysObject function in props.cpp. I also need to translate each convex piece to match the host item's local space.

I also noticed that the item physics CPhysCollide isn't really showing up correctly in the client side, though I am not sure why this is. To visualize the new physics object, I needed to include the code that creates the CPhysCollide object on both server and client, and recreate it and draw it when v_collidewireframe is set to 1. When I was implementing this code, there was few cases where the server and client side code had mistmatching physics (something on the server side was causing the physics to be created incorrectly). I had to create a helper function that would do traces on the physics object to draw debug lines on the physics object to show its true shape.

Creating merged objects their own physics might not be 100% necessary. I could have done with the items just having the original physics object. There was a lot of problems with merged child items going through walls and floors, which looked weird, so this fixed that problem. There might also be a problem where item would end up having too many convex pieces as a result of being merged from so many objects. I could also try to create some kind of code that checks if the child item is so completely enveloped by the host item, so that there's no need to create convex pieces from it.

Example

$keyvalues
{ 
	"hlss_settings"
	{
		"animations" 		"default"
		"energy"			"0.5"
		"scanned"			"1"
		"disintegrated"		"1"
		"throw"			"1"
	}

	"hlss_merge"
	{
		//These two should match
		"spawn beams energy"
		{
			"value1"		"0.1"
			"parent"		"1"
		}

		"wearable melee energy"
		{
			"parent"	"1"
			"value1"	"0.1"
			"type"	"add"
		}

		"wearable melee"
		{
			"parent"	"1"
			"value1"	"1.5"
			"type"	"multiply"
		}

		"spawn beams"
		{
			"value1"		"beams1"
			"value2"		"beams2"
			"parent"	"1"
		}

		"spawn beams dist"
		{
			"calculation"	"set"
			"value1"		"2.7"
			"parent"	"1"
		}
	
		"spawn beams width"
		{
			"parent"	"1"
			"value1"	"0.4"
		}

		"spawn beams length"
		{
			"calculation"	"set"
			"value1"		"4"
			"parent"	"1"
		}

		"neutralize shock damage"
		{
			"parent"	"1"
			"value1"	"1"
		}

		"shock damage"
		{
			"parent"	"1"
			"value1"	"1"
		}	
	}
}
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: