This is a sort of sequel to the previous post I made about handling the Houdini.env file, and about configuring environments in general. Houdini 17.5 introduced the concept of “packages”, which are little JSON files (JSON meaning JavaScript Object Notation, filling a similar role as XML or YAML) that define Houdini-specific changes to be made to the environment. They’re meant to fill the exact same role as the Houdini.env file. JSON syntax can take a little getting used to, but the advantage of using packages over the Houdini.env file is that these packages can be easily enabled or disabled individually, and they can support special syntax for loading packages only when certain conditions are met (such as a specific build of Houdini).

SideFX has a reasonably long documentation page on what packages are and how they work, but I still keep seeing a lot of badly-configured package files floating around out there that can prevent your environment from working correctly when multiple packages are combined. Part of this is due to the internal inconsistency of how different “keys” in the package file are handled; for some reason, SideFX decided that any additions to the HOUDINI_PATH variable can be done with a special key called “path” that automatically operates in “prepend” mode, meaning each package automatically adds the new value to the beginning of HOUDINI_PATH. However, other environment-related keys default to the “replace” mode, and confusingly one of the common environment variables you need to edit is named “PATH”, and this is not the same as the special “path” key. Little inconsistencies like this can really throw a wrench in what should otherwise be a pretty simple file format. I’m going to explain a bit about how this syntax is supposed to work, and then write a couple of sample packages you can follow that should be enough to configure just about any add-on or plugin you choose to add to Houdini.

Package Syntax

Houdini package files are written in JSON, which is a bit finicky to say the least. If you’re not used to dealing with JSON, it’s basically a bunch of key/value pairs in a hierarchical structure. Each “object” in this structure is surrounded by curly braces ({ }). The file itself is one of these, so you’re going to have a pair of curly braces opening and closing the file as a whole. Any environment variables you want to store are another object, named env. This object internally is a list of environment variables you want to adjust, so it’s going to be surrounded by square braces ([ ]). So, before we’re adding any variables to our environment at all, here’s what a blank package would look like:

{
    "env": [
        {
        
        }
    ]
}

That’s looking pretty… useless. But now we can start filling in the blanks. You can see that I put another pair of curly braces in there, inside the square braces that define the list of environment variables we’re going to add. This is because each environment variable addition we make is another object, each with its own properties. Let’s start with the most obvious property here… what environment variable are we setting?

{
    "env": [
        {
            "PATH": "C:/ProgramData/Redshift/bin"
        }
    ]
}

The actual key/value pairs are just strings, separated by a colon. This is setting the PATH environment variable to be the given path on disk. It’s the equivalent of writing this in Houdini.env:

PATH="C:/ProgramData/Redshift/bin"

Those of you who have already slogged through a Houdini.env might notice that something’s missing, though… you usually want to append or prepend to the PATH variable, not replace it entirely. In Houdini.env, you typically do this by saying PATH=$PATH;"C:/ProgramData/Redshift/bin", and then writing this line over and over again for any other plugins you might be adding to your system path. With packages, you do this via the method property of this JSON object:

{
    "env": [
        {
            "PATH": "C:/ProgramData/Redshift/bin",
            "method": "append"
        }
    ]
}

Note that there’s a comma there after the PATH definition… JSON is very particular about this! You need a comma in between multiple objects in the same hierarchy. Setting the method to append here ensures that our new key is just going to be added to what’s already there.

Houdini gotchas

Of course, because it’s Houdini, it can’t be that easy. There’s a specially-named key in Houdini package files that you’ll frequenty see called path. This has nothing to do with the PATH environment variable set above… it’s actually a shortcut for HOUDINI_PATH. Worse still, it automatically assumes that you’re using the prepend method, whereas the env key assumes you are using the replace method. This trips up a lot of people when they’re trying to do anything more complex in a package than adding something to HOUDINI_PATH. You might even see this in some widely-distributed packages out there on the internet. If things start to fail when you’re combining multiple packages together, it’s worth taking a look in there and seeing if they’re following the right syntax!

Following our previous example for configuring a Redshift package, we still need to add the Redshift plugin path to HOUDINI_PATH to complete the install. Using the special path key, our package will look like this:

{
    "env": [
        {
            "PATH": "C:/ProgramData/Redshift/bin",
            "method": "append"
        }
    ],
    "path": "C:/ProgramData/Redshift/Plugins/Houdini/18.0.391"
}

Notice that extra comma after the closing square bracket! Now that we’re defining multiple keys inside the outermost object, we need a comma in between them.

The last main gotcha here is that you can’t have these things defined in Houdini.env and in a package file at the same time… it’s one or the other. My recommendation is to hose out your Houdini.env file entirely and replace all the keys you’re setting with packages. They’re so easy to individually swap in and out that you’ll have a much easier time adding, removing, or updating plugins and tools as necessary, even on a show-by-show basis.

Finishing up

The Houdini packages documentation goes into the specifics of where you can put these package files, but the usual directory is wherever your Houdini.env file typically goes on your system, plus /packages. So on Windows, you’d place all of these JSON files into C:/Users/butt/Documents/houdini18.0/packages. Each of these files will be processed in turn, and the result is the total environment for Houdini. Once you get used to the JSON syntax, it’s way easier than doing the old dance of semicolons and ampersands that we all had to do in Houdini.env.

The last thing I should mention is that packages are only a replacement for Houdini’s environment… they can never replace your system environment. I still recommend learning about how to manipulate environment keys on your given OS so that you can configure your projects in a more flexible manner… having auto-configured variables like $SHOW and $SHOT can save you a ton of time if done right, and the environment is a great place to tuck away “global” variables that you might need in multiple software packages all communicating with each other.

As a final example, here’s another package file that you could use to configure Arnold for Houdini. It’s almost exactly the same as Redshift… you can use this as a template for other tools you want to install, too! (Except MOPs. Use the included JSON for that one.) Just replace /path/to/htoa with the install location on your machine:

{
    "env": [
        {
            "PATH": "C:/path/to/htoa/htoa-5.0.2_raba8949_houdini-18.0.348/scripts/bin",
            "method": "append"
        }
    ],
    "path": "C:/path/to/htoa/htoa-5.0.2_raba8949_houdini-18.0.348"
}

Happy packaging!


15 Comments

Ivan · 06/11/2020 at 00:08

Hello, Im trying to make dance Arnold and Renderman together, but no luck.
For some reason Arnold spare parameters could not be added to geometry (errors from shelf python script)
Ive configured Arnold from your example:
{
“env”: [
{
“PATH”: “C:/Users/Ivan/htoa/htoa-5.3.0_r233605f_houdini-18.0.460/htoa-5.3.0_r233605f_houdini-18.0.460/scripts/bin”,
“method”: “append”
}
],
“path”: “C:/Users/Ivan/htoa/htoa-5.3.0_r233605f_houdini-18.0.460/htoa-5.3.0_r233605f_houdini-18.0.460”
}

Renderman config (done it myself):
{
“env”: [
{ “RMANTREE” : “C:/Program Files/Pixar/RenderManProServer-23.3” },
{ “RFHTREE” : “C:/Program Files/Pixar/RenderManForHoudini-23.3” },

{ “RMAN_PROCEDURALPATH” : “$RFHTREE/18.0/openvdb” },

{
“PATH”: “$RMANTREE/bin”,
“method”: “append”
}
],
“path”: “$RFHTREE/18.0”
}

This is official ENV from installation page
(https://rmanwiki.pixar.com/display/RFH23/Installation+of+RenderMan+for+Houdini)

RMANTREE=C:\Program Files\Pixar\RenderManProServer-23.3
RFHTREE=C:\Program Files\Pixar\RenderManForHoudini-23.3
RMAN_PROCEDURALPATH=$RFHTREE\18.0\openvdb;&
HOUDINI_PATH=$RFHTREE\18.0;&
PATH=$RMANTREE\bin;&

    toadstorm · 06/11/2020 at 07:04

    What errors? Do either of these packages work correctly alone?

      Ivan · 06/11/2020 at 08:51

      Each package working by itself, but when they together I get this error message:

      Error running C:/Users/ivan/htoa/htoa-5.3.0_r233605f_houdini-18.0.460/htoa-5.3.0_r233605f_houdini-18.0.460/scripts/obj/geo.py:
      Traceback (most recent call last):
      File “C:/Users/ivan/htoa/htoa-5.3.0_r233605f_houdini-18.0.460/htoa-5.3.0_r233605f_houdini-18.0.460/scripts/obj/geo.py”, line 3, in
      htoa.properties.initArnoldProperties(kwargs[‘node’])
      File “C:/Users/ivan/htoa/htoa-5.3.0_r233605f_houdini-18.0.460/htoa-5.3.0_r233605f_houdini-18.0.460/scripts/python\htoa\properties.py”, line 167, in initArnoldProperties
      addArnoldProperties(node)
      File “C:/Users/ivan/htoa/htoa-5.3.0_r233605f_houdini-18.0.460/htoa-5.3.0_r233605f_houdini-18.0.460/scripts/python\htoa\properties.py”, line 111, in addArnoldProperties
      node.parm(‘ar_matte’).setExpression(‘ch(“vm_matte”)’)
      AttributeError: ‘NoneType’ object has no attribute ‘setExpression’

        toadstorm · 06/11/2020 at 08:58

        Okay, so it looks like Arnold is trying to add callbacks to Geometry containers and it’s likely getting overridden or otherwise confused by callbacks in Renderman. I’m not terribly familiar with either of those engines, but my guess is that this isn’t something you’ll be able to easily resolve with environment changes, other than removing one package or the other depending on what engine you want to be using for a specific show.

        There may be a way to get these to work together, but if I were you I’d send an email to the Arnold guys and see if it’s something they can patch.

Ivan · 06/11/2020 at 09:33

Sad, I thought that package method will solve all this ENV nightmare.
But anyway thank you for this valuable information about packages, it really helped me a lot!

    haggi · 12/30/2020 at 06:20

    I did not manage to solve the Arnold/Renderman problem. The renderman paths somehow influence the arnold paths, so in theory using a “prepend” for the Renderman env paths should solve the problem, but it does not. To me it seems that as soon as the plugin is loaded, the problem appears, no matter how the paths are defined and since Houdini seems to load the packages in alphabetical order, it first loads Arnold, then Renderman which causes truble. So my idea was… just rename the Arnold.json to ZArnold.json and maybe Houdini first loads Renderman and finally Arnold …. and it seems to work :)

Brian Hanke · 01/26/2021 at 09:06

Just wanted to pop in to say thanks for explaining how to create packages. Also, load order seems to matter a lot. Just had a small problem with the most recent version of 3Delight plus Octane and Renderman in Houdini 18.5.462. A new feature in 3DL wasn’t working with Renderman loaded. The solution was to rename the Renderman package to 01_renderman.json so it loaded first. All working smoothly now.

    Dave · 09/08/2023 at 22:13

    I absolutely cannot get this to work, regardless of naming the Arnold and Renderman.json files alphabetically. I can render fine with Arnold, but as soon as I try Renderman, it spits out a ton of jibberish about mtlx files. I’m guessing there’s a clash between the mtlx packaged with Arnold vs Renderman as I’m trying to render a mtlx file. Renderman works fine when I remove the Arnold_for_houdini.json from the packages dir, but shits the bed when the Arnold .json exists. Arnold renders fine regardless.

Dmitry Shura · 04/04/2021 at 02:04

Redshift users:
For easy of use , it would be better to specify the automatic plugin folder version selection with ${HOUDINI_VERSION} or $houdini_version variables:

{
“recommends”: “houdini_version >= ‘17.0.506’”,

“env”: [
{
“PATH”: “C:/ProgramData/Redshift/bin”,
“method”: “append”
}
],
“path”: “C:/ProgramData/Redshift/Plugins/Houdini/${HOUDINI_VERSION}”
}

Jesus Nieto · 11/28/2022 at 20:16

There’s really not enough “thank yous” in this post. This is hands down the best most detailed explanation I’ve seen. Thank you for taking the time to do it.

    toadstorm · 12/01/2022 at 12:00

    You’re very welcome!

Harsh · 12/14/2022 at 02:52

Hey,
Would it be possible to introduce conditional statement inside the json file ? To configure different render engines for different projects or different houdini versions ?

Sharan · 10/31/2023 at 14:27

Hey! Thank you for explaining packages in such detail, really useful.

Would it be possible to load the packages if they do not exists on the /houdini19.X.XXX/packages folder? I want to use the packages system on an online render farm but I dont have access to their houdini dir to place the packages. I have been trying to use hou.ui.loadPackages(scanpath) to load the package from a custom path after the session has load but no luck.

Would appreciate the help!

    toadstorm · 01/04/2024 at 11:15

    There’s another environment key you can set either at the system / shell level or in houdini.env called HOUDINI_PACKAGE_DIR. Houdini will look for package JSON files inside any directory specified there.

Leave a Reply to Harsh Cancel reply

Your email address will not be published. Required fields are marked *