FAQ
Why isn't my script working correctly?
Whenever something doesn't work, you should look at allegro.log to see if any errors have been reported. You'll get more helpful messages using full logging, which is enabled by importing loggingFull.zh instead of loggingMinimal.zh. These are found near the bottom of the main file.
Some common errors:
-
Using more styles than alloted
- Fixed by increasing
__TANGO_NUM_STYLES
and the size of__Tango_Styles[]
- Fixed by increasing
-
Using more menu options than alloted
- Fixed by increasing
__TANGO_MAX_MENU_ITEMS
and the size of__Tango_Data[]
- Fixed by increasing
-
Incorrect constants for custom functions
- Use
Tango_ConvertFunctionName()
to make sure you've got them right
- Use
You can also try calling the function Tango_ValidateConfiguration()
. This will
analyze your settings and report any errors it finds in allegro.log.
How do I display a string?
- Find a free text slot (
Tango_GetFreeSlot()
) - Clear all data in the slot (
Tango_ClearSlot()
) - Load text into the slot (
Tango_LoadString()
orTango_LoadMessage()
) - Set a style (
Tango_SetSlotStyle()
) - Set the position on the screen (
Tango_SetSlotPosition()
) - Activate the text slot (
Tango_ActivateSlot()
)
Tango_LoadString()
loads a ZScript string (an int
array);
Tango_LoadMessage()
loads a ZC message (Quest > Strings). All built-in
function names follow this naming convention.
You'll probably want to combine these into a single function for simplicity.
tangoQuickStart.zh provides examples in the ShowString()
and ShowMessage()
functions.
What is a text slot?
Text slots are where strings are stored for processing and display. They store the text, the style, and the position on the screen, as well as some internal data. Before any text can be shown on the screen, it must be loaded into one of the available slots.
Slot IDs are integers counting up from 0. Most often, you'll want to find a free slot automatically, but you can also use hardcoded slot numbers. Each slot has its own definition, which determines how long a string can be and how much space is available for drawing it.
What is a style?
A style determines the appearance and behavior of displayed text. For instance, the font, the backdrop, and whether the text can be sped up by holding A are all controlled by the style.
Style IDs are integers counting up from 0. Every text slot using the same style will have the same appearance and behavior.
How many text slots do I need?
You need at least as many slots as will ever be active at once. If you want fifty strings onscreen at once, you need fifty slots. If you only want one string active at a time, just one slot will suffice.
For more advanced uses, you may want more slots than are strictly necessary. For instance, you might want to reserve certain slots for specific purposes, even if they'll never all be in use at once.
How do I add more text slots?
Set __TANGO_NUM_SLOTS
to the number of slots you want and change the size of
__Tango_Buffer[]
so that it's large enough to hold the text for all of them.
The slot definitions go in __Tango_SlotDefs[]
. The first seven numbers define
slot 0, the next seven define slot 1, and so on. In order, these numbers are
the slot type, the starting index and size in __Tango_Buffer[]
, the X and Y
coordinates on the bitmap, and the width and height on the bitmap. For example:
int __Tango_SlotDefs[] = { // Slot 0 TANGO_SLOT_NORMAL, // The slot type 0, 512, // Occupies __Tango_Buffer[0] to __Tango_Buffer[511] 0, 0, // Draws to a region at 0, 0 on the bitmap 192, 128, // Drawing region is 192x128 pixels // Slot 1 TANGO_SLOT_SMALL, 512, 64, // Occupies __Tango_Buffer[512] to __Tango_Buffer[575] 0, 128, // Draws to a region at 0, 128 (just below slot 0) 128, 32 // Drawing region is 128x32 // Slot 2 TANGO_SLOT_SMALL, 576, 64, // Occupies __Tango_Buffer[576] to __Tango_Buffer[639] 0, 160, // Draws to a region at 0, 160 (just below slot 1) 128, 32 // Drawing region is 128x32 };
The slot type is arbitrary. It can be any non-negative number. The default
slot type, TANGO_SLOT_NORMAL
, can safely be renamed or deleted.
Generally, you shouldn't let slots overlap in the buffer or the bitmap. If they won't be in use at the same time, however, it won't cause problems. If you use a very large number of slots, it may even be necessary for them to share some space on the bitmap.
What is the purpose of slot types?
A slot's type makes no difference to how it's handled internally. The only
thing it actually affects is what's returned by Tango_GetFreeSlot()
. Slot
types exist for users to create their own distictions. There are three reasons
you might use different slot types:
-
Reservation
In order to display a string, you must first have a free slot. If no slots are free, you can't show any text without clearing one out. If there's something you need to be able to display, you can create a dedicated slot type for it, so there will always be a slot free when you need it.
For instance, suppose you want NPCs to spout random lines of dialog in the background. You might define several slots of type
SLOT_BG
to use for this purpose, and one of typeSLOT_FG
for the text box when Link talks to someone. This way, you can have the NPCs use as manySLOT_BG
slots as they like, and the mainSLOT_FG
will always be available when you need it. -
Drawing order
Text slots are drawn to the screen in order from first to last. If you want certain strings to be drawn above or below others, you can enforce this by using different slot types.
Going back to the same example, you wouldn't want your NPCs' random lines to appear on top of the main text box. If slots 0-4 are
SLOT_BG
and slot 5 isSLOT_FG
, you can be sure the most important text will always be on top. -
Efficient use of space
If you plan to have one or two long strings appear alongside a lot of short ones, you can use different slot types to avoid wasting space in
__Tango_Buffer[]
. Because__Tango_Buffer[]
is a global array, it is part of the quest's save data. Making it larger than necessary causes useless data to be saved and loaded, making both take a little longer (though only slightly). More importantly, there's limited space for drawing on the offscreen bitmap. If you have ten slots all using 192x128 pixels, they'll have to overlap, potentially causing graphical errors.If your random NPC dialog will only ever be a line or two, you can give
SLOT_BG
a small amount of space in the buffer and bitmap, whileSLOT_FG
might have room for several hundred characters and space to draw a large text box.
Ordinarily, it is expected that all slots of the same type have the same amount
of space allocated in the buffer and on the bitmap, but this is not enforced.
If you want to make some SLOT_BG
s small and some large, you can do that, but
it's up to you to ensure they're used correctly.
How do I create a style?
With a series of calls to Tango_SetStyleAttribute()
. Each call will set
a single attribute of the style. At a minimum, you must set a font and color
for the text. See the constants page for the available settings.
Check out tangoQuickStart.zh for an example.
If you want to unload a style after it's been set up, use Tango_ClearStyle()
.
This is only necessary if you want to reuse an ID for a different style,
which is rarely done.
When should I set up a style?
Any time before it's actually used is fine. The most common method is to set up
all of your styles at the beginning of the active global script. It's also okay
to do it in the Init
script. Styles will stay set up until you clear them or
change them.
Another approach is to set a style up immediately before displaying a string that uses it; this may be preferable when using a large number of different styles.
A combination of those two methods is also possible. If you want multiple styles that are mostly the same, you might set the common attributes in advance and set the distinct ones on demand.
Changing a style while it's in use is permitted, but changes to the text color and font will not affect any text that has already been printed.
Why isn't the screen freeze style flag working?
There are two functions in the main file, __Tango_FreezeScreen()
and
__Tango_UnfreezeScreen()
, that are blank by default. In order for the
screen freeze style flag to work, you must implement these functions.
The reason that they're blank is that there isn't a reasonable default implementation; they're too dependent on the quest. Grabbing arbitrary FFCs or changing combo definitions in an unknown quest might cause serious problems.
The recommended method is to set two unused FFCs to combos of type
Screen Freeze (Except FFCs) and Screen Freeze (FFCs Only). Be aware,
however, that if an FFC script triggers this, that script will freeze, too.
If you're using ghost.zh, SuspendGhostZHScripts()
and ResumeGhostZHScripts()
should be used as well. Other headers may have similar suspend functions that
should also be included.