Mac Software
Software Register Support Gallery About Stick Software Help
divider
 

Eyeballs Skins Manual

Last modified June 15, 2006.

By Ben Haller. Copyright © 2006 Stick Software.


[ A PDF version of this manual is not currently available, because we doubt anybody cares. This manual is only available in English at present. ]

Eyeballs is a Mac OS X application that gives you a fun set of eyeballs in your menu bar or on your desktop. This manual describes how make custom "skins" for Eyeballs. If you are looking for more general information about how to use Eyeballs, please see the Eyeballs User Manual. To download Eyeballs or for other useful information, visit the Eyeballs Home Page.

Please send comments on this manual to us at our support email address. Thanks!


Topics

What is a skin? What do I need to make my own?

How and where do I install skins for Eyeballs?

What is the filesystem structure of a skin?

What goes in the properties plist?

What are the keys supported in the properties plist?

What are the specifics on the image files in the skin?

How do I debug my skin? What are some common issues?

Do you have any suggestions for cool skins?

What do I do with my skin once it's done?


What is a skin? What do I need to make my own?

A skin is a user-customized appearance for an application. In the case of Eyeballs, skins can change the appearance and behavior of the eyeballs, within fairly broad limits. If you can think of a way you would like your eyes to look, you can probably make a skin to do it!

Making your own skins is not a simple process, however. You will need an image-editing program capable of making 24-bit TIFF images with an 8-bit "alpha" (transparency) channel, and you will need to know how to use that program; we will not provide you with technical support regarding how to use whatever image editor you may have. Other image formats are not supported, either because they don't provide the transparency information Eyeballs needs to composite things together, or because they are not supported by the Cocoa image engine that Eyeballs depends upon, or in a few cases, just because we didn't see a reason to further complicate things with multiple formats when TIFF is well-suited to the task.

You will also either need an XML editing application, or you will need to be comfortable with hand-editing XML files; we will not be giving more than the briefest of tutorials on the XML format here. Apple's "Property List Editor", distributed as part of their Developer Tools package, may suffice because the XML files involved are "property lists", a specific XML-based format defined by Apple. Be aware, however, that Property List Editor is fairly buggy, at least in the December 2002 Developer Tools release; we have been unable to use it in-house for our own skin development.

A good skin requires many images to be created that are precisely aligned with respect to each other and have exactly the right transparency to look good when composited. This is not something the average end user will probably be able to do; it really requires a skilled graphic artist to do well. If you suspect you're not up to the task, perhaps you would enjoy using Eyeballs' customizable personalities instead, which also allow you to customize the appearance of the eyes without having to make your own skin from scratch. For more information on customizable personalities, please see the Eyeballs User Manual.


How and where do I install skins for Eyeballs?

Skins for Eyeballs are just ordinary folders, with a file extension of ".eyeskin", containing files of particular names and formats. They can be moved, copied, duplicated, renamed and deleted in the Finder just like any other folders, and they will continue to work as skins provided you don't change the contents of the folder or the ".eyeskin" extension.

However, skins do need to be placed in a special location in order to be found by Eyeballs. There are three places Eyeballs looks in: ~/Library/Eyeballs, /Library/Eyeballs, and inside the Eyeballs application itself. In normal circumstances you will not want to place skins inside the application itself, so that leaves you with the two Library folders. "~" is your home directory; as a location under your home directory, ~/Library/Eyeballs is where to put skins which you want to be visible only to the current user. The other folder, /Library/Eyeballs, is a global location, and skins placed there will be visible to all users of the machine. You may need Administrator privileges to create or modify that folder, however.

If the folder you want to put your skins into doesn't already exist, you can simply create it in the Finder. Then just move or copy your skin files into it, and they should immediately appear in the Personality pop-up in Eyeballs' Preferences Panel. If they do not, closing and re-opening the Preferences panel should refresh the list; but that should not be necessary in general.


What is the filesystem structure of a skin?

The top-level folder is named with the name of the skin plus the extension ".eyeskin". For example, "Blinky.eyeskin" would be the top-level folder for a skin named Blinky. Renaming the top-level folder renames the skin; the name of the skin is not duplicated anywhere in the contents of the folder.

Inside that folder are a bunch of files:

  • properties.plist (required): an XML "property list" that defines and controls the skin

  • TIFF images (some required, some optional): these get composited together in different ways to "draw" the eyeballs

Details about these files are provided in the following sections.


What goes in the properties plist?

The properties plist file (properties.plist) is an XML file in the "property list" format defined by Apple. It is essentially a dictionary of keys and values; you define the values that you want for the different keys. The only required key is "EyeRects"; the rest are optional and have default values explained below.

Before getting into the specific keys, though, let's show a minimal properties.plist file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
    "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">

<dict>
    <key>EyeRects</key>
    <array>
        <string>{x=1; y=3; width=60; height=58}</string>
        <string>{x=66; y=3; width=60; height=58}</string>
    </array>
</dict>
</plist>

The first line defines the file as an XML file and specifies the character encoding of the file as UTF-8. The properties.plist file does not need to be in UTF-8, but the encoding of the file does need to match what is specified here. TextEdit, Apple's text editor, is capable of saving text files in specific encodings; any decent XML editor should also take care of this issue for you. Further discussion of character encodings and specifications is beyond the scope of this manual, as an XML issue; a book on XML ought to cover this topic nicely if necessary.

The second line (which has been wrapped here) specifies the file as being, more specifically, a "plist" or "property list" file conforming to Apple's DTD at the URL specified. This line should simply be preserved without modification.

The third line starts the contents of the property list, and specifies the version of the list's format as being "1.0"; this also should be preserved without modification, unless you know exactly what you are doing.

Next, after the blank line, the top-level dictionary that contains all of the keys and values for the property list is opened. This tag should always be present.

Inside the top-level dictionary are our keys and values, the keys delimited with <key> and </key> tags, the values by different tags depending upon the type of value expected for the key (in this case, an array of strings specifying rectangular areas).

Finally, the top-level dictionary and then the whole property list are closed with end tags.

Apple's Developer website has information about Property Lists, although it may not be useful to non-developers. If you want more interesting sample files, you can look at the properties.plist files in eyeskins made by others (including the ones inside the Eyeballs application itself). More information on the supported keys and their values is in the next section.


What are the keys supported in the properties plist?

The previous section discusses the general format of the properties.plist file. In this section, we present all of the supported keys, their expected value types and defaults values, and samples showing how to use them. You should be able to put together your own properties plist file with this information, or confidently modify the properties file from an existing skin. The supported keys are divided into sections: Eyeball Setup, Size Constraints, Personality, Mobility, Author Information, and Debugging.

Eyeball Setup


EyeCount (integer, default 2, range 1-20)

    <key>EyeCount</key>
    <integer>3</integer>

Specifies how many eyeballs there are in the skin.

EyeRects (array of formatted strings, no default, required)

    <key>EyeRects</key>
    <array>
        <string>{x=1; y=3; width=60; height=58}</string>
        <string>{x=66; y=3; width=60; height=58}</string>
    </array>

Specifies the boundaries of the various eyeballs for this skin. The number of entries should be equal to the value of the EyeCount key. Each eyeball's rect is expressed with an (x, y) origin point and a (width, height) size, where the (0, 0) origin is the lower left corner of base.tiff.

The eyeball rect itself is important primarily for mouse collision detection; the pupils will move inside an area defined by the eyeball rect inset by the pupil inset value (described below). So each eyeball rect should be the bounding rect of an eye in the base image. The eyeballs are assumed to be circles (or ovals) inscribed inside their eyeball rects; this should be at least roughly true, in order for the collision detection and pupil movement to be correct.

The format of the strings is important and must be followed exactly, or the results will be undefined.

PupilInset (integer, default 0)

    <key>PupilInset</key>
    <integer>7</integer>

This value expresses the margin by which the eye rects are reduced in order to determine the area in which the pupils are allowed to travel. With a value of 0, the pupils will be allowed to travel up to the edge of the eye rects. Negative values allow the pupils to travel outside of the eye rects (but they will be clipped at or near the edge of the base image, so if you use this feature, you might wish to leave a transparent margin around the edges of the base image).

PupilInsets (array of integers, no default)

    <key>PupilInsets</key>
    <array>
        <integer>7</integer>
        <integer>10</integer>
    </array>

This is an array of pupil inset values, one per eyeball. It may be defined instead of (but not in addition to) PupilInset and PupilInsetArrays, in cases where the pupil inset should vary among the different eyeballs in the skin.

PupilInsetArrays (array of arrays of integers, no default)

    <key>PupilInsetArrays</key>
    <array>
        <array>
            <integer>17</integer>
            <integer>7</integer>
            <integer>7</integer>
            <integer>17</integer>
        </array>
        <array>
            <integer>7</integer>
            <integer>7</integer>
            <integer>17</integer>
            <integer>17</integer>
        </array>
    </array>

This is an array of arrays of integers; the top-level array contains one subarray for each eyeball, and each subarray contains four integers that specify, respectively, the inset margin for the left, bottom, right and top of that eyerect. Positive margins move inward (i.e. further restrict the travel of the pupil within the eyerect), negative margins move outward. PupilInsetArrays may be defined instead of (but not in addition to) PupilInset and PupilInsets, in cases where total control is needed over the pupil insets because they are irregular or asymmetrical.

PupilInsetArrays is the most powerful (but most complex) way to describe pupil insets. It lets you set up arbitrary rects within which the pupils travel, which may have little or nothing to do with the declared eyerects. The example given above, for example, has a basic inset of 7 all the way around, but the inset on the top of both eyeballs has an extra 10 pixels, the left eyeball has an extra 10 pixel inset on the left, and the right eyeball has an extra 10 pixel inset on the right. This moves the pupil travel areas downward and centerward, making the pupils travel in such a way as to make the eyes appear crosseyed.

As a reminder, the reasons that you would not just change the eyerects themselves are several. The eyerects should reflect the bounds of what appear to be the eyes in base.tiff; if they do not, collision detection with the mouse will not be correct, and eyelid frames will be positioned in an a more difficult-to-work-with manner. The point of having complex pupil insets is to allow the "apparent" eyeballs, as shown in base.tiff, to differ from the actual bounds that the pupils are constrained within.

PupilsCompositeAtopBase (boolean, default false)

    <key>PupilsCompositeAtopBase</key>
    <true/>

If false (the default), the pupil images are composited onto the base image clipping only to the bounding box of the base image, so they can go outside of the base image's opaque area — outside of the "eyes" themselves. If true, the pupil images will be composited "atop" the base image such that the pupils will only "show through" where the base image is opaque, effectively clipping them not to the bounding box of the base image, but to its actual visible appearance. This allows the pupils to slide all the way to the edge of the eyes, as if they are "looking out of the corners of their eyes"; but it probably is a little slower, and will be undesirable in cases where the base image includes some transparency inside the area of the eyes. If you have no idea what this all means, you can try it both ways, and if you can't tell the difference, then leave it as false. ;-> Of the built-in skins, only the Anime skins set this to true; the others all constrain the pupils to travel entirely inside the eyes anyhow, so it would make no difference to them.

Size Constraints


MinSizePercent (integer, default 10, range 5-100)

    <key>MinSizePercent</key>
    <integer>25</integer>

This is the minimum size that the skin is allowed to be scaled to, expressed as a percentage. If it is equal to the maximum size, the size of the skin will be fixed.

MaxSizePercent (integer, default 50, range 5-100)

    <key>MaxSizePercent</key>
    <integer>100</integer>

This is the maximum size that the skin is allowed to be scaled to, expressed as a percentage. If it is equal to the minimum size, the size of the skin will be fixed. The default value of 50 is intended to work well for skins with large images that are designed to be anti-aliased down for higher-quality scaled images.

Personality


Orientation (integer, default 50, range 0-100)

    <key>Orientation</key>
    <integer>80</integer>

The sexual orientation of the eyeballs, where 0 is gay, 50 is bisexual and 100 is straight. This is an inside joke, and has no effect whatsoever on the appearance or behavior of the eyeballs. Not when you're looking, anyhow; what they do in the privacy of their own homes is none of your business.

Alertness (integer, default 3, range 1-5)

    <key>Alertness</key>
    <integer>4</integer>

How long the eyes will stay awake when nothing is happening, how quickly they track the mouse, and other such behavioral variables. 1 through 5 are, respectively, pet rock, drugged, normal, caffeinated and speed freak.

QuiverRate (integer, default 0, range 0-100)

    <key>QuiverRate</key>
    <integer>50</integer>

How much quiver or "jitter" the pupils have. Non-zero values will cause a marked increase in CPU usage, since the eyes will have to be redrawn continuously.

Bloodshot (integer, default 50, range 0-100)

    <key>Bloodshot</key>
    <integer>75</integer>

How bloodshot the eyes are. 0 will result in the eyes never being bloodshot at all, 100 in them usually being fully bloodshot, while values in between will allow the degree of bloodshot to vary based upon time of day, alertness and other factors. The more bloodshot the eyes are, the more opaquely the bloodshot.tiff image is composited in on top of base.tiff. If bloodshot.tiff is not present in this skin, this value will have no effect.

BlinkRate (integer, default 50, range 0-100)

    <key>BlinkRate</key>
    <integer>10</integer>

How often the eyes blink. 0 will result in no blinking, 100 in fairly frenetic blinking. Blinking is accomplished by sequentially compositing the eyelid images in over base.tiff; if eyelid images are not supplied, then this value will have no effect.

Nocturnality (integer, default 0, range 0-2)

    <key>Nocturnality</key>
    <integer>2</integer>

The sleep schedule of the eyes; when they are lively and when they are tired. 0 indicates that the eyes belong to a "morning person" and 1 a "night person", while 2 indicates that the eyes are fully nocturnal.

SynchBlink (boolean, default true)

    <key>SynchBlink</key>
    <false/>

Whether the eyes blink in synchrony or not. There is not currently any way to indicate that individual eyes are or are not synchronized; they all blink together or they are all independent.

SmoothBlink (boolean, default false)

    <key>SmoothBlink</key>
    <true/>

Changes the way that the animation frames for blinking are handled. Normally the speed of the blink animation is determined by personality variables like Alertness. At any given moment, the eyes decide how closed or open they are, and choose an eyelid frame that best expresses that state. However, this can result in eyelid frames being skipped over, or in some frames being displayed more than once during the animation sequence. For example, suppose the eyes decide to blink by first being one-quarter closed, then half-closed, then three-quarters closed, then fully closed (and then the reverse as they open again). If there are eight eyelid frames available, this would mean that frame 2, 4, 6 and 8 will be shown (and then 6, 4, and 2 as the eyes open again); frames 1, 3, 5 and 7 will not be used at all. This results in the eyes blinking at a consistent and predictable speed based upon the personality chosen, but it is poor from the point of view of animation quality.

When SmoothBlink is true, blinking works completely differently. If there are eight eyelid frames, a blink will go 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, regardless of the personality settings. This will look smoother to the user, but it has the perhaps odd consequence that the speed of a blink now depends upon the number of frames provided; if you put twice as many eyelid frames in your skin, it will take twice as long for a blink to be shown from beginning to end. This means that if you turn SmoothBlink on, you must carefully choose the number of eyelid frames you provide in order to convey the personality (sluggish, alert, hopped-up) you want your skin to have. Eyeballs tries to display one blink animation frame every 1/100th of a second when SmoothBlink is turned on; a typical, reasonably alert-feeling skin might have around 8-12 eyelid frames.

It is strongly recommended that skin designers set SmoothBlink to true. However, since it forces consideration of these relatively obscure and non-obvious issues, it is false by default.

Sleepless (boolean, default false)

    <key>Sleepless</key>
    <true/>

Whether the eyes ever actually fall asleep or not; if true, the eyes will remain awake at all times regardless of the values of the other keys (but the other keys will still be used to determine how alert, lively, bloodshot, etc. the eyes are at any given time). Typically, skins with no eyelids will want to be sleepless; when the eyes fall asleep the pupils no longer follow the mouse, and if there are not eyelids closed to obscure the pupil, that will be visible to the user and will usually look odd. However, it is legal to set up such a skin, since it may make sense in some cases.

Mobility


Sessile (boolean, default false)

    <key>Sessile</key>
    <true/>

Causes the eyes to be sessile, i.e. immobile. The user will still be allowed to drag them to relocate them, but the ability to wander or avoid the mouse will be disabled. This would be appropriate for a skin which had the appearance of immobility, such as eyeballs embedded in a mesh of webbing that appeared to tie the eyes to the desktop, or eyeballs set in a steel plate bolted to the desktop.

Note that setting any of the TiedToX flags described below implicitly sets this flag to true; if the eyes are tied to an edge, they are assumed to be immobile.

TiedToTop (boolean, default false)
TiedToBottom (boolean, default false)
TiedToLeft (boolean, default false)
TiedToRight (boolean, default false)
TiedToMenubar (boolean, default false)

    <key>TiedToTop</key>
    <true/>

These flags constrain where the eyes are allowed to be placed, tying their position to the top, bottom, left or right edges of the monitor, or to the bottom of the menubar. This would be appropriate for skins which appear to grow out of or attach to the edge of the screen, such as eyes on stalks, or eyes hanging from strings. Pairs of flags, such as TiedToRight and TiedToBottom, may be set together to constrain the placement of the eyes to only that corner of the monitor. Flags which are opposites, such as TiedToLeft and TiedToRight, may not be set together.

TiedToMenubar ties the eyeballs to the bottom of the menubar instead of to the top of the monitor, for skins which do not wish to intrude upon the menubar area; it may not be set at the same time as TiedToTop, and in situations (such as secondary monitors) where there is no menu bar, it acts identically to TiedToTop.

When the eyes are being displayed in the menu bar instead of on the desktop, TiedToLeft and TiedToRight have no effect, while TiedToTop (or TiedToMenubar) and TiedToBottom tie the eyes to the top or bottom of the menu bar, instead of the monitor as a whole. If a skin is designed to be tied to the left or right, and the user puts it in the menu bar, it will presumably look funny; so it goes.

Note that if any of these flags is set, the Sessile flag is implicitly set also; if the eyes are tied to an edge, they are assumed to be immobile.

BouncySkin (boolean, default false)

    <key>BouncySkin</key>
    <true/>

Whether the skin as a whole should be considered "bouncy" when mouse avoidance has been turned on by the user. If this flag is true, an oval fitted into the base.tiff bounds (inset or outset by the bounce margin) will be used for mouse avoidance. If this flag is false, each individual eyerect's bounds (again, inset or outset by the bounce margin) will be used, and the parts of the skin outside the eyerects will not trigger mouse avoidance.

BounceMargin (integer, default 0, range -100 - 100)

    <key>BounceMargin</key>
    <integer>10</integer>

This is a margin added around the "bouncy" areas of the skin prior to evaluating mouse avoidance, when mouse avoidance has been turned on by the user. When it is zero (the default), oval areas defined by the individual eyerects (if BouncySkin is false) or by base.tiff's bounds (if BouncySkin is true) will be used in avoiding the mouse. When it is negative, those oval areas will be inset by the given number of pixels, making a smaller bouncy area; when it is positive, they will be outset, making a larger bouncy area.

Author Information


AuthorName (string, no default)

    <key>AuthorName</key>
    <string>Ben Haller</string>

The name of the author of the skin. This is displayed in the Preferences panel when the skin is selected.

AuthorEmail (string, no default)

    <key>AuthorEmail</key>
    <string>spam@sticksoftware</string>

The author's email address. A hyperlink to this address will be placed on the author's name in the Preferences panel if the AuthorName key has also been defined; if not, this email address will be displayed in lieu of the author's name.

AuthorHomePage (string, no default)

    <key>AuthorHomePage</key>
    <string>http://www.sticksoftware.com/</string>

A URL to the author's home page. This URL will be displayed in the Preferences panel as a hyperlink when the skin is selected.

Debugging


OutlineBaseRect (boolean, default false)

    <key>OutlineBaseRect</key>
    <true/>

Turns on the drawing of an outline around the entire base rect, in blue. Helps to find the boundaries of the base rect when the base image is mostly transparent.

OutlineEyeRects (boolean, default false)

    <key>OutlineEyeRects</key>
    <true/>

Turns on the drawing of outlines around each individual eye rect, in red. Helps to find and align the eye rects properly.

OutlinePupilAreas (boolean, default false)

    <key>OutlinePupilAreas</key>
    <true/>

Turns on the drawing of an outline around the bounds of the area that the pupil is allowed to move inside, in black. Helps to debug pupil insets and pupil images.

OutlinePupilRects (boolean, default false)

    <key>OutlinePupilRects</key>
    <true/>

Turns on the drawing of an outline around each individual pupil, in green. Helps to debug pupil insets and pupil images.


What are the specifics on the image files in the skin?

All of the image files in the skin folder must be 24-bit TIFFs with an 8-bit "alpha" (transparency) channel. It is recommended that skins contain images at double the maximum intended final size, so that antialiasing can produce the best-looking possible eyes. The MaxSizePercent key will allow you to limit the maximum final size to 50% of the original base image size, so that this internal implementation detail is invisible to the user. Images must be named exactly as described below, or Eyeballs will not be able to locate them. The supported images are divided into sections: Overall Skin, Pupils, and Eyelids.

The order of compositing should be noted. The base.tiff image goes down first, then bloodshot.tiff (to the extent it is visible), then the pupil image, then the eyelids (if they are not completely open), and finally overlay.tiff goes on the top. This is usually the right ordering, although it is occasionally limiting, as in the fact that the contents of the overlay layer cannot be changed according to the degree of bloodshot.

Overall Skin


base.tiff (required)

Provides the foundation image for the whole set of eyeballs, upon which pupils, eyelids and other ornaments are composited. This image should be big enough to encompass all of the EyeRects enumerated in the properties.plist file, and in most cases each EyeRect will have a visual representation in the corresponding area of the base.tiff image.

bloodshot.tiff (optional)

Provides a bloodshot appearance of varying intensity, provided by compositing with varying opacity on top of the base.tiff image. If not present, the eyes will not become bloodshot. This image must have exactly the same dimensions as base.tiff. It is not necessarily only bloodshot capillaries, despite the name; it could cause baggy shadows to appear under the eyes, for example, or redness to appear around the rims of the eyes.

overlay.tiff (optional)

Provides the ability to add a final overlay on top of the final, composited eyes. This allows you to modify the final appearance of the eyes in a way that will not be obscured by eyelids, pupils or bloodshot. For example, this image might contain a pair of glasses, or a piece of jewelry that hangs over the eyes, or a lock of hair.

Pupils


pupil.tiff (either this or pupilX.tiff is required)

A single pupil image to be used in all of the eyes in this skin. The actual image is assumed to lie roughly inside a circle (or oval) inscribed within the bounds of the pupil image. If that is not the case, the pupils may not move within the eye rects as one would expect.

pupilX.tiff (either this or pupil.tiff is required)

A set of images (pupil1.tiff, pupil2.tiff, ...) to be used as pupil images in the respectively numbered eye rects. This allows the pupil appearance of each eye to be different. In all other respects these images work in the same way as the single pupil.tiff image would.

Eyelids


eyelidStageY.tiff (either this or eyelidXStageY.tiff is required)

A set of images (eyelidStage1.tiff, eyelidStage2.tiff, ...) to be used as eyelid animation frames in all of the eyes in this skin. As many frames may be provided as the designer wishes, but it is not guaranteed that all of the frames will actually be displayed in any given blink sequence. Eyeballs decides, for every animation frame, what fraction of the way from open to closed it wants the eyelids to be, and then displays the image whose sequential number is closest to that position. So if 10 stage images are provided (eyelidStage1.tiff, ..., eyelidStage10.tiff), Eyeballs might animate a blink by showing all 10 frames, or it might do it by showing only frames 3, 6 and 10. This is governed by how quickly the blink is supposed to happen, which is in turn governed by the Alertness setting (and perhaps other values). (However, this works completely different if the SmoothBlink flag is turned on in the skin's .plist file; see that section for details).

Each frame of animation must have the same dimensions. Typically, the animation for a given eye rect will have dimensions exactly matching those of the eye rect itself, since the eyelid is intended to cover the eye rect. This is not required, however; eyelid animations that differ in size will be centered over their eye rect. If you intend to make an animation that goes outside of the eye rect itself, however, you should make sure that it is still entirely within the boundaries of the base image, or it may be clipped. Transparent space may be added around the edges of base.tiff to provide an adequate margin if necessary.

Optionally, an image titled "eyelidStage0.tiff" may be provided in addition to the other images. If it is present, it will be displayed whenever the eyes are completely open; if it is not present, then when the eyes are completely open no eyelid image at all is displayed. An eyelidStage0.tiff image would be used when some vestige of eyelids (such as eyelashes, or wrinkles of skin around the eye) should be visible when the eyes are fully open. Such an appearance could not be put into base.tiff, since there would be no way for that appearance to be overdrawn when the eyelids were in other positions.

eyelidXStageY.tiff (either this or eyelidStageY.tiff is required)

A set of sets of images (eyelid1Stage1.tiff...eyelid1StageY.tiff, eyelid2Stage1.tiff...eyelid2StageY.tiff, ..., eyelidXStage1.tiff...eyelidXStageY.tiff) to be used as eyelid animation frames for the various eyes in the skin. The first number in the filenames, X, is the index of the eye rect that that set of images (eyelidXStage1.tiff...eyelidXStageY.tiff) is to be used for. The second number in the filenames, Y, is the animation frame index. So an image named eyelid3Stage7.tiff is the 7th frame of animation for the eyeball in eye rect 3.

Each eye rect must be given the same number of frames of animation; the maximum value of Y must be the same for every value of X, in other words. Each frame of animation must have the same dimensions, for the whole animation sequence for any given eye rect (but the dimensions for the animations for different eye rects may and often should differ).

Optional images named "eyelid1Stage0.tiff" through "eyelidXStage0.tiff" may be provided to supply an eyelid appearance when the eyes are fully open, in the same way as the "eyelidStage0.tiff" image. If one such image is provided, they must all be provided (but may be completely transparent for some eyes if so desired).

In all other respects these images work in the same was as a single set of eyelidStageY.tiff images would.


How do I debug my skin? What are some common issues?

The most common problem when developing a skin is that Eyeballs will not let you choose your skin in the Personality pop-up of the Preferences panel. When you try, you get an error message like "The .eyeskin file "Blinky" could not be used because it was incorrectly formatted." When this message is displayed to you, a supplementary error message with a more detailed explanation of the problem should also be displayed, to help you debug the problem.

These messages will tell you about a great many problems with your skin files. Sometimes, though, Eyeballs will be willing to let you choose your skin, but what gets displayed is not what you expected. To help with this type of problem, several debugging-oriented keys can be defined in your properties.plist file, such as OutlineBaseRect. You can read the description of those keys in the section on debugging keys in this manual.

To finish off this section, we'll list some problems we expect skin designers to commonly hit that the debugging techniques described above probably won't help with. If the advice below does not fix the problem, then contact our support email address and send us your skin together with a detailed description of where you installed it, what happens when you select it in the Preferences panel, and what exactly the problem is that you're having. If you can take a screenshot that illustrates the problem, that would be very helpful.


My skin does not appear in the Personality menu

First, check that it has been correctly placed in /Library/Eyeballs or ~/Library/Eyeballs. Second, check that the name of the top-level folder for the skin ends in the extension ".eyeskin"; for example, "Blinky.eyeskin". Third, try closing and reopening the Preferences window; this should not normally be necessary, but there are cases where Eyeballs will not immediately notice a skin that has just been copied in. Fourth, try quitting and restarting Eyeballs; perhaps some internal glitch has confused it. Fifth, look really carefully at the menu to make sure your skin really isn't listed there (the skins are listed in a separate section from the non-skin personalities).


My eyes never blink

First, check that the names of your eyelid images exactly conform to one of the two supported naming schemes; if they are named incorrectly, they will not be found, and Eyeballs will assume that you simply do not wish your eyes to blink. Second, check the BlinkRate key's value in your properties.plist file to make sure it is non-zero; you might try setting it to 100 temporarily just to make sure this is not the problem.


The pupils are not positioned correctly

How the pupils are positioned is a result of several different factors. Check your eye rects, using the OutlineEyeRects debugging flag, to make sure they are positioned correctly. Check your pupil inset values in your properties.plist file to make sure they are defined with the value you want, and check your pupil images to make sure the most visible part of the image is centered in the image; the OutlinePupilAreas and OutlinePupilRects flags may help with this. Check that your pupils are roughly circular or oval and are roughly inscribed inside the bounds of their images; Eyeballs expects the pupil images to be set up this way, and if they are not, it may result in them being drawn in an unexpected place.


My skin appears shrunken

The size of the original images in a skin is not necessarily, or even usually, the size that the skin ends up displayed at. First check that the "size" slider in the Preferences panel is all the way to the right. If it is, and your skin is still smaller than its original size, then check the value of the MaxSizePercent key in your properties.plist file. The default value for this key results in a maximum size that is 50% of the original size. This is intentional; it is designed this way to encourage skin designers to make their skins at double size, allowing for higher-quality scaling of the skin when Eyeballs displays it at the size the user has chosen. If you really wish to override this, however, you can define MaxSizePercent to be 100, and the maximum size for your skin will then be equal to the original size of the images.


My eyes are never bloodshot

First, check that your bloodshot.tiff file has exactly that name; if it is not named exactly correctly, Eyeballs will not find it and will assume that you do not wish your eyes to have a bloodshot appearance. If bloodshot.tiff exists and is correctly named, then check the value of the Bloodshot key in your properties.plist file to make sure it is non-zero; you might try setting it to 100 just to make sure this is not the problem. Intermediate values for Bloodshot will not necessarily result in intermediate degrees of bloodshot being displayed. A value of 50, for example, means that your eyes will sometimes be completely bloodshot (when they are tired and have been kept awake, for example), and will sometimes be completely clear (when they are well-rested).


Do you have any suggestions for cool skins?

Users have sent us a great many ideas for Eyeballs, more than we could ever implement on our own. Some of those ideas can now be implemented by skin designers, so we'll post them here in the hopes that they will inspire someone!

Adornments: There are lots of things that could "accessorize" a skin. Glasses, or a pirate eye patch, or a monocle. Piercings. Eyelashes or eyebrows. Makeup, or special "colored contacts" with designs on them.

Photorealism: One approach to a skin would be to make a skin that looks, as realistically as possible, like a human eye, or a cat eye, or a penguin's eye, or whatever. Another would be to make eyes that look like no real eyes in the world ever could: pixellated, or Dr. Seuss-shaped, or fractal, or cubist.

Arrangements: Skins allow eyes to be arranged spatially in any way at all. The main thing that determines which way is "up" for an eye is the direction that its eyelid closes in from; if the eyelid images are rotated, "up" could be to the right, or anywhere else. (For eyes that are non-circular, or that have non-circular pupils, the axis of the ovals is assumed to be orthogonal, which does constrain designs somewhat; this is not expected to be excessively limiting). So you could make an arrangement of eyes in a pentagram, and have each eye's "up" direction be different such that all the eyelids come down towards the center of the pentagram. Or perhaps "up" is towards the top, but the eyes are not arranged neatly left-to-right. Eyes in a skin don't need to be the same shape or size, and their pupils and eyelids can all be different, so all sorts of odd arrangements are possible!

Quirks: The eyes could have different iris colors, like David Bowie (or many cats). They could have unusually shaped pupils or eyes, from amorphous blobs to pointy stars. They could blink in an unusual way; one idea a user sent in was that the eyes could have a two-stage blink with a "nictating membrane" such as some animals have, which would just be a matter of doing the proper animation in the eyelid images.

Context: One interesting thing a skin can do is to provide context for the eyes. Perhaps the eyes are suspended in spider-webbing designed to string across the corner of the user's monitor. Perhaps the eyes are on stalks that attach them to the bottom of the screen. Perhaps they are designed to go with a "theme" such as those supported by Unsanity's ShapeShifter. Perhaps they attach to the Dock somehow. Perhaps the skin provides a whole "critter" that the eyes are inside, like a little head or a whole little person or animal.

Random thoughts: Here are a few things I'd like to see. A stereotypical "alien head" with those big, liquid-looking eyes. Eyes suspended along a string of wires, like Christmas lights for the Addams family. Eyes that completely integrate into the menu bar, as if the menu bar itself had eyes (rather than looking like the eyes were just overlaid onto the menu bar or inset into it); the "skin" of the menu bar would stretch and wrinkle around the openings in it, as skin does around real eyes. Really good cat eyes. A nice gruesome single eyeball that looks like it has just been removed from someone's head, for Halloween. A row of tiny little people who stand at the bottom of the user's screen, all looking up with tiny little eyes. A pyramid with an eye on the top of it, like the Masonic symbol on the one-dollar bill. A little tree with an eyeball hanging at the end of each branch.

There are certainly limitations to the eyeballs skin model: the only animation possible is in blinking, for example, and emotions the eyes may be feeling can't be expressed in the skin (like different eyebrow positions). But within this framework, we think a great many cool things should be possible. We hope this captures the imaginations of the designers out there; we need your help!

If you have a cool skin idea but Eyeballs isn't quite set up to allow it, let us know. We don't want to go to great lengths to support individual skin ideas, but if we could easily add a key to the properties.plist file that would allow us to support what you have in mind, we'll consider it!


What do I do with my skin once it's done?

Assuming your skin does not recycle copyrighted images that belong to Stick Software, the simple answer is "whatever you like". It is your creation, and Stick Software has no rights to it whatsoever. Post it on your website, email it to your friends, share it around. Link back to the Eyeballs home page at http://www.sticksoftware.com/software/Eyeballs.html to let people know about Eyeballs (since your skin isn't terribly useful without our app). Copyright it if you like; we recommend putting a file named Copyright.txt inside the .eyeskin folder with a brief copyright notice and any other licensing terms you intend to apply to your skin. Or don't, in which case you might put a file name PublicDomain.txt inside the .eyeskin folder declaring the skin to be public domain.

If you think your skin is cool enough to merit inclusion in a future release of Eyeballs, or to be posted on the Stick Software website, feel free to email it to us. If a skin is emailed to us, we will assume that we have been granted full, non-exclusive, non-revocable rights to copy, modify, distribute and sell that skin, whether packaged as part of Eyeballs or posted separately on our website, unless you explicitly notify us otherwise in the same email in which you enclose the skin. We will keep your author information intact in the skin, and will credit you in whatever other way seems appropriate to us, and we'll let you know if we decide to publish your skin. We cannot provide financial compensation to the creators of skins; sorry!