parent nodes: hotkeys | YSokoban

Skins

You can change the sokoban visual elements (wall, box, goal, etc.) via a skin. With different skins YSokoban will look in a different way.
Function keys F3 to F8 can be defined to use different skin for each key.
YSokoban can automatically resize skin, but smaller skins doesn't look good when enlarged.
It's better to have large skin and resize it down to smaller size.
So all skins with size more than 40 pixels are considered resizable by default.
Following keys control resizing:

Skin options dialog

Activated via main menu -> Skins. It brings a dialog where one can define which skin (bmp or png file) to be used for every functional key. Usually skins are copied into folder where YSokoban resides.

Other options in this menu has following meaning: Example: Show/Hide grid (try with default skin pressing F7 and ctrl-F7 to show/hide grid):


Skin history

Skins for YSokoban started as a simple BMP file. Intention was to keep them as simple as possible and preferably to have just one file, so that user should not take care for folders with files, keeping together several parts of a skin (if tiles are different images and/or if there are some special text file in addition to a bmp).
NOTE: the word "cell" and "tile" are used interchangeably in this file.

Old skin format

What YSokoban needs is following: In YSokoban it is possible to select box or man and click on some tile and man will push box there (or will just go there). So YSokoban needs a way to mark selected object. Best thing is to have this animated. When level is completed then same animation is used for all objects.

All walls (at that moment) are represented by 16 possible tiles. So they occupy 4x4 tiles from image.

For animation YSokoban uses one row per object - man, man on goal, box, box on goal. This takes 4 more rows. First two rows are used for empty tile, man and box, on next row I have goal, man on goal, box on goal. Two unused tiles were used to put invalid selection for boxes.



(I think YSokoban still supports it, but does not scale it, i.e. it is not resizeable).

Later on I realize that there are some features I want to have, but it is not possible with this skin. This is:
    ########
    #-.--$-#
    #-####-#
    #-####-#
    #-####-#
    #----@-#
    ########
Result (with old skin) of above level is


New skin format

New skin format was designed to serve this needs, but it is not possible anymore to have all possible tiles (or should I say, it will be not nice to draw all of them). Instead we draw only building parts of a walls and combine them on the fly.

New skin format has same tiles as the old one, except walls (which were totally rearranged) and one tile for out of level was added.

To be more precise: The animation frames are played from left to right.



Wall construction is done in the following way:
Every wall tile consist of four parts (see skinExample above, building parts of skins are marked). So when the program needs wall it creates it by using appropriate parts from given 5 walls. Normally this four parts are equal by size, but sometime they are not (because wall is shifted to the upper left part of a square and provides some shadow on the lower right part. So we need a way to specify how exactly it is divided - how large is left part and how large is
upper part. For that purpose we use second empty square. If it is filled with same color - then by default program divides square in equal pieces. If there is some line starting from upper corner to the left then it's length is used to form the X size of leftmost piece and the
length of vertical line is used to form the Y size of topmost piece.

The rest of this square is used to mark squares which could have grid marks inside. For more information, read the section "More information on the description tile" below.

Box in Row 4 column 3 is not used at all and in example, the author puts his name there.

The above level (shown with old skins), now looks better with new skin (because parts are marked you can see how they are constructed).


More information on the description tile

That's the tile on row 4, column 4, counting from left to right, top to bottom.

This tile should start with only one color for the entire tile. So, it can be colored white, black, red, or whatever. Just color the whole tile with the same solid color.

Other color can be added to this tile to describe two things:
To describe how to divide each of the wall tiles.
Draw a one-pixel line, with a different color than the tile, starting from the upper-left corner of this tile to the right. Draw another one-pixel line, same color as the horizontal line, starting from the upper-left corner of this tile straight down (a vertical line).

These two lines combined shows how to divide each of the five wall-tiles.

YSokoban's skin is setup this way because there are times in which you want to divide the wall-tile differently to allow shadow to show properly.

By default, (meaning if there is no horizontal or vertical line, the entire tile is just one solid color), YSokoban will divide the wall tiles into 4 equal parts.
To describe which tile to show grid and what color.
Please compare the files "skinExample1.png" and "skinExample1_without_net_mark.png" (download skins_description.zip from skins page on YSokoban site).
Specifically, compare the right-most tile on row 4.

The two skin files are identical except that the one shows the grid-mark, one doesn't.

The grid-mark area in this tile is an 4x8 pixel rectangular area. Note that this 4x8 area is not part of the two lines that's used to describe the wall-tile division. If we assume the upper-left corner pixel of this tile is position (1,1). This 4x8 area starts at (2,2). Each pixel of this 4x8 area corresponds to one tile of the skin. (Note that the skin is a 4x8 tiles)

This 4x8 area also need to be the same color as those two lines that's used to describe the wall-tile division. Furthermore, this color is also used as the "grid" color.

skinExample1.png indicates that every tile will have a grid, and the color for the grid is a lighter gray than the floor.

skinExample1_without_net_mark.png indicates that there is no grid. So, if you press CTRL+N, doesn't show a grid.

Also, you don't have to mark every tile to show the grid. You can specify the grid for some tiles and leave some unmarked.

In the sf_100z_greenRed_gray.png skin, it shows that the tiles in row 3 and 4 doesn't have a gird. Load the skin into YSokoban and check out the result of the grid.

There is also a good reason for not having a grid-mark at all in the skin. Sometimes tiles are designed in such a way that there is no need for artificially added grid and/or such a grid will spoil the design. For such tiles we remove the grid. Usually this is either all tiles (because there is natural grid for them) or only walls (because grid over walls will spoil wall design). For example, look at the sf_100rg24.png skin, it has "grid" built-in already.
More technical details on how YSokoban process the description tile (right most tile on row 4):
YSokoban gets pixel 0,0 (I'm talking with relative coordinates inside this cell) and scans first row horizontally and first column vertically. When it gets pixel with different color (up to the end of cell) then this is X and Y length to be used for dividing walls, if X = Y = cell size (i.e., nothing defined) then YSokoban simply assumes that division shall happen at the middle (as it is usually). Then it scans all 4x8 pixels to get which cells are allowed to have grid (those which has same color are allowed). Which means that if you left this tile (4x4) empty, i.e. filled with one color, then this means - divide walls in the middle and all
cells may have grid. The rest of cell is not used. This means that from entire cell we use topmost row, leftmost column and 4x8 pixels from 1,1 to 4,8. The rest is not used at all and could contain whatever we please (including another copyright image).

Thanks to Ming for suggestions and improvements.
Created with wikidPad