Coordinates
Different video games (and 3D graphics engines generally) have different conventions for how rotations are stored, what Euler angles actually mean, and what the different 3D axes actually mean. For example, in Skyrim, an object's local Y-axis is its forward axis, but in Halo: Reach, an object's local X-axis is its forward axis.
Axis conventions
- Although Forge uses Euler angles in its UI, the game engine typically uses local axis vectors instead. Generally, the local forward vector and local up vector are used; the local side vector can be computed as the cross product of those.
- The X-axis is "world forward" and the Z-axis is "world up."
Working with rotations
There is a way to spawn an object that is completely unrotated.
If you use object.place_between_me_and to spawn something between an object and itself, then the newly-spawned object will be rotated so that its local up-vector matches the world X-axis; the object will point exactly nose-down, with no rotation otherwise.
(This happens because the game tries to adjust the spawned object based on the rotations of what it's spawning between: it takes the two other objects' local axes and performs a cross product on them. The cross product of a vector with itself is a zero-length vector, and the game's fallback case for that is the world X-axis.)
Once you have a nose-down object, you can use object.place_at_me to spawn another object at it. As long as you don't use the absolute_orientation flag, the newly-spawned object will have a perfect (0, 0, 0) rotation.
(This happens because without the absolute_orientation flag, the created object takes on the yaw-rotation of the basis object. If the basis object is almost exactly nose-up or nose-down, however, then that fails, and the game falls back to using a local forward vector aligned with the world X-axis.)