# Surface Properties **Surfaces** are being abstracted into one API with the help of **SurfData** helper functions and large parts of NSSurfacePropEntity. # Preface {#preface} ## The problem {#the_problem} We need to define how a surface, speak a texture-mapped triangle, behaves when being interacted with. - What happens when e.g. a bullet collides with it? - What sounds does it make when it collides with other objects? - What physical properties does it have that make it special? ## History {#history} In GoldSrc and similar engines, you'd specify which material is used through 3 ways: - The surface is a map texture, with a short material character definition inside `sound/materials.txt` defining what the surface is made of. See (MatGoldSrc.md) for details. - The entity itself offers a list of materials to choose from for impact/breaking properties. For example `func_breakable` has the `material` key. Which then tells the rest of the codebase that this object will respond like whatever it's defined as. - The entity might hard-code what it's made of. For example you could say an entity will always be `glass`, or always be `metal`. Level designers can't change these. **In that engine, this attribute merely affected audio visual feedback like bullet impacts.** They all sounded the same when it came to physics etc. Nowadays the artists want more control, they want to decide if an entity uses special particle effects for impacts, or sounds - the sound it makes when it scrapes across the floor or gets shaken - the weight of the object and the friction it deals with. ## Understanding the new way {#understanding_the_new_way} So in Nuclide, there's a few options too as to how you're able to define what property anything is made of. - For the level geometry, a surfaceprop is used to define what material properties to use. There are a lot of basic materials to choose from there. - Entities can **specify** which entry from `scripts/surfaceproperties.txt` get's used. This is required for NSPhysicsEntity derived classes. Those entities set their `surfdata` or `materialdata` key/value field to be the name of an entity listed inside the `surfaceproperties.txt` file. - ...of course, the old way is supported as long as you're using a legacy format that does not support **surfaceprop**. They'll get mapped to the IDs specified in the surfaceproperties.txt file. And instead of defining a single character defining the audio visual appearance, you can now tweak every aspect of it. See **Scripting** below. Also, if an entity does not specify the material character inside the script, Nuclide will figure it out on a surrounding surfaceparm basis. # Scripting {#scripting} Scripts are formatted like our soundDefs: typename { key/value pairs ... } Available keys are: "base" what type to inherit "gamematerial" material character, e.g. W for wood "climbable" ??? "thickness" non-solid, air (?) thickness "density" material density in kg / m^3 "elasticity" 0.0 - 1.0 ; soft to hard "friction" friction multiplier "dampening" drag multiplier "jumpfactor" bouncyness? "maxspeedfactor" maxvelocity? "stepleft" footstep left "stepright" footstep right "fx_bulletimpact" particle effect to cast on impact "bulletimpact" soundDef to play on impact "scraperough" soundDef to play on rough scraping "scrapesmooth" soundDef to play on smooth scraping "impacthard" soundDef for hard impacts "impactsoft" soundDef for soft impacts "shake" sound to play when object is being shaken "strain" sound to play when object is being strained? "break" sound to play when object breaks "roll/rolling" sound to play when object rolls none of these are concerning us right now: "audioreflectivity" "audiohardnessfactor" "audioroughnessfactor" "scrapeRoughThreshold" "impactHardThreshold" "audioHardMinVelocity"