MAXScript Language Improvements in 3ds Max 8

The following is a description of internal changes and "tweaks" to the MAXScript language in 3ds Max 8. Other than the "What is new..." topic, these changes do not implement new objects, classes, methods or interfaces, but change the way MAXScript works internally. Usually these changes either improve performance or simplify programming.

MAXScript Debugger

The MAXScript Debugger

Using the MAXScript Debugger

Interface: MXSDebugger

new.gif The MAXScript Debugger allows the main thread of 3ds Max to be suspended, the values of global and local variables to be examined and altered while the 3ds Max thread is not running, MAXScript commands to be executed from a command line, and the execution to be suspended using method calls from inside the MAXScript code. The Debugger also lets you stop or continue the execution of the suspended code.

MAXScript Crash Recovery

Saving MaxScript Files on Crash

new.gif After attempting to save the scene file, the crash handler now allows MAXScript to attempt to save modified open script windows...

Controller Improvements

new.gif Previously, when assigning a controller to a track, the value of the track was used by the new controller. While this works well when assigning a new controller class to an existing track, it would cause strange results when instancing an existing controller that already has a value. In addition, when assigning scripted controllers to a track, their script string set before the assignemtn was always overwritten by the current value of the track.

This has been fixed in 3ds Max 8. A flag is set internally when a controller is "not new" and the existing data of the controller being instanced will be used instead of the value of the track at frame 0.

Script Controllers

new.gif The replacement of the script string in scripted controllers with the current value of the track has been fixed thanks to the change in controllers described in the previous paragraph. When the settings of a script or expression controller have been changed, the controller will be marked as "not new" and its existing script / expression will be used instead of the value of the target track.

Weak References To Nodes in the Expression/Script Controller

new.gif Expression controller variables that point at nodes now use the new nodeTransformMonitor class to hold the reference to the node. This will speed up scenes where expression controllers with node variables are used.

copyPasteKeys function

new.gif A new method for copying and pasting selected keys has been added to MAXScript.

Fixed .Checked and .Enabled Properties in RCMenus

Fixed .Checked and .Enabled Properties in RCMenus

new.gif Menu items in RCMenus used in dialogs will now update correctly when the menuItem's .enabled and .checked properties change...

Read-Only .owner Property in Rollout Values

Utility and Rollout Properties, Methods, and Event Handlers

new.gif A read-only .owner property has been added to rollout values. If the rollout is being displayed by a scripted plugin or CA, the property will contain the scripted plugin or CA instance. This property was added to make it easier to access the variables in a scripted plugin or CA instance when a debugger break occurs in a rollout event handler. In this case, the owner of the event handler is the rollout, so you can access the scripted plugin or CA instance via getVar owner.owner.

Access to .caption Property of Rollout Groups

Group .caption Access

new.gif Setting the .caption property of either the GroupStartControl or GroupEndControl via the .controls property of a rollout will now update the name of the group.

Read-Only Local Variables in Scripted Plug-ins

new.gif The following predefined local variables in scripted plug-ins are now read-only:

All plug-in types: this, loading. version was previously marked as read-only.

SimpleMod: extent, min, max, center

SimpleManipulator: target, node

Specifying Global Variables As Global Using ::

Specifying Global Variables As Global Using ::

new.gif You can now specify a global variable name by preceeding the name with '::'. Such names are looked for only in the global variable pool, and will be created if they do not currently exist.

New Persistent Global Variables Behavior On Merge

Persistent Global Variables

new.gif When merging or XRef-ing in a file (scene/object XRefs are a special case of merge), when reading in persistent global variables, If the variable being read from the scene file already exists as a persistent global variable, the value of the persistent global is not overwritten.

Import/Export using a specified I/O class

ImportFile() and ExportFile()

new.gif A new [using:<maxclass>] optional keyword argument has been added to the ImportFile() and ExportFile() functions.

It can be used to pass the max class of the exact importer/exporter to be invoked, thus preventing conflicts when the same extension is supported by multiple files.

Saving Files - Quiet Mode and Return Value

3ds Max File Loading and Saving

new.gif A new [quiet:<bool>] optional keyword argument has been added to the SaveMaxFile() and SaveNodes() functions. In addition, instead of returning OK, these methods will now return true on success and false on failure (for example if the target file exists and is write-protected).

Bitmap Values

new.gif A new [quiet:<bool>] optional keyword argument has been added to the Save() method for bitmap values. In addition, instead of returning OK, the method will now return true on success and false on failure (for example if the target file exists and is write-protected).

Material Editor

new.gif A new [quiet:<bool>] optional keyword argument has been added to the fileSaveMatLib() method. It will still return OK as the corresponding SDK method does not return a valid success or failure result.

New initialDir: Keyword Argument To getSavePath()

Standard Open and Save File Dialogs

new.gif A new [initialDir:<pathname>] optional keyword argument has been added to the getSavePath() method. When specified, the dialog will open at the specified path.

Custom SnapPlane for gw.SnapPoint()

Viewport gw.snapPoint method

new.gif A new optional keyword argument has been added to the existing gw.snapPoint method. It lets the user provide a snapPlane matrix3 value which maps the XY plane to a custom snapping plane.

32bit Floating-point Support for Scripted Render Effects

new.gif Scripted render effects now implement the Effect8 interface. Effect8::SupportsBitmap() is implemented to return true in all cases.

This means that scripted Render Effects are considered compatible with all types of bitmaps since they only access bitmaps through the proper GetPixel() method and will automatically support high-dynamic-range images without clipping - unless, of course, the script intentionaly clips the colors or convertes them to integers.

mental ray Support for Scripted Materials

new.gif Scripted materials are now supported by mental ray, as long as the delegate material is supported. The delegate material is correctly interpreted by mental ray as the actual material used to render. The "mental ray Connection" rollout of the scripted material is also correctly used and initialized.

Undo/Redo Callbacks NotificationParams

Callbacks: Undo System Notifications

new.gif #sceneUndo and #sceneRedo callbacks now return the undo/redo name entry in callbacks.notificationparams().

Example script:

callbacks.removeScripts id:#test

callbacks.addScript #sceneRedo "format \"Redo: %\\n\" (callbacks.notificationParam())" id:#test

callbacks.addScript #sceneUndo "format \"Undo: %\\n\" (callbacks.notificationParam())" id:#test

Inspecting Interface Properties

new.gif The methods showProperties, getPropNames, and hasProperty now include FPS interface properties.

For example,

CameraMap exposes no properties through its param blocks, but it exposes two properties through an FPS interface:


CameraMap:Camera Map Modifier


showinterfaces c

Interface: interface


.cameraNode : node : Read|Write

.channel : integer : Read|Write





getpropnames c -- on instance

#(#cameraNode, #channel) -- previously returned #()


showproperties c -- on instance

.cameraNode : node -- previously not shown

.channel : integer -- previously not shown



hasproperty c #channel -- on instance

true -- previously returned false


getpropnames CameraMap -- on class



showclass "cameraMap.*"

CameraMap : modifier {21ce6ea4,7ed434db}



MAXScript Editor Improvements

new.gif New Edit>Clear All command in the Editor menuThis option was previously available only in the Listener. When executed, clears the content of the editor.

new.gif Color-coding of large scripts has been made over 30% faster. In addition, a wait cursor will be shown during color-coding.

Quiet Mode, DefaultAction and Quiet Contexts

defaultAction Context

new.gif New context to specify the default action.

quiet Context

new.gif New context to specify the current quiet mode.

Quiet Mode

new.gif For default action arguments for render, loadMaxFile, fetchMaxFile, mergeMaxFile, and getMAXFileObjectNames, the option #default has been added. When #default is specified, the current defaultAction context state is used.

new.gif If a default action argument is not specified for render, loadMaxFile, fetchMaxFile, mergeMaxFile, and getMAXFileObjectNames, it defaults to the current defaultAction context state.

new.gif Modified default for MAXScript render, loadMaxFile, fetchMaxFile, mergeMaxFile, and getMAXFileObjectNames method's 'quiet' keyword argument. Previously, the default was FALSE. Now the default is the current quiet mode.

new.gif Added keyword args to MXS mergeMAXFile method. missingExtFilesAction:, missingExtFilesList: , missingXRefsAction: and missingXRefsList:

Controlling the Renderer

new.gif Added new unsupportedRenderEffectAction: and unsupportedRenderEffectList: keyword arguments to MAXScript render method.

File Link and Quiet Mode

new.gif File Link dialogs now respect the Quiet Mode. All File Link dialogs (those that appear in the course of an Attach, Reload, Detach, or Bind) now respect this setting. 

readValue Method Enhancement

StringStream Associated Methods

new.gif A new ignoreStringEscapes: keyword parameter has been added to readValue method. 

filterString splitEmptyTokens Parameter


new.gif A new splitEmptyTokens: keyword parameter has been added to the filterString method. If splitEmptyTokens is false or not specified, sequential tokens are handled as a single token, and tokens at the beginning or end of the string are ignored. If splitEmptyTokens is true, each token found will result in string element in the output, with the string element in the cases ignored above being empty strings.

OLE Improvements

SafeArrayWrapper Class

new.gif Instances of the new SafeArrayWrapper Class are creatable by the user and are returned by OLE methods that return SAFEARRAY values.


new.gif In previous releases, the MAXScript string / OLE string conversion routines were using stack memory. A particular method was attempting to allocate two times the string size on the stack. For very long strings, this was causing stack overflows. In 3ds Max 8, MAXScript is using much better conversion routines, only using stack memory when actually needed and when stack memory requirements are small.

Garbage Collection Status Display


new.gif A new options.showGCStatus global variable has been added. When set to true, the message "MXS GC" will be displayed in the status bar during MAXScript Garbage Collection. When set to false, no message will be displayed. The setting is stored in the 3dsmax.ini file in the [MAXScript] section.

UI Speed-ups

new.gif In previous releases, the MacroScript isEnabled handler was called N times when N objects were deleted using MAXScript. This has been fixed. Scene redraw will be disabled while the objects are being deleted, and the MacroScript handlers will be called just once after the scene redraws have been re-enabled.

SelectByName showHidden: Option Now Working

Picking Scene Nodes by Name

new.gif In previous releases, the documented showHidden optional keyword was broken. Now it works as expected.

Slider controller: Creation Parameter


new.gif In previous releases, only spinner controls could be linked to a controller via the controller: creation parameter. Now the same can be done with Sliders.

New Spinner Change Handler Arguments


new.gif New optional arguments have been added to the changed, entered and buttonUp change handlers to allow better manual undo handling.

Removing Button Control Images

new.gif Setting the value of the .images property for either Button or Checkbutton to undefined will set the control back to displaying its caption rather than images.

New Mouse Button Event Handlers in Buttons and ImgTag

new.gif A new rightclick event has been added to button, checkButton, mapButton, materialButton, pickButton, and imgTag.

new.gif Several new events similar to the ones found in dialogs have been added to imgTag, including lbuttondown, lbuttonup, lbuttondblclk, mbuttondown, mbuttonup, mbuttondblclk, rbuttondown, rbuttonup, rbuttondblclk

New useWireColor Handler for Scripted Cameras, Lights and Dummies and Custom Display Mesh for Lights

Scripted Cameras

Scripted Light Plug-ins

Scripted Helper Plug-ins

new.gif This event handler is available to scripted cameras, lights, and helpers and lets the developer specify whether to use the node's wire color when drawing the object in the viewport, or use the UI color for the object type (Dummy Object for helpers, Light Object for lights, and Camera Object for cameras). If this handler returns true, the node's wire color is used, otherwise the UI color for the object type is used. If the event handler is not specified, the wire color is used. This handler is only applicable when a getDisplayMesh handler is supplied.

This handler is optional.

Scripted Light Plug-ins

new.gif The getDisplayMesh event handler previously available to scripted cameras and helpers is now available to scripted light plug-ins, too.

Listener Can Be Toggled On and Off

new.gif The MAXScript Listener can now be toggled on and off using the default F11 key. Previously, it was being opened but not closed using the shortcut.


See also

New in MAXScript