Monday, July 21, 2025

How to make add-on parts for cars

    Introduction

    Since the advent of Binary, its associated Speedreflect library and Unlimiter with Extra/Extended Customization support, Black Box NFS games modding possibilites went up exponentially, amongst them there's the possibility of adding new car parts - and even make them car-specific or even without modifying the original game's geometry files. To this day, there is no concise documentation on the subject; hence I'm doing this write up to at least cover the basics with regards to NFS Underground 2 and NFS Most Wanted

    How parts work?

    For most Black Box games, part data is stored in GLOBAL\GlobalB.lzc; in Binary it's located in DBModelParts section. Each vehicle and part type (wheels, spoilers, paint, vinyls, etc.) has it's own DBModelParts node, which can be imported, exported, added, copied or deleted; to open a node, simply double-click on it. To rename a node, change its CollectionName value.

     



    Each node has the vehicles or parts set's part list, each part has the following basic editable properties (which are shown in bold in Binary):
    • CarPartGroupID (dropdown): what part slot (type of part) does the part use. For example, a hood uses the HOOD CarPartGroupID. Check the SlotTypes section in Binary to see what part slots are available.
    • DebugName (string): debug name of the part, shown only in debug menu or when there's no LANGUAGES\<language>.bin file string associated to it in the part attributes (more on that later). For example: STYLE02_HOOD.
    • LodStruct: a set of properties that sets up what parts from the car or part set GEOMETRY.BIN file uses, if the part has geometry associated with it, like body kits and so.
      • Concatenator (string): part of the name after the XNAME (e.g. FOCUS) and before the last part of the part name (e.g. _FRONT_BUMPER). For example _KIT00
        • ConcatenatorExists (boolean): enables/disables usage of concatenator
      • Exists (boolean): enables/disables geometry for the part
      • Geometry0Lod(A/B/C/D/E) (string): part name for the corresponding LOD of primary geometry for the part. If it uses concatenator,it's the last part of the part name without the LOD letter (e.g. _REAR_BUMPER), otherwise use the full part name (e.g. COROLLA_STYLE01_WHEEL)
        • Geometry0Lod(A/B/C/D/E)Exists (boolean): enables/disables corresponding LOD
      • Geometry1Lod(A/B/C/D/E) (string): part name for the corresponding LOD of secondary geometry for the part (e.g. body fixed parts of a 2-piece spoiler). Same naming convention as Geometry0Lod
        • Geometry1Lod(A/B/C/D/E)Exists (boolean): enables/disables corresponding LOD
      • Templated (boolean)
    • PartLabel (string): internal name of the part, must be unique.
    • UpgradeGroupID (integer): determines several properties of the part in-game (what kind of part is, when it unlocks, cost of part in Career Mode, etc.), for reference here you can check the UpgradeGroupID lists for NFSU2 and here are the NFSMW ones.
    Part naming conventions aren't very strict in most cases, only requirements is to match to whatever geometry file part name has and it has to be unique.

    Parts can be added, copied, deleted and sorted via the Car Parts menu. Keep on mind the part order you see in the DBModelParts node will determine the part order in-game.

    Parts also can have a set of attributes, which can be managed via the Attributes menu; you can add, remove, sort and even add custom attributes (which Extra/Extended Customization makes use of; check here for NFSU2 custom attributes or here for NFSMW custom attributes). Standard attributes are too many to list and describe for now, but the most relevant for part types will be described later on.

    How to add parts

    To add a part, open the DBModelParts node of your vehicle or parts set and go to Car Parts > Add Part or Car Parts > Copy Part. The latter is recommended if you're adding a part with geometry since Binary currently has a bug with added parts through the Add Part command that prevents from using geometry. Then you can adjust the properties and add the attributes you need for your part.

    Making geometry for new parts

    Making geometry for new parts is very similar to making new geometry for cars, which is detailed in the tutorial sections of the NFSU2/MW modding pages; however there are some caveats:
    • If your geometry belongs to a separate part set, you should include their entire part names (e.g. SPOILER_STYLE50_A) in the Data\<game>\GenericParts.txt file and leave the XNAME field blank in CarToolkit. If it's included with a car geometry, you should put the part names (e.g. STYLE50_SPOILER_A, so it will be SENTRA_STYLE50_SPOILER_A when compiled) in the Data\<game>\Parts_Racer.txt file.
    • Parts like spoilers, roof scoops (and for some games, mirrors -NFSU2- and exhausts) should be placed at origin (XYZ 0,0,0), since their mountpoints will put them in place.


       


    • For NFSMW and prior: paintable spoilers, roof scoops, calipers, exhausts, mirrors and audio components should be mapped to certain regions of the SKIN texture (seen in the DUMMY_SKIN textures)
    • Wheels and brake discs should be also placed at origin but with the face/disc (or hub in case of brakes for NFSMW onwards) sitting at Y origin 0.


    Part Slot Overrides

    Sometimes it's needed to tell the game to use a certain part set for certain vehicle types (like hatchbacks) or make the game use only certain parts in your car (like a set of roof scoops) for a slot; that's where the SlotOverrides section comes in. SlotOverrides nodes can be added, deleted, copied, imported and exported.

    To add a new SlotOverride node, click on the SlotOverrides section and click on Add Node. Name the slot <XNAME>_PART_<slot to be overriden> (e.g. IMPREZAWRX_PART_SPOILER) and click OK. Change the InfoMainOverride value to the part set you want to use or set it to some non-existent name (e.g. NULL) to restrict the parts availabity to whatever you provide with your car's parts.

    For NFSU2 some instances of car-specific parts like vinyls and decals need a SlotOverride to function, though another way is to apply this script to set SlotType overrides to SlotMainOverride (so it can be used without an SlotOverride node). NFSMW Unlimiter v4 already has this kind of feature built-in.

    Keep on mind some slots (like ROOF -roof scoops-) might put your custom parts above the stock parts in the parts browser in-game if there's no InfoMainOverride part defined.

    Most commonly used attributes

    For most parts

    • LANGUAGEHASH (key): Specifies what language string stored in LANGUAGES\<language>.bin uses the part (e.g. KIT00_FRONT_WHEEL)
    • CARBONFIBRE (boolean): Specifies if this part is a carbonfiber part

    Headlights/taillights

    • TEXTURE_NAME (key): Specifies what texture the part uses (e.g. PEUGOT_STYLE01_BRAKELIGHT)

    Wheels

    • TEXTURE_NAME (key): Specifies what texture the part uses the wheel (e.g. BBS_STYLE09)
      • Texture should be in ARGB format, name ending with _WHEEL (e.g. BBS_STYLE10_WHEEL)
      • Texture must have an accompanying _WHEEL_INNER_MASK (e.g. BBS_STYLE10_WHEEL_INNER_MASK) black and white texture to define colorable sections
      • Texture should match resolution of DUMMY_WHEEL textures in CARS\TEXTURES.BIN
      • Texture should have the following properties:
        • AlphaBlendType: TEXBLEND_SRCCOPY
        • AlphaUsageType: TEXUSAGE_PUNCHTHRU (for WHEEL/OUTER textures) / TEXUSAGE_NONE (for MASK textures)
    • SPINNER_NAME (key) -used only in NFSU2-: Specifies what texture the part uses the spinner attached to the wheel (e.g. DAVIN_STYLE09_OUTER)
      • Same properties as wheels, texture must match resolution of DUMMY_SPINNER textures and must have an accompanying _OUTER_MASK texture (e.g. DAVIN_STYLE09_OUTER_MASK) black and white texture
      • Can also be used in regular wheels thus making two-color wheels possible
    • OUTER_RADIUS (integer): overall wheel size in inches (ranges from 23 to 26)
    • INNER_RADIUS (integer): rim size in inches (ranges from 15 to 20)
    • BRAND_NAME (key): specifies what manufacturer the wheel uses as defined in WHEEL_MANUFACTURERSDBModelParts and scripts\UnlimiterData\_RimBrands.ini file. If you're making a car-specific custom wheel, leave it blank.

    Most visual parts (paint/neons/etc)

    • RED/GREEN/BLUE -and any variation therefore- (integer): red/green/blue color values (range from 0 to 255)

    Paint (body/rim/hoses/vinyl)

    • GLOSS (integer): how glossy is the paint (ranges from 0 to 255)
    • LIGHT_MATERIAL_NAME (key): what material will the paint use (e.g. REGPAINTGREY). Check Materials section for material availability.
    • BRAND_NAME (key): what kind of paint will the paint be. Usual values are GLOSS, METAL, PEARL, RIM, MUFFLER, HOSE and VINYL

    Vinyls

    • REMAP (boolean): determines if vinyl is colorable
    • TEXTURE_NAME (key): specifies what texture does the vinyl use (e.g. TEAR_012A)
      • Vinyl textures should be ARGB or 8-bit (256-color) with alpha channel without mipmaps; red and blue channels should be swapped; alpha channel determines blending with car paint.
      • Texture name is usually <XNAME>_<vinyl name> (e.g. 350Z_MODERN_056C).
      • A black and white _MASK texture is needed (e.g. 350Z_MODERN_056C_MASK) for transparency.
      • Colorable vinyls should have pure red, blue and green colors.
      • Textures should have the following properties:
        • AlphaBlendType: TEXBLEND_SRCCOPY
        • AlphaUsageType: TEXUSAGE_NONE
    • NUMCOLORS (integer): how many colors are present in the texture. Usually it's 16 for colorable vinyls and 64 for non-colorable vinyls
    • NUMREMAPCOLORS (integer): how many colorable colors does the vinyl have (range from 1 to 3)
    • BRAND_NAME (key): not sure what is for, but it's always NFSU
    • TEXTURE (string): usually the same as TEXTURE_NAME. Has a boolean property named ValueExists that enables/disables it.

    Decals

    • NAME (key): specifies what texture is being used for the decal (e.g. 5ZIGEN_WHITE)
      • Texture for decals should be DXT3 format
      • Set ApplyAlphaSort to 1 in the texture properties
      • Decal textures should be named <brand>_RECT/<brand>_WIDE/<brand>_WHITE_RECT/<brand>_WHITE_RECT (e.g. GREDDY_RECT)
    • BRAND_NAME (key): what brand is your decal, usually it matches what's in NAME (e.g. 5ZIGEN)
    • NUM_DECALS (integer): number of decals the decal part can hold (ranges from 1 to 8)

    Creating custom part sets

    A not so widely publicized feature of the Speedreflect library is the ability to load parts from any geometry file linked with an Universal type CarTypeInfos. That means you can make a custom part set that contains several types of parts (spoilers, wheels, etc.) without having to modify the vanilla game's geometry files. In order to use this feature make sure to do the following:
    • First make sure you have the Speedreflect library installed in your game. Binary can install it via Tools > Install Speedreflect menu; you can also incorporate the speedreflect auto command in your mod installation script
    • Go to the CarTypeInfos section and create a new CarTypeInfos, set its type to Universal
    • Create a folder in your CARS folder with the same name as your parts set's CarTypeInfos
    • Make the geometry file for your parts set.
    • Copy the geometry file to the parts set folder you've made.
    • Edit the relevant DBModelParts for your parts (be it specific cars, spoilers, wheels, etc.), and add their relevant textures to their respective places.

    Some things to consider

    • Remember that if you want to put parts in it that will be car-specific, put their full names in CarToolkit's Data\<game>\GenericParts.txt since part sets do use an XNAME in CarToolkit.
    • Even tho the game isn't usually very strict with part naming, try to stick to a simple to handle naming convention. For example, you could name your part set CarTypeInfo MYCOOLPARTS and a front bumper for the 350Z could be named 350Z_COOLPART00_FRONT_BUMPER
    • If you are editing a car's DBModelParts node with car-specific custom part: before exporting, try as far as possible to delete all parts except your custom parts and a copy of the stock part of its part slot so it can be imported later with the Synchronize type to minimize chances of duplicating parts when merging nodes.

    No comments:

    Post a Comment