A sample model from GameMaker Model Viewer and its raw data

This is a blog post about the structure of GameMaker's (now-legacy) 3d model format.

## Description

`GMMOD`

/`D3D`

(no formal extension) is a 3d model file format used by
GameMaker versions starting with Game Maker 6 and up until GameMaker: Studio
(deprecated in GMS2 together with the rest of `d3d_`

functions).

In a slight contrast with how model formats usually work, `D3D`

model format stores not vertices
and triangles, but functions that were called to populate the model.

This allows a model to contain mixed geometry types (e.g. both lines and triangles), and to contain shapes as a primitive unit.

In compatible versions, they can be saved using `d3d_model_save`

and loaded using `d3d_model_load`

.

## Structure

The file format is text-based.

Empty lines are skipped.

Unusual line endings (like CR-CR-LF) are allowed.

The structure is as following:

version number (always 100) number of entries that follow ...entries

Each entry consists of an instruction ID and the arguments for it.

`d3d_model_save`

always pad arguments to maximum argument count (10) with zeroes,
though `d3d_model_load`

loads models without unused arguments just fine.

`d3d_model_save`

uses 4..7-digit precision for floating-point arguments,
but you can use both less or more digits if necessary.

The following are the supported instructions, equivalent functions, and their arguments:

ID | Function |
---|---|

0 | d3d_model_primitive_begin(m, kind) |

1 | d3d_model_primitive_end(m, kind) |

2 | d3d_model_vertex(m, x, y, z) |

3 | d3d_model_vertex_color(m, x, y, z, color, alpha) |

4 | d3d_model_vertex_texture(m, x, y, z, xtex, ytex) |

5 | d3d_model_vertex_texture_color(m, x, y, z, xtex, ytex, color, alpha) |

6 | d3d_model_vertex_normal(m, x, y, z, nx, ny, nz) |

7 | d3d_model_vertex_normal_color(m, x, y, z, nx, ny, nz, color, alpha) |

8 | d3d_model_vertex_normal_texture(m, x, y, z, nx, ny, nz, xtex, ytex) |

9 | d3d_model_vertex_normal_texture_color(m, x, y, z, nx, ny, nz, xtex, ytex, color, alpha) |

10 | d3d_model_block(m, x1, y1, z1, x2, y2, z2, hrepeat, vrepeat) |

11 | d3d_model_cylinder(m, x1, y1, z1, x2, y2, z2, hrepeat, vrepeat, closed, steps) |

12 | d3d_model_cone(m, x1, y1, z1, x2, y2, z2, hrepeat, vrepeat, closed, steps) |

13 | d3d_model_ellipsoid(m, x1, y1, z1, x2, y2, z2, hrepeat, vrepeat, steps) |

14 | d3d_model_wall(m, x1, y1, z1, x2, y2, z2, hrepeat, vrepeat) |

15 | d3d_model_floor(m, x1, y1, z1, x2, y2, z2, hrepeat, vrepeat) |

`x`

/`y`

/`z`

are fairly abstract coordinates - it is up to the game to decide unit scale.

`nx`

/`ny`

/`nz`

are the normal vector for a point. The length is *usually* 1.

`xtex`

/`ytex`

are texture coordinates, (0,0) being top-left and (1,1) being bottom-right.

`color`

is a 24-bit BGR color.

`alpha`

is in 0..1 range.

`hrepeat`

/`vrepeat`

indicate how many times the texture should repeat on a primitive.

For blocks, it repeats HxV on top/bottom and HxV for each side, which leads people to use
walls+floors instead for non-cubes to have finer control.

`closed`

for cylinder and cone indicate whether whether they should have lid(s).

`steps`

is the number of polygons per quadrant for shapes that are circular.

The `kind`

in `d3d_model_primitive_begin`

can be as following:

ID | Name | Description |
---|---|---|

1 | pr_pointlist | Each vertex is drawn as a point. |

2 | pr_linelist | Pairs of vertices to be connected with lines (1,2,3,4 ➜ 1-2, 3-4) |

3 | pr_linestrip | Each vertex is connected to a preceding one (1,2,3,4 ➜ 1-2, 2-3, 3-4) |

4 | pr_trianglelist | Trios of vertices to be joined into triangles (1,2,3,4,5,6 ➜ 1-2-3, 4-5-6) |

5 | pr_trianglestrip | Each vertex is connected to the preceding two (1,2,3,4,5,6 ➜ 1-2-3, 2-3-4, 3-4-5, 4-5-6) Often used for drawing curves and multi-segment lines. |

6 | pr_trianglefan | Each vertex is connnected to a preceding one and to the first vertex (1,2,3,4,5,6 ➜ 1-2-3, 1-3-4, 1-5-6) Often used for drawing circles, stars, and anything else where everything connects to a center point. |

**Note:** Since GameMaker models tend to be converted from other common formats,
implementing instructions 0 (for `pr_trianglelist`

), 1, and 9 is enough to display most of these.

## Software

A number of tools exist for converting GM models, mostly made in GM itself, such as:

- GameMaker Model Viewer
can quickly display models with an optional texture.

The author also made a Blender addon for exporting GM models. - Dragonite's 3D Model Converter converts models both to and from GM format, along with a handful other features.

That is all.

Dragonite’s 3D Model Converter is fine, but for some reason, if I load a .d3d model consisting of a trianglestrip list into the program and save it, say, to an .obj model, the normals of the faces are flipped, one not and the next one yes, throughout the entire model. GM Model Creator, on the other hand, can detect and correct this and save it without visual errors, and I really don’t know what magic is behind it. : (

Should probably ask Dragonite about it – if it always happens with a specific model, might not be too hard to fix.

thank you for sharing your knowledge with us it’s been a long time that I’ve been looking for how to covert obj models to D3D from game maker, and I couldn’t find any source, until I came across yours.

thank you very much.

I want to know how you found this information about the internal format of the D3D file?

thank you in advance!

You can add geometry to a d3d_model, call d3d_model_save, and see what shows up in the file. I think that’s how most of people that made converters figured it out.