PWT File Specification

This is the specification for the exported case file that is used by the player to run user made cases. The file is broken up into chunks, which are basically groups of data that make up certain elements, like characters, backgrounds, etc. Each chunk contains several data types, which are discussed in the coming sections.

  1. General
  2. Data Types
  3. Header
  4. Chunks
    1. Overview
    2. Overrides
    3. Characters
    4. Images
    5. Backgrounds
    6. Evidence
    7. Locations
    8. Audio
    9. Testimonies
    10. Text Blocks


General

The PWT file format is actually really simple. It may resemble the Quake 3 model and map formats for those of you who have worked with them. Regardless, this is the basic structure of the file:

Header
First Chunk
Second Chunk
...

Chunks will be discussed in the next section, but before we go that far, it's necessary to discuss a few things. First, you'll notice that the amount of chunks in the file is variable. This allows for the file to be extended without breaking compatability with older players and editors. New chunks that may be added in future versions will always have their own offset registered in the header, and so there is no need to worry about having to read the file in a different order. Furthermore, if you are going to try to load this file, make sure you don't do it in a linear fashion. Instead, use the offsets in the header to skip to the different chunks.

Each chunk is made up of data that is specific to a certain element of a case. For example, the chunk that stores data about characters will include names, descriptions, etc. If you don't grasp this concept, think of chunks as building blocks, where each one adds something to the case.


Data Types

Before you try to read the separate chunks, you need to know the different data types that are present. Here is a basic rundown of the data types, their sizes, and their uses:

TypeSize (bytes)Uses
int4Stores various integer amounts
uchar4UNICODE character, used primarily in strings
bool1A Boolean value; holds true or false
string
(see below)
image
(see below)

String

A string is a series of uchars, and it can contain any amount of characters. Strings are saved in a specific format, where each string begins with an int that defines the length. Afterwards, that amount of uchar values exist. Take the string 'Hello World!' for example. This is how it looks in the file:

intucharucharucharucharucharucharucharucharucharucharucharuchar
11Hello World!

Image

Images are stored as highly compressed PNGs. Each image has a size saved with it, that determines the size of the PNG data buffer. Loading the actual PNG data is up to you.

Data TypeValueDescription
intlengthThe size of the image buffer
charlengthThe actual image data buffer


Header

The header stores the file's magic number and version, along with offsets into the chunk sections. This is the format of the header:

Data TypeValueDescription
intidentMagic number, should always be equal to 'PWT'
intversionThe file's revision number
intoverviewOffsetOffset into overview
intoverridesOffsetOffset into overrides
intcharOffsetOffset into characters
intimgOffsetOffset into images
intbgOffsetOffset into backgrounds
intevidenceOffsetOffset into evidence
intlocationOffsetOffset into locations
intaudioOffsetOffset into audio
inttestimonyOffsetOffset into testimonies
intblockOffsetOffset into text blocks


Chunks

This section describes the chunks that are present in the file.

Overview

The Overview chunk provides basic data about the case itself. Its format is as follows.

Data TypeValueDescription
stringnameThe name of the case
stringauthorThe author's name
intlawSysThe law system, describing amount of trial days


Overrides

Overrides let the user customize otherwise internal elements of the player. This includes the transparency of text box, the title screen, and other things.

Data TypeValueDescription
inttbAlphaThe text box transparency value
stringtitleScreenID of the image to use for the title screen
stringinitialBlockID of the block where to start parsing the script


Characters

The Characters chunk holds data about all of the characters present in the case. This does not include the characters that are included in the player's resource file.

Data TypeValueDescription
intcountThe amount of characters
stringinternalNameThe internal name
stringdisplayNameThe display name
intgenderGender of the character
stringcaptionText to display in Court Record in the green box
stringdescriptionText to display in Court Record below the profile
stringspriteNameFile name of sprite, or "null" if none
boolhasTextBoxTagWhether or not this character has a tag for the text box
imagetextBoxTagIf hasTextBoxTag is TRUE, then this is the text box tag image
boolheadshotWhether or not this character has a profile image
imageprofileImgIf headshot is TRUE, then this is the image for the Court Record profiles
imagesProfileImgIf headshot is TRUE, then this is the scaled profile image

The only things that are important to note are the hasTextBoxTag and headshot Booleans. If, and ONLY if they are TRUE, should you read the following images. So if hasTextBoxTag is FALSE, you should proceed right to the headshot value, bypassing the image altogether.


Images

The Images chunk stores miscellaneous images and other pictures that are used in specific areas of the case. Such include the images used for the characters positioned in the courtroom overview scene. Also, these images can be used for the set_temp_image trigger, among others.

Data TypeValueDescription
intcountAmount of images
stringidInternal ID for this image
imagetextureThe actual image


Backgrounds

This chunk stores the data about the backgrounds used for other locations.

Data TypeValueDescription
intcountAmount of backgrounds
stringidID of the background
intbgTypeHow many screens does the background span
imagetextureThe actual image for the background


Evidence

All of the case evidence is stored in this chunk.

Data TypeValueDescription
intcountAmount of evidence
stringidID of this evidence
stringnameDisplay name
stringcaptionShort text to describe the evidence
stringdescriptionText displayed below entry in Court Record
stringcheckIDID of image that can be checked, or "null" if none
imagetextureThe actual image of the evidence
imagesTextureScaled image used in Court Record

The checkID contains the ID of an image that the user can examine when he or she clicks the Check button in the Court Record. Of course, most evidence won't have such an image, and so this value may be "null" in that case.


Locations

All of the user made locations are stored in this chunk. Each location has a set of examinable hotspots, along with variable states. These are all described in this section. First, here is the format of this chunk:

Data TypeValueDescription
intcountAmount of locations
stringidInternal ID
stringnameDisplay name
inthcountAmount of hotspots
Hotspot-(see relevant info below)
intscountAmount of location states
State-(see relevant info below)

Here is the format of the hotspots, known in the code as the Hotspot struct:

Data TypeValueDescription
intxTop-left x coordinate of the bounding box
intyTop-left y coordinate of the bounding box
intwWidth of bounding box
inthHeight of bounding box
stringtargetID of the target text block to execute

Finally, here is the format for a location state. Note that in the code, the states are stored as a key:value map of the state ID to the background ID for that state.

Data TypeValueDescription
stringstateIDID of this state
stringbgIDID of background for this state


Audio

Although none of the audio, apart from sound effects, is stored in memory when the player loads, this chunk specifies user included sound effects and music for this case. All audio file paths are relevant to where the actual *.pwt case file is.

Data TypeValueDescription
intcountAmount of audio samples
stringidInternal ID
stringfilenamePath to the sample, relative to case root path


Testimonies

This chunk stores all the data about the testimonies present in the case. Testimonies have some general data, along with the actual contents of the testimony. They are comprised of pieces, and each piece can have evidence presented, be pressed, and be hidden.

Data TypeValueDescription
intcountAmount of testimonies
stringidThe internal ID
stringdisplayNameDisplay name of testimony
stringspeakerID of speaking character
stringnextBlockID of block to follow once testimony is spoken
stringfollowLocationID of location to go once testimony is spoken
stringxExamineEndBlockID of block to follow once user completes cross examination
inttPieceCountAmount of pieces
TestimonyPiece-(see relevant info below)

Finally, here is the format of testimony pieces, known in the code as the TestimonyPiece struct:

Data TypeValueDescription
stringtextThe actual text content of the testimony piece
stringpresentIDID of evidence that can be presented, or "null" for none
stringpresentBlockID of block to follow if correct evidence is presented, or "null" for none
stringpressBlockID of block to follow if witness is pressed
boolhiddenWhether or not this piece is initially hidden


Text Blocks

Finally, this is the meat and bones of the case file. The text blocks are stored here, along with IDs to reference them from within the script.

Data TypeValueDescription
stringidID of the block
stringtextActual text contents of this block



Hosted on Sourceforge.net. All Phoenix Wright trademarks and other property are copyright Capcom.