Furniture Modding

From Software Inc.
Jump to navigation Jump to search

Furniture modding

Furniture modding is available as of Alpha 8.10.13

Furniture packages should be located in subfolders in the “Furniture” folder with the game. A furniture package will inherit its name from the folder name.

You can reload furniture while in-game by bringing up the console and executing the RELOAD_FURNITURE command. You can generate thumbnails by bringing up the console in the main menu and executing the FURNITURE_THUMBNAIL command with the name of your furniture as parameter.

XML Generator

Furniture XML Generator This tool is currently under development, it is stable for producing basic XML files for objects

The XML and basic tags

Each furniture should be defined in separate XML files.

The root tag in a furniture xml file should have a Thumbnail attribute with a relative path to a 128x128 thumbnail it should use in-game.

The root tag can also have a Base attribute to inherit from an existing furniture from the game. If you define the attribute AutoBounds to “True”, the game will auto generate the navigation mesh, building boundary, vertical span, x and y grid offset, width and vertical offset for wall furniture, and collision box for selection, based on the furniture meshes, otherwise these can be controlled in the Furniture component by setting the variables BuildBoundary, NavBoundary, Height1, Height2, OnXEdge, OnYEdge, WallWidth, YOffset and the BoxCollider component.

You can check your build and navigation boundary, and interaction and snap points by enabling furniture debugging using the command "FURNITURE_DEBUG True" in the console and selecting the furniture you want to review in-game. The navigation boundary is located on the floor and goes from green to pink. The build boundary also illustrates Height1 and Height2 and goes from cyan to red. Interaction points are blue and snap points are yellow:

FurnDebug.png

It is highly recommended that you run the command EXPORT_FURNITURE_BOUNDS with your furniture name as parameter if you've used the AutoBounds attribute. This command bakes the bounds information in the XML file so it doesn't have to be recalculated each time the game launches. This command has been introduced in alpha 8.10.15.

Meshes and materials

Meshes will be loaded from the Models tag. The Models tag should contain children tags that define meshes. Each mesh tag should have a File tag, with the relative path to an obj file, a Position, Rotation and Scale. Optionally, the mesh tag can have a Parent tag, to make it a child transform of the ith mesh loaded (Zero index), a ComponentName tag to name the mesh for later reference and a Material tag to give it a material.

If no material is defined the furniture will use the default material which is much better performance wise and allows the player to colorize the furniture. Meshes using the default material should be UV mapped as shown below.

FurnitureMap.png

If you decide to use your own materials, you should have a Materials XML file in your furniture package folder, in which you define your materials. The Materials.xml file should have a root tag with material tags as children. Each material will be named as its tag and should have up to three children: Textures, Floats and Colors. All materials use Unity’s default material. If you want to set the texture you would write <_MainTex>test.png</_MainTex>. All textures will be loaded in 256x256. If you want to see all the colors, floats and textures you can change, refer to Unity’s default shader, which can be downloaded here: http://unity3d.com/get-unity/download/archive . Some variables include:

  • _MainTex
  • _BumpMap
  • _OcclusionMap
  • _Metallic
  • _Glossiness
  • _BumpScale
  • _Color

To apply the material to a model, simply add a Material tag to the model naming your material.

Interaction points

Interaction points control how employees can interact with a piece of furniture.

If you have used the Base attribute, the furniture will inherit its interaction points from the base furniture, unless you add the “InteractionPoints” tag.

Interaction points should define a Name, which at this point in time includes “Use”, “Repair”, “Serve”, “Social” and “Visit” for the base game. They should also have Position and Rotation defined. You can define a ComponentName tag to name the interaction points for later reference.

Interaction points can also define Animation(main animation used when interacting, ignored for some interactions), SubAnimation(used for repairs, 0, 1 or 2 for repair height), MinimumNeeded(how many need to be reachable before the player gets a warning) and ReachCheck(whether we should warn the player at all).

Finally, it can define a Child, which is the ith interaction point defined (Zero index). If you want a number of interaction points to only be used by one employee at a time you should define children such that they form a dependency loop(E.g. 0->1->2->3->0). When one interaction point gets reserved, the children will recursively get reserved as well.

Snap points

Snap points are points at which certain furniture can be snapped to other furniture, like chairs to tables.

If you have used the Base attribute, the furniture will inherit its snap points from the base furniture, unless you add the “SnapPoints” tag.

Snap points should define a Name, which will control which furniture can snap to it, currently in use in the base game is “PCAddon”, “AtTable” and “OnTable”. “Food” is also used in the game for tables which should allow for food but not OnTable furniture, like benches. They should also have Position and Rotation defined.

You can define a ComponentName tag to name the snap point for later reference.

Snap points can also have “CheckValid” defined, which controls whether the game should allow for something to be placed no matter if there are collisions. This calculation is heavy, but not needed for stuff like computers and computer add-ons.

Finally, snap points can define Links, which is a comma separated list of linked snap points, referencing the ith snap point defined (zero index). Links are currently used to link chairs with computers and chairs with food. E.g. for the square table, the OnTable point is linked to all AtTable points around it. The bench does not have chairs and instead the “Use” interaction points are defined in the same order as its “Food” snap points so the game knows where to put the employee’s food and how to save it to a file.

Replacements/upgrading

The root tag can use the UpgradeFrom and UpgradeTo attributes to control which furniture can be replaced with your furniture and which furniture your furniture can be replaced with.

<Root UpgradeFrom="Server" UpgradeTo="Big Server">

This furniture can be upgraded to any furniture that has UpgradeTo="Server" and UpgradeTo="Big Server", but it cannot be upgraded FROM furniture that has UpgradeTo="Server". This is to avoid upgrading a server that sits on the floor to a server that sits on a table, as the table would have to be created out of thin air.

In-game upgrade groups

  • Computer
  • Floor Decoration
  • Server
  • Big Server
  • PCAddon
  • Chair
  • Coffee
  • Couch
  • Table Decoration
  • Standard Table
  • Tree
  • ProductPrinter

Limitations

Replacing wall furniture is currently not supported.

The game will be able to destroy tables if you're replacing something on a table with something that is not on a table, e.g. small server and server rack, but not the other way around. The game won't build new tables automatically, so you should be careful in differentiating between "UpgradeFrom" and "UpgradeTo", as these will not always be the same.

Components

Other than the tags described so far, all tags are interpreted as Unity MonoBehaviour components. If you added a tag called “<BoxCollider>”, the children tags would be interpreted as variables of the BoxCollider component and if the component does not exist, it will be instantiated for the Furniture. All MonoBehaviour variables in a Component will use the ComponentName reference set in the other tags, or alternatively you can add a Transforms tag to define empty objects with a Name, Position and Rotation. Using “self” as a value for a MonoBehaviour variable will find the corresponding component in the furniture object itself. This allows for anything to be added to a furniture, even MonoBehaviors from custom mods.

If you set the Parent attribute to a ComponentName reference or Transforms reference, the component will be fetched/added to the object instead. This could be used to add a PointLight component to an empty object to make your own lights. Make sure to add a LampScript component to your furniture object if you’re making a custom lamp, so the game can control shadows and lighting.

Setting a Destroy attribute to “True” for a tag will remove that MonoBehavior from the furniture.

Note that using MonoBehaviors from other mods requires setting the Namespace attribute and the Assembly attribute so the game knows where to find the classes, e.g. <MyCustomComponent Namespace=”MyMod.Behaviours.” Assembly=”MyMod”>.

Furniture

This component will always be present in a furniture. Common variables to edit would be:

  • Type
  • Category
  • FunctionCategory
  • Cost
  • ButtonDescription
  • ComputerPower
  • RoleBuffs
  • Lighting
  • Coffee
  • Wait
  • AuraValues
  • Wattage
  • Water
  • Noisiness
  • Comfort
  • Environment
  • DefaultColorGroup
  • PrimaryColorName
  • SecondaryColorName
  • TertiaryColorName
  • ColorPrimaryEnabled
  • ColorSecondaryEnabled
  • ColorTertiaryEnabled
  • ForceColorSecondary
  • ForceColorTertiary
  • ColorPrimaryDefault
  • ColorSecondaryDefault
  • ColorTertiaryDefault
  • ColorableLights
  • LightPrimary
  • BuildBoundary
  • NavBoundary
  • OnXEdge
  • OnYEdge
  • CanRotate
  • Height1
  • Height2
  • YOffset
  • WallWidth
  • BasementValid
  • OnlyExteriorWalls
  • WallFurn
  • IsSnapping
  • SnapsTo
  • CanAssign
  • ValidIndoors
  • ValidOutdoors
  • ValidOnFence
  • MaxQueue
  • ForceAccessible
  • ITFix
  • UnlockYear
  • TemperatureController
  • HeatCoolPotential
  • EqualizeTemperature
  • AlwaysOn
  • ComputerTransform
  • OriginalOffset
  • PCAddonOffset
  • OriginalRotation
  • PCAddonRotation
  • PokesThroughWall
  • CanLean
  • UseStandardMat
  • TwoFloors
  • OffsetPoints
  • InterPoints
  • UpperFloorFrame
  • HoldablePoints
  • DespawnHoldables
  • DespawnHour

Upgradable

This component makes this furniture repairable. Common variables to edit would be:

  • TheScreen
  • SmokePosition
  • TimeToAtrophy
  • UpgradePrice
  • OnMat
  • OffMat
  • DegradeAlways
  • AffectedByTemp

TableScript

This component handles tables and table grouping for meeting, canteens, etc.

LampScript

This component handles lighting and shadows for lamps.

Server

This component makes this furniture a server. It is recommended to inherit from a server furniture, as the server component uses some in-game objects, like a text mesh and a wire mesh. Use the Power variable to change its power in mb.

Example

<Root Base="Server Rack" Thumbnail="BigServerRackThumb.png" UpgradeFrom="Server Rack">
	<Models>
		<Model>
			<File>BigServerRack.obj</File>
			<Position>0,0,0</Position>
			<Rotation>0,270,0</Rotation>
			<Scale>1,1,1</Scale>
		</Model>
	</Models>
	<InteractionPoints>
		<InteractionPoint>
			<Name>Repair</Name>
			<Position>0,0,1</Position>
			<Rotation>0,180,0</Rotation>
			<Animation>Repair</Animation>
			<Child>1</Child>
		</InteractionPoint>
		<InteractionPoint>
			<Name>Repair</Name>
			<Position>0,0,-1</Position>
			<Rotation>0,0,0</Rotation>
			<Animation>Repair</Animation>
			<Child>0</Child>
		</InteractionPoint>
	</InteractionPoints>
	<Furniture>
		<Cost>12000</Cost>
		<Wattage>50</Wattage>
		<Noisiness>2</Noisiness>
		<UnlockYear>2010</UnlockYear>
		<ButtonDescription>When you can't get enough server</ButtonDescription>
		<ColorPrimaryDefault>0.2,0.2,0.2,1</ColorPrimaryDefault>
		<PrimaryColorName>0.2,0.2,0.2,1</PrimaryColorName>
		<ColorSecondaryDefault>0.3,0.3,0.3,1</ColorSecondaryDefault>
		<ColorTertiaryDefault>0,0.8,1,1</ColorTertiaryDefault>
		<ColorSecondaryEnabled>True</ColorSecondaryEnabled>
		<ColorTertiaryEnabled>True</ColorTertiaryEnabled>
		<ForceColorSecondary>False</ForceColorSecondary>
		<ForceColorTertiary>False</ForceColorTertiary>
		<PrimaryColorName>Casing</PrimaryColorName>
		<SecondaryColorName>Casing</SecondaryColorName>
		<TertiaryColorName>LED</TertiaryColorName>
		<BuildBoundary>
-0.99,-0.49
0.99,-0.49
0.99,0.49
-0.99,0.49</BuildBoundary>
		<NavBoundary>
-1,-0.5
1,-0.5
1,0.5
-1,0.5</NavBoundary>
		<Height1>0</Height1>
		<Height2>1.8</Height2>
		<OnXEdge>True</OnXEdge>
	</Furniture>
	<Upgradable>
		<UpgradePrice>1000</UpgradePrice>
	</Upgradable>
	<Server>
		<Power>10000</Power>
	</Server>
	<BoxCollider>
		<center>0,0.9,0</center>
		<size>2,1.8,1</size>
	</BoxCollider>
</Root>