Skip to main content

RSW

This document describes the RSW file format used in the Ragnarok Online client.

Contents

RSW files contain the following information:

  • References to other files required to render the map (mainly GAT and GND; the others are only used in Arcturus)
  • The configuration of scene-wide light sources, as well as decorative game objects that should be placed in the scene
  • In earlier versions they also include a definition of the water plane, which is later stored in the referenced GND file instead
  • A scene graph-like representation of the object hierarchy (tree of bounding boxes), used for intersection queries

RSW is essentially the "scene definition" format used by the game.

Layout

Newer RSW files may include a third version segment, resulting in a Major.Minor.BuildNumber versioning scheme.

Version 1.9

An older version that's virtually identical to 2.1, but there's no QuadTree and audio sources don't have a CycleInterval.

Version 2.1

This is the original version used for most maps in the original RO client:

FieldOffsetLengthTypeDescription
Signature04string"GRSW" as an ASCII-encoded, fixed-size string
MajorVersion41uint8Versioning information
MinorVersion51uint8Versioning information
WaterConfiguration624WaterPlaneConfiguration of the map's primary water plane (only one)
LightingParameters3036LightParamsConfiguration of the map's global (fixed-function) light sources
MapBoundaries6616BoundingBoxA bounding box containing the entire scene (?)
SceneObjectsCount824intThe number of (ObjectTypeID, SceneObject) pairs to be read
SceneObjects86variablearrayScene objects of varying types (see tables below)
QuadTreevariable64kQuadTreeRangeScene graph data structure, for culling invisible objects

Scene objects are effectively a union type structure, the contents of which depend on the object type (first struct member).

Water Plane Configuration

This structure is exactly the same as in GND 1.8. Only one water plane is supported in this version, however.

Lighting Parameters

These define the settings that should be applied to the global light sources, which exist in every scene:

FieldOffsetLengthTypeDescription
Longitude04uint32Spherical longitude of the directional light source (in degrees)
Latitude44uint32Spherical latitude of the directional light source (in degrees)
DiffuseRed84floatDiffuse red component of the directional light source
DiffuseGreen124floatDiffuse green component of the directional light source
DiffuseBlue164floatDiffuse blue component of the directional light source
AmbientRed204floatDiffuse red component of the ambient light source
AmbientGreen244floatDiffuse green component of the ambient light source
AmbientBlue284floatDiffuse blue component of the ambient light source
ShadowmapAlpha324floatOpacity of the shadowmap (for baking GND lightmap textures)

Bounding Box

This was claimed to define the outside bounds of the visible game world, though the data doesn't really make sense:

FieldOffsetLengthTypeDescription
Top04uint32Purpose unknown; appears to be unused (?)
Bottom44uint32Purpose unknown; appears to be unused (?)
Left84uint32Purpose unknown; appears to be unused (?)
Right124uint32Purpose unknown; appears to be unused (?)

More research is needed to determine the meaning of this structure. Might be for internal tools, or used in Arcturus?

Scene Objects

There are multiple types of decorative scene objects, which are differentiated by a type identifier (first value):

FieldOffsetLengthTypeDescription
ObjectTypeID04intOne of the supported scene object type identifiers
SceneObject4variablestructLayout depends on the object type

The following object types may be used:

enum ObjectTypeID {
SCENE_OBJECT_TYPE_ANIMATED_PROP = 1,
SCENE_OBJECT_TYPE_DYNAMIC_LIGHT_SOURCE = 2,
SCENE_OBJECT_TYPE_SPATIAL_AUDIO_SOURCE = 3,
SCENE_OBJECT_TYPE_PARTICLE_EFFECT_EMITTER = 4,
}
3D Models (Animated Props)

Instances of a given RSM model can be placed in the scene and configured according to these parameters:

FieldOffsetLengthTypeDescription
Name040stringName of this model instance
AnimationTypeID404int32Defines the looping behavior of the model's animation
AnimationSpeed444floatAnimation speed modifier (percentage)
CollisionFlags484int32Zero means the object is "solid" (affected by collision checks?)
ModelFile5280stringName of the RSM file to instantiate
NodeName13280stringName of the RSM root node to render (?)
PositionX2124floatX coordinate of the instance's world position (translation)
PositionY2164floatY coordinate of the instance's world position (translation)
PositionZ2204floatZ coordinate of the instance's world position (translation)
RotationX2244floatX rotation applied to the model instance
RotationY2284floatY rotation applied to the model instance
RotationZ2324floatZ rotation applied to the model instance
ScaleX2364floatX scale factor applied to the model instance
ScaleY2404floatY scale factor applied to the model instance
ScaleZ2444floatZ scale factor applied to the model instance

The known values for AnimationTypeID are:

enum AnimationTypeID {
ANIMATION_TYPE_NONE = 0,
ANIMATION_TYPE_LOOPING = 2,
}

Only those types have been observed in the game files, though other modes might be supported.

Dynamic Light Sources

Dynamic lights aren't actually rendered by the client, as their output is baked into the lightmaps stored in the map's GND file:

FieldOffsetLengthTypeDescription
Name080stringNull-terminated (discard garbage bytes at the end)
PositionX804floatX coordinate of the light's world position
PositionY844floatY coordinate of the light's world position
PositionZ884floatZ coordinate of the light's world position
DiffuseRed924floatRed component of the light's diffuse color
DiffuseGreen964floatGreen component of the light's diffuse color
DiffuseBlue1004floatBlue component of the light's diffuse color
Range1044floatLight intensity (falloff range), given in world units
Spatialized 3D Audio Sources

Ambient sound effects (like frogs or flowing water) are emitted by these invisible game objects:

FieldOffsetLengthTypeDescription
Name080stringNull-terminated (discard garbage bytes at the end)
SoundFile8080stringNull-terminated (discard garbage bytes at the end)
PositionX1604floatX coordinate of the emitter's world position
PositionY1644floatY coordinate of the emitter's world position
PositionZ1684floatZ coordinate of the emitter's world position
VolumeGain1724floatPlayback volume, given as a percentage in the range of 0 to 1
Width1764uintThe width of the area that emits sound (used for attenuation?)
Height1804uintThe height of the area that emits sound (used for attenuation?)
Range1844floatAttenuation range (how far sound can be heard), in world units
CycleInterval1884floatDuration of the individual (looping) playback cycles, given in seconds

When CycleInterval is not present (i.e., in older RSW versions), it defaults to a duration of 4 seconds.

Particle Effect Emitters

Particle effects such as bats, smoke, or clouds, can be configured from a number of preset effects:

FieldOffsetLengthTypeDescription
Name080stringNull-terminated (discard garbage bytes at the end)
PositionX804floatX coordinate of the emitter's world position
PositionY844floatY coordinate of the emitter's world position
PositionZ884floatZ coordinate of the emitter's world position
PresetEffectID924uintDetermines which preconfigured effect should be used (see this list)
EmissionDelay964floatHow fast new particles may spawn (in frames; 60 means 1 second)
LaunchParameterA1004floatConfigures the preset effect (meaning depends on PresetEffectID)
LaunchParameterB1044floatConfigures the preset effect (meaning depends on PresetEffectID)
LaunchParameterC1084floatConfigures the preset effect (meaning depends on PresetEffectID)
LaunchParameterD1124floatConfigures the preset effect (meaning depends on PresetEffectID)

How launch parameters are used needs to be determined on a per-effect basis. Each emitter will process them differently.

Quad Tree

The layout for this data structure corresponds to a fixed-size quad tree with 5 levels, each consisting of four sub-ranges:

FieldOffsetLengthTypeDescription
BottomLeftQuadrant048QuadTreeRangeVolume for the area south-west of the previous level's center
BottomRightQuadrant4848QuadTreeRangeVolume for the area south-east of the previous level's center
TopLeftQuadrant9648QuadTreeRangeVolume for the area north-west of the previous level's center
TopRightQuadrant14448QuadTreeRangeVolume for the area north-east of the previous level's center

Quadrants always exist for each of the upper levels of the hiararchy, but are NULL if it's a leaf node (sub-tree at level 5).

Quad Tree Range

Each range defines an axis-aligned bounding box that can be used to store all visible elements in this part of the scene:

FieldOffsetLengthTypeDescription
BottomX04floatX coordinate of the corner at the lowest altitude
BottomY44floatY coordinate of the corner at the lowest altitude
BottomZ84floatZ coordinate of the corner at the lowest altitude
TopX124floatX coordinate of the corner at the highest altitude
TopY164floatY coordinate of the corner at the highest altitude
TopZ204floatZ coordinate of the corner at the highest altitude
DiameterX244floatWidth of the bounding box (when interpreted as a cuboid)
DiameterY284floatHeight of the bounding box (when interpreted as a cuboid)
DiameterZ324floatDepth of the bounding box (when interpreted as a cuboid)
CenterX364floatX coordinate of the point in the exact center of the box
CenterY404floatY coordinate of the point in the exact center of the box
CenterZ444floatZ coordinate of the point in the exact center of the box

Version 2.2

Changes the file header slightly, adding a BuildNumber (in this version, a uint8 value) after MinorVersion.

Version 2.3

No superficial changes to the layout have been observed. More research is needed.

Version 2.4

No superficial changes to the layout have been observed. More research is needed.

Version 2.5

The BuildNumber is now a uint32 value. An additional uint8, tentatively called UnknownRenderFlag, appears immediately afterward.

Version 2.6

The water plan setup was moved to the GND file. While the BuildNumber is 161 or lower, no other changes have been observed.

Version 2.6.162

In files using a BuildNumber of 162 or higher, the layout for animated props (RSM models) changes slightly:

An unknown byte (seemingly a uint8 value, possibly a boolean flag) has been added after the CollisionFlags field.